import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:intl/intl.dart'; import '../../../shared/services/api_client.dart'; final eventsProvider = FutureProvider.autoDispose .family>, int?>((ref, upcomingDays) async { final apiClient = ref.watch(apiClientProvider); return apiClient.getEvents(upcomingDays: upcomingDays ?? 30); }); class EventsScreen extends ConsumerWidget { const EventsScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final eventsAsync = ref.watch(eventsProvider(30)); return Scaffold( appBar: AppBar( title: const Text('Upcoming Events'), ), body: eventsAsync.when( data: (events) { if (events.isEmpty) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.event_outlined, size: 64, color: Colors.grey.shade400, ), const SizedBox(height: 16), Text( 'No upcoming events', style: Theme.of(context).textTheme.titleMedium?.copyWith( color: Colors.grey, ), ), const SizedBox(height: 8), Text( 'Add birthdays and anniversaries to clients', style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: Colors.grey, ), ), ], ), ); } return RefreshIndicator( onRefresh: () async { ref.invalidate(eventsProvider(30)); }, child: ListView.builder( padding: const EdgeInsets.all(16), itemCount: events.length, itemBuilder: (context, index) { final event = events[index]; return _EventCard(event: event); }, ), ); }, loading: () => const Center(child: CircularProgressIndicator()), error: (e, s) => Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.error_outline, size: 64, color: Colors.red.shade300), const SizedBox(height: 16), const Text('Failed to load events'), TextButton( onPressed: () => ref.invalidate(eventsProvider(30)), child: const Text('Retry'), ), ], ), ), ), ); } } class _EventCard extends StatelessWidget { final Map event; const _EventCard({required this.event}); @override Widget build(BuildContext context) { final eventData = event['event'] as Map; final client = event['client'] as Map?; final dateFormat = DateFormat.MMMd(); final date = DateTime.parse(eventData['date']); final daysUntil = date.difference(DateTime.now()).inDays; IconData icon; Color iconColor; switch (eventData['type']) { case 'birthday': icon = Icons.cake; iconColor = Colors.pink; break; case 'anniversary': icon = Icons.favorite; iconColor = Colors.red; break; default: icon = Icons.event; iconColor = Colors.blue; } return Card( margin: const EdgeInsets.only(bottom: 12), child: ListTile( leading: CircleAvatar( backgroundColor: iconColor.withOpacity(0.1), child: Icon(icon, color: iconColor), ), title: Text(eventData['title']), subtitle: client != null ? Text('${client['firstName']} ${client['lastName']}') : null, trailing: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( dateFormat.format(date), style: Theme.of(context).textTheme.titleSmall, ), Text( daysUntil == 0 ? 'Today!' : daysUntil == 1 ? 'Tomorrow' : 'In $daysUntil days', style: Theme.of(context).textTheme.bodySmall?.copyWith( color: daysUntil <= 3 ? Colors.orange : Colors.grey, fontWeight: daysUntil <= 3 ? FontWeight.bold : null, ), ), ], ), ), ); } }