import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:intl/intl.dart'; import '../providers/dashboard_providers.dart'; import '../../../widgets/error_view.dart'; class NotificationsScreen extends ConsumerWidget { const NotificationsScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final async = ref.watch(notificationsProvider); return Scaffold( appBar: AppBar( title: const Text('Notifications'), actions: [ IconButton( icon: const Icon(Icons.done_all), tooltip: 'Mark all read', onPressed: () async { await ref.read(notificationServiceProvider).markAllRead(); ref.invalidate(notificationsProvider); ref.invalidate(unreadCountProvider); }, ), ], ), body: async.when( loading: () => const Center(child: CircularProgressIndicator()), error: (e, _) => ErrorView( message: 'Failed to load notifications', onRetry: () => ref.invalidate(notificationsProvider), ), data: (notifications) { if (notifications.isEmpty) { return const Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.notifications_none, size: 64, color: Color(0xFFD1D5DB)), SizedBox(height: 16), Text('No notifications', style: TextStyle(color: Color(0xFF9CA3AF))), ], ), ); } return RefreshIndicator( onRefresh: () async => ref.invalidate(notificationsProvider), child: ListView.separated( itemCount: notifications.length, separatorBuilder: (_, _) => const Divider(height: 1, indent: 72), itemBuilder: (_, i) { final n = notifications[i]; return _NotificationTile( notification: n, onRead: () async { if (!n.isRead) { await ref .read(notificationServiceProvider) .markRead(n.id); ref.invalidate(notificationsProvider); ref.invalidate(unreadCountProvider); } }, ); }, ), ); }, ), ); } } class _NotificationTile extends StatelessWidget { final dynamic notification; final VoidCallback onRead; const _NotificationTile( {required this.notification, required this.onRead}); IconData _icon(String type) { switch (type) { case 'RESERVATION_CREATED': case 'RESERVATION_CONFIRMED': return Icons.event_available; case 'RESERVATION_CANCELLED': return Icons.event_busy; case 'PAYMENT_RECEIVED': return Icons.payments_outlined; case 'LICENSE_UPLOADED': return Icons.badge_outlined; default: return Icons.notifications_outlined; } } @override Widget build(BuildContext context) { final fmt = DateFormat('MMM d, h:mm a'); final isRead = notification.isRead as bool; return InkWell( onTap: onRead, child: Container( color: isRead ? null : const Color(0xFFF0F7FF), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: 40, height: 40, decoration: BoxDecoration( color: isRead ? const Color(0xFFF3F4F6) : const Color(0xFFE1EFFE), shape: BoxShape.circle, ), child: Icon( _icon(notification.type as String), size: 20, color: isRead ? const Color(0xFF6B7280) : const Color(0xFF1A56DB), ), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( notification.title as String, style: TextStyle( fontWeight: isRead ? FontWeight.normal : FontWeight.w600, fontSize: 14, ), ), const SizedBox(height: 2), Text( notification.body as String, style: const TextStyle( fontSize: 13, color: Color(0xFF6B7280)), ), const SizedBox(height: 4), Text( fmt.format(notification.createdAt as DateTime), style: const TextStyle( fontSize: 11, color: Color(0xFF9CA3AF)), ), ], ), ), if (!isRead) Container( width: 8, height: 8, margin: const EdgeInsets.only(top: 6), decoration: const BoxDecoration( color: Color(0xFF1A56DB), shape: BoxShape.circle, ), ), ], ), ), ); } }