/// Notification Card Widget /// /// Displays a single notification item with icon, title, message, and timestamp. /// Shows unread indicator with blue left border for unread notifications. library; import 'package:flutter/material.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/theme/colors.dart'; import 'package:worker/features/notifications/domain/entities/notification.dart' as entity; /// Notification Card /// /// Features: /// - Icon with color based on notification type /// - Title and message text /// - Time ago timestamp /// - Blue left border for unread notifications /// - Tap handler class NotificationCard extends StatelessWidget { /// Notification to display final entity.Notification notification; /// Tap callback final VoidCallback? onTap; /// Constructor const NotificationCard({super.key, required this.notification, this.onTap}); @override Widget build(BuildContext context) { return Container( margin: const EdgeInsets.only(bottom: 12), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), border: notification.isUnread ? const Border( left: BorderSide(color: AppColors.primaryBlue, width: 3), ) : null, boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.05), blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: Material( color: Colors.transparent, child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(12), child: Padding( padding: const EdgeInsets.all(AppSpacing.md), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Title with icon Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Icon(_getIcon(), size: 18, color: _getIconColor()), const SizedBox(width: 8), Expanded( child: Text( notification.title, style: TextStyle( fontSize: 14, fontWeight: notification.isUnread ? FontWeight.w600 : FontWeight.w500, color: const Color(0xFF212121), ), ), ), ], ), const SizedBox(height: 4), // Message Padding( padding: const EdgeInsets.only(left: 26), child: Text( notification.message, style: const TextStyle( fontSize: 13, color: Color(0xFF64748B), ), ), ), const SizedBox(height: 8), // Time ago Padding( padding: const EdgeInsets.only(left: 26), child: Text( notification.formattedTimeAgo, style: const TextStyle( fontSize: 11, color: Color(0xFF94A3B8), ), ), ), ], ), ), ), ), ); } /// Get icon based on notification type IconData _getIcon() { final type = notification.type.toLowerCase(); if (type.contains('points') || type.contains('loyalty')) { return Icons.card_giftcard; } else if (type.contains('promotion') || type.contains('sale')) { return Icons.local_offer; } else if (type.contains('shipping')) { return Icons.local_shipping; } else if (type.contains('tier') || type.contains('upgrade')) { return Icons.workspace_premium; } else if (type.contains('event')) { return Icons.event; } else if (type.contains('confirmed')) { return Icons.check_circle; } else if (type.contains('birthday')) { return Icons.cake; } else { return Icons.notifications; } } /// Get icon color based on notification type Color _getIconColor() { final type = notification.type.toLowerCase(); if (type.contains('points') || type.contains('loyalty')) { return AppColors.primaryBlue; // Blue for points/loyalty } else if (type.contains('promotion') || type.contains('sale')) { return AppColors.warning; // Orange/yellow for promotions } else if (type.contains('shipping')) { return AppColors.success; // Green for shipping } else if (type.contains('tier') || type.contains('upgrade')) { return AppColors.warning; // Gold/yellow for tier } else if (type.contains('event')) { return AppColors.primaryBlue; // Blue for events } else if (type.contains('confirmed')) { return AppColors.success; // Green for confirmations } else if (type.contains('birthday')) { return const Color(0xFFFF69B4); // Pink for birthday } else { return AppColors.grey500; // Gray for system } } }