/// Related Article Card Widget /// /// Compact horizontal card for displaying related articles. /// Used in the news detail page to show similar content. library; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/theme/colors.dart'; import 'package:worker/features/news/domain/entities/news_article.dart'; /// Related Article Card /// /// Features: /// - Horizontal layout /// - 60x60 thumbnail /// - Title (max 2 lines) /// - Metadata: date and view count /// - OnTap handler for navigation class RelatedArticleCard extends StatelessWidget { /// Article to display final NewsArticle article; /// Callback when card is tapped final VoidCallback? onTap; /// Constructor const RelatedArticleCard({super.key, required this.article, this.onTap}); @override Widget build(BuildContext context) { return GestureDetector( onTap: onTap, child: Container( margin: const EdgeInsets.only(bottom: AppSpacing.md), padding: const EdgeInsets.all(AppSpacing.md), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(AppRadius.lg), border: Border.all(color: const Color(0xFFE2E8F0)), ), child: Row( children: [ // Thumbnail (60x60) ClipRRect( borderRadius: BorderRadius.circular(AppRadius.md), child: CachedNetworkImage( imageUrl: article.imageUrl, width: 60, height: 60, fit: BoxFit.cover, placeholder: (context, url) => Container( width: 60, height: 60, color: AppColors.grey100, child: const Center( child: SizedBox( width: 16, height: 16, child: CircularProgressIndicator(strokeWidth: 2), ), ), ), errorWidget: (context, url, error) => Container( width: 60, height: 60, color: AppColors.grey100, child: const FaIcon( FontAwesomeIcons.image, size: 20, color: AppColors.grey500, ), ), ), ), const SizedBox(width: AppSpacing.md), // Content Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Title (max 2 lines) Text( article.title, style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xFF1E293B), height: 1.3, ), maxLines: 2, overflow: TextOverflow.ellipsis, ), const SizedBox(height: 6), // Metadata Text( '${article.formattedDate} • ${article.formattedViewCount} lượt xem', style: const TextStyle( fontSize: 12, color: Color(0xFF64748B), ), ), ], ), ), ], ), ), ); } }