import 'package:flutter/material.dart'; import 'models/notification_model.dart'; import 'widgets/empty_state_widget.dart'; class NotificationPage extends StatefulWidget { const NotificationPage({super.key}); @override State createState() => _NotificationPageState(); } class _NotificationPageState extends State { final List _notifications = [ NotificationModel(id: '1', title: 'Order Shipped!', message: 'Your order #AMZ12345 for Nighthawk AX12 Router has been shipped.', timestamp: DateTime.now().subtract(const Duration(hours: 2)), icon: Icons.local_shipping_outlined), NotificationModel(id: '2', title: 'Weekend Deal!', message: 'Get 15% off on all Mesh Systems this weekend. Use code WEEKEND15.', timestamp: DateTime.now().subtract(const Duration(days: 1)), icon: Icons.campaign_outlined, isRead: true), NotificationModel(id: '3', title: 'Password Reset Confirmation', message: 'Your password was successfully reset on a new device an hour ago.', timestamp: DateTime.now().subtract(const Duration(days: 3)), icon: Icons.lock_reset_outlined), NotificationModel(id: '4', title: 'New Login Detected', message: 'We detected a new login to your account from a new device in California, US.', timestamp: DateTime.now().subtract(const Duration(days: 3, hours: 2)), icon: Icons.login_outlined, isRead: true), NotificationModel(id: '5', title: 'Feature Update: Dark Mode', message: 'Dark mode is now even better! Check out the latest app improvements and enjoy a smoother experience.', timestamp: DateTime.now().subtract(const Duration(days: 5)), icon: Icons.new_releases_outlined), ]; void _markAsRead(NotificationModel notification) { setState(() { notification.isRead = true; }); } void _deleteNotification(String id) { setState(() { _notifications.removeWhere((n) => n.id == id); }); ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Notification dismissed'), duration: Duration(seconds: 1)), ); } String _timeAgo(DateTime date) { final Duration diff = DateTime.now().difference(date); if (diff.inDays >= 365) return "${(diff.inDays / 365).floor()} year(s)"; if (diff.inDays >= 30) return "${(diff.inDays / 30).floor()} month(s)"; if (diff.inDays > 0) return "${diff.inDays} day(s)"; if (diff.inHours > 0) return "${diff.inHours} hour(s)"; if (diff.inMinutes > 0) return "${diff.inMinutes} minute(s)"; return "Just now"; } @override Widget build(BuildContext context) { final theme = Theme.of(context); return Scaffold( appBar: AppBar( title: const Text('Notifications'), centerTitle: true, actions: [ if (_notifications.any((n) => !n.isRead)) IconButton( icon: const Icon(Icons.mark_chat_read_outlined), tooltip: 'Mark all as read', onPressed: () { setState(() { for (var n in _notifications) { n.isRead = true; } }); ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('All notifications marked as read.')), ); }, ) ], ), body: _notifications.isEmpty ? const EmptyStateWidget( icon: Icons.notifications_off_outlined, message: 'You have no notifications yet.', ) : ListView.builder( padding: const EdgeInsets.symmetric(vertical: 8.0), itemCount: _notifications.length, itemBuilder: (context, index) { final notification = _notifications[index]; return Dismissible( key: Key(notification.id), direction: DismissDirection.endToStart, onDismissed: (direction) { _deleteNotification(notification.id); }, background: Container( color: theme.colorScheme.errorContainer, alignment: Alignment.centerRight, padding: const EdgeInsets.symmetric(horizontal: 20.0), child: Icon(Icons.delete_outline, color: theme.colorScheme.onErrorContainer), ), child: Card( margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), elevation: notification.isRead ? 1 : 2.5, shape: RoundedRectangleBorder( side: BorderSide( color: notification.isRead ? theme.dividerColor.withOpacity(0.5) : theme.colorScheme.primary.withOpacity(0.6), width: notification.isRead ? 0.8 : 1.2, ), borderRadius: BorderRadius.circular(theme.cardTheme.shape is RoundedRectangleBorder ? (theme.cardTheme.shape as RoundedRectangleBorder).borderRadius.resolve(Directionality.of(context)).topLeft.x : 8) ), child: ListTile( leading: CircleAvatar( backgroundColor: notification.isRead ? theme.colorScheme.secondaryContainer.withOpacity(0.5) : theme.colorScheme.primaryContainer, child: Icon( notification.icon, color: notification.isRead ? theme.colorScheme.onSecondaryContainer.withOpacity(0.7) : theme.colorScheme.onPrimaryContainer, size: 22, ), ), title: Text( notification.title, style: theme.textTheme.titleMedium?.copyWith( fontWeight: notification.isRead ? FontWeight.normal : FontWeight.w600, color: notification.isRead ? theme.textTheme.titleMedium?.color?.withOpacity(0.8) : theme.textTheme.titleMedium?.color, ), ), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text(notification.message, maxLines: 2, overflow: TextOverflow.ellipsis, style: theme.textTheme.bodySmall), const SizedBox(height: 4), Text( '${_timeAgo(notification.timestamp)} ago', style: theme.textTheme.bodySmall?.copyWith(color: theme.textTheme.bodySmall?.color?.withOpacity(0.6), fontSize: 11), ), ], ), isThreeLine: true, trailing: !notification.isRead ? Icon(Icons.circle, size: 10, color: theme.colorScheme.primary) : null, onTap: () { _markAsRead(notification); // Mock action: show snackbar ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Notification "${notification.title}" viewed.'), duration: const Duration(seconds: 2)), ); }, ), ), ); }, ), ); } }