import 'package:wanisclient/config/custom_loader.dart'; import 'package:wanisclient/config/custom_text.dart'; import 'package:wanisclient/utils/colors.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_svg/svg.dart'; import 'package:provider/provider.dart'; import '../providers/NotificationFCMProvider.dart'; class NotificationsScreen extends StatefulWidget { const NotificationsScreen({super.key}); @override State createState() => _NotificationsScreenState(); } class _NotificationsScreenState extends State { late ScrollController _scrollController; @override void initState() { super.initState(); _scrollController = ScrollController(); _scrollController.addListener(_onScroll); WidgetsBinding.instance.addPostFrameCallback((_) { Provider.of(context, listen: false) .fetchNotifications(); }); } @override void dispose() { _scrollController.dispose(); super.dispose(); } void _onScroll() { if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent - 200) { final provider = Provider.of(context, listen: false); if (provider.hasMore && !provider.isLoading) { provider.fetchNotifications(loadMore: true); } } } String formatRideStatus(String status) { switch (status) { case 'NEW_RIDE_REQUESTED': return 'New Ride Requested'; case 'CLIENT_CANCEL_RIDE': return 'Client Cancelled the Ride'; case 'IDLE': return 'Idle'; case 'NEW_INSTANT_RIDE': return 'New Instant Ride'; case 'NEW_SCHEDULE_RIDE': return 'New Scheduled Ride'; case 'TIME_OUT': return 'Request Timed Out'; case 'UPDATE_SCHEDULE_RIDE': return 'Updated Scheduled Ride'; default: return 'Unknown Status'; } } String formatDeliveryStatus(String status) { switch (status) { case 'DELIVERED': return 'Delivered'; case 'OUT': return 'Out for Delivery'; case 'READ': return 'Read'; case 'RECEIVED': return 'Received'; case 'SENDING': return 'Sending'; case 'WAITING': return 'Waiting'; default: return 'Unknown Delivery Status'; } } IconData getNotificationIcon(String status) { switch (status) { case 'NEW_RIDE_REQUESTED': case 'NEW_INSTANT_RIDE': case 'NEW_SCHEDULE_RIDE': return Icons.directions_car; case 'CLIENT_CANCEL_RIDE': return Icons.cancel; case 'TIME_OUT': return Icons.timer_off; case 'UPDATE_SCHEDULE_RIDE': return Icons.update; case 'IDLE': return Icons.pause_circle_outline; default: return Icons.notifications_none ; } } Color getStatusColor(String status) { switch (status) { case 'DELIVERED': return Colors.green; case 'OUT': return Colors.orange; case 'READ': return Colors.blue; case 'RECEIVED': return Colors.teal; case 'SENDING': return Colors.amber; case 'WAITING': return Colors.grey; default: return Colors.grey; } } @override Widget build(BuildContext context) { return SafeArea( child: Scaffold( body: Container( color:Colors.white, child: Column( children: [ SizedBox(height: 20.w), const Center( child: Txt( text: 'Notifications', style: TextStyle( fontWeight: FontWeight.bold, fontSize: 20, ), ), ), Expanded( child: Padding( padding: const EdgeInsets.only(top: 16.0), child: Consumer( builder: (context, provider, _) { if (provider.isLoading && provider.notifications.isEmpty) { return const Center(child: CustomLoader()); } if (provider.notifications.isEmpty) { return Container( width: double.infinity, child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ SvgPicture.asset( 'assets/icons/no_notification.svg', width: 120, height: 120, ), const SizedBox(height: 20,), const Txt( text: "You have no notifications", style: TextStyle( fontSize: 17, color: Colors.black, fontWeight: FontWeight.bold ), ), ], ), ); } return RefreshIndicator( onRefresh: () async { await provider.fetchNotifications(); }, child: ListView.builder( controller: _scrollController, padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), itemCount: provider.notifications.length + (provider.hasMore ? 1 : 0), itemBuilder: (context, index) { // Show loading indicator at the end when loading more if (index == provider.notifications.length) { return Container( padding: const EdgeInsets.all(16), child: const Center( child: CircularProgressIndicator(), ), ); } final notification = provider.notifications[index]; return Container( margin: const EdgeInsets.only(bottom: 12), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), border: Border.all( color: Colors.grey.withOpacity(0.5), width: 1, ), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.04), blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: ListTile( contentPadding: const EdgeInsets.all(16), leading: Container( width: 48, height: 48, decoration: BoxDecoration( color: AppNewColors.backgroundPurpleColor2, borderRadius: BorderRadius.circular(50), ), child: Icon( getNotificationIcon(notification.body), color: Colors.black, size: 24, ), ), title: Txt( text: formatRideStatus(notification.title), style: const TextStyle( fontWeight: FontWeight.w600, fontSize: 16, color: Colors.black ), ), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 4), Txt( text: notification.body, style: const TextStyle( fontSize: 14, color: Colors.black87 ), ), const SizedBox(height: 8), Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 4, ), decoration: BoxDecoration( color: AppNewColors.backgroundPurpleColor2, borderRadius: BorderRadius.circular(8), ), child: Txt( text: formatDeliveryStatus(notification.status), style: const TextStyle( fontSize: 12, fontWeight: FontWeight.w500, color: AppNewColors.primaryColor, ), ), ), ], ), ), ); }, ), ); }, ), ), ), ], ), ), ), ); } }