/// Data Model: News Article Model /// /// Data layer model for news articles. /// Handles JSON serialization and conversion to/from domain entity. library; import 'package:worker/features/news/domain/entities/news_article.dart'; /// News Article Model /// /// Used in the data layer for: /// - JSON serialization/deserialization from API /// - Conversion to domain entity /// - Local storage (if needed) class NewsArticleModel { /// Unique article ID final String id; /// Article title final String title; /// Article excerpt/summary final String excerpt; /// Full article content (optional) final String? content; /// Featured image URL final String imageUrl; /// Article category final String category; /// Publication date (ISO 8601 string) final String publishedDate; /// View count final int viewCount; /// Estimated reading time in minutes final int readingTimeMinutes; /// Whether this is a featured article final bool isFeatured; /// Author name (optional) final String? authorName; /// Author avatar URL (optional) final String? authorAvatar; /// Tags/keywords for the article final List tags; /// Like count final int likeCount; /// Comment count final int commentCount; /// Share count final int shareCount; /// Constructor const NewsArticleModel({ required this.id, required this.title, required this.excerpt, this.content, required this.imageUrl, required this.category, required this.publishedDate, required this.viewCount, required this.readingTimeMinutes, this.isFeatured = false, this.authorName, this.authorAvatar, this.tags = const [], this.likeCount = 0, this.commentCount = 0, this.shareCount = 0, }); /// Create model from JSON factory NewsArticleModel.fromJson(Map json) { return NewsArticleModel( id: json['id'] as String, title: json['title'] as String, excerpt: json['excerpt'] as String, content: json['content'] as String?, imageUrl: json['image_url'] as String, category: json['category'] as String, publishedDate: json['published_date'] as String, viewCount: json['view_count'] as int, readingTimeMinutes: json['reading_time_minutes'] as int, isFeatured: json['is_featured'] as bool? ?? false, authorName: json['author_name'] as String?, authorAvatar: json['author_avatar'] as String?, tags: (json['tags'] as List?)?.map((e) => e as String).toList() ?? const [], likeCount: json['like_count'] as int? ?? 0, commentCount: json['comment_count'] as int? ?? 0, shareCount: json['share_count'] as int? ?? 0, ); } /// Convert model to JSON Map toJson() { return { 'id': id, 'title': title, 'excerpt': excerpt, 'content': content, 'image_url': imageUrl, 'category': category, 'published_date': publishedDate, 'view_count': viewCount, 'reading_time_minutes': readingTimeMinutes, 'is_featured': isFeatured, 'author_name': authorName, 'author_avatar': authorAvatar, 'tags': tags, 'like_count': likeCount, 'comment_count': commentCount, 'share_count': shareCount, }; } /// Convert model to domain entity NewsArticle toEntity() { return NewsArticle( id: id, title: title, excerpt: excerpt, content: content, imageUrl: imageUrl, category: _parseCategory(category), publishedDate: DateTime.parse(publishedDate), viewCount: viewCount, readingTimeMinutes: readingTimeMinutes, isFeatured: isFeatured, authorName: authorName, authorAvatar: authorAvatar, tags: tags, likeCount: likeCount, commentCount: commentCount, shareCount: shareCount, ); } /// Create model from domain entity factory NewsArticleModel.fromEntity(NewsArticle entity) { return NewsArticleModel( id: entity.id, title: entity.title, excerpt: entity.excerpt, content: entity.content, imageUrl: entity.imageUrl, category: _categoryToString(entity.category), publishedDate: entity.publishedDate.toIso8601String(), viewCount: entity.viewCount, readingTimeMinutes: entity.readingTimeMinutes, isFeatured: entity.isFeatured, authorName: entity.authorName, authorAvatar: entity.authorAvatar, tags: entity.tags, likeCount: entity.likeCount, commentCount: entity.commentCount, shareCount: entity.shareCount, ); } /// Parse category from string static NewsCategory _parseCategory(String category) { switch (category.toLowerCase()) { case 'news': return NewsCategory.news; case 'professional': case 'technique': return NewsCategory.professional; case 'projects': return NewsCategory.projects; case 'events': return NewsCategory.events; case 'promotions': return NewsCategory.promotions; default: return NewsCategory.news; } } /// Convert category to string static String _categoryToString(NewsCategory category) { switch (category) { case NewsCategory.news: return 'news'; case NewsCategory.professional: return 'professional'; case NewsCategory.projects: return 'projects'; case NewsCategory.events: return 'events'; case NewsCategory.promotions: return 'promotions'; } } @override String toString() { return 'NewsArticleModel(id: $id, title: $title, category: $category, ' 'publishedDate: $publishedDate)'; } }