import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import '../../../common/theme/theme.dart'; import '../../../sample/news_sample_data.dart'; extension NewsCategoryUi on NewsCategory { Color get color => switch (this) { NewsCategory.menu => const Color(0xFFD9642A), NewsCategory.promo => AppColor.primary, NewsCategory.event => const Color(0xFF7D63C9), NewsCategory.info => const Color(0xFF3B7BBF), NewsCategory.tips => const Color(0xFF2F8A5B), }; IconData get icon => switch (this) { NewsCategory.menu => Icons.restaurant_menu_rounded, NewsCategory.promo => Icons.local_offer_rounded, NewsCategory.event => Icons.celebration_rounded, NewsCategory.info => Icons.campaign_rounded, NewsCategory.tips => Icons.lightbulb_rounded, }; } /// "Baru saja" / "5 menit lalu" / "3 jam lalu" / "Kemarin" / "2 hari lalu", /// lalu tanggal pendek. String formatNewsTime(DateTime time) { final diff = DateTime.now().difference(time); if (diff.inMinutes < 1) return 'Baru saja'; if (diff.inHours < 1) return '${diff.inMinutes} menit lalu'; if (diff.inDays < 1) return '${diff.inHours} jam lalu'; if (diff.inDays == 1) return 'Kemarin'; if (diff.inDays < 7) return '${diff.inDays} hari lalu'; return DateFormat('d MMM yyyy', 'id_ID').format(time); } /// "3 jam lalu · 2 menit baca". String newsMetaLabel(NewsArticle article) => '${formatNewsTime(article.publishedAt)} · ' '${article.readMinutes} menit baca'; /// Sampul artikel: foto, atau warna kategori dengan ikon bila tidak ada foto. class NewsCover extends StatelessWidget { const NewsCover({super.key, required this.article, this.iconSize = 40}); final NewsArticle article; final double iconSize; @override Widget build(BuildContext context) { final image = article.coverImage; if (image != null) { return Image.asset( image, fit: BoxFit.cover, errorBuilder: (_, _, _) => _buildFallback(), ); } return _buildFallback(); } Widget _buildFallback() { final color = article.category.color; return DecoratedBox( decoration: BoxDecoration( gradient: LinearGradient( colors: [color.withOpacity(0.75), color], begin: Alignment.topLeft, end: Alignment.bottomRight, ), ), child: Center( child: Icon( article.category.icon, size: iconSize, color: AppColor.white.withOpacity(0.9), ), ), ); } } /// Label kategori berwarna; [onImage] untuk di atas foto sampul. class NewsCategoryPill extends StatelessWidget { const NewsCategoryPill({ super.key, required this.category, this.onImage = false, }); final NewsCategory category; final bool onImage; @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), decoration: BoxDecoration( color: onImage ? AppColor.white : category.color.withOpacity(0.1), borderRadius: BorderRadius.circular(20), ), child: Text( category.label, style: AppStyle.xs.copyWith( color: category.color, fontWeight: FontWeight.w800, ), ), ); } }