From 62c6125d8c6162a7e2d56b755e3d708199e435f2 Mon Sep 17 00:00:00 2001 From: "PC-PAUL\\paulf" Date: Sun, 18 May 2025 20:01:26 +0200 Subject: [PATCH] Base solide de la page calendar, commit avant refacto --- em2rp/lib/main.dart | 6 ++ em2rp/lib/models/event_model.dart | 60 +++++++++----- em2rp/lib/providers/event_provider.dart | 105 ++++++++++++++++++++++++ em2rp/lib/views/calendar_page.dart | 57 ++++++------- 4 files changed, 176 insertions(+), 52 deletions(-) create mode 100644 em2rp/lib/providers/event_provider.dart diff --git a/em2rp/lib/main.dart b/em2rp/lib/main.dart index 400a43d..5a367b3 100644 --- a/em2rp/lib/main.dart +++ b/em2rp/lib/main.dart @@ -1,4 +1,5 @@ import 'package:em2rp/providers/users_provider.dart'; +import 'package:em2rp/providers/event_provider.dart'; import 'package:em2rp/utils/auth_guard_widget.dart'; import 'package:em2rp/views/calendar_page.dart'; import 'package:em2rp/views/login_page.dart'; @@ -36,6 +37,11 @@ void main() async { ChangeNotifierProvider( create: (context) => UsersProvider(context.read()), ), + + // EventProvider pour la gestion des événements + ChangeNotifierProvider( + create: (context) => EventProvider(), + ), ], child: const MyApp(), ), diff --git a/em2rp/lib/models/event_model.dart b/em2rp/lib/models/event_model.dart index 9795ef5..586e26e 100644 --- a/em2rp/lib/models/event_model.dart +++ b/em2rp/lib/models/event_model.dart @@ -13,6 +13,7 @@ class EventModel { final String eventTypeId; final String customerId; final LatLng address; + final List workforce; EventModel({ required this.id, @@ -26,37 +27,56 @@ class EventModel { required this.eventTypeId, required this.customerId, required this.address, + required this.workforce, }); factory EventModel.fromMap(Map map, String id) { - final GeoPoint geoPoint = map['address'] as GeoPoint; + final GeoPoint? geoPoint = map['Address'] as GeoPoint?; + final List workforceRefs = map['workforce'] ?? []; + final Timestamp? startTimestamp = map['StartDateTime'] as Timestamp?; + final Timestamp? endTimestamp = map['EndDateTime'] as Timestamp?; + return EventModel( id: id, - name: map['name'] ?? '', - description: map['description'] ?? '', - startDateTime: (map['startDateTime'] as Timestamp).toDate(), - endDateTime: (map['endDateTime'] as Timestamp).toDate(), - price: (map['price'] ?? 0.0).toDouble(), - installationTime: map['installationTime'] ?? 0, - disassemblyTime: map['disassemblyTime'] ?? 0, - eventTypeId: map['eventType'] ?? '', - customerId: map['customer'] ?? '', - address: LatLng(geoPoint.latitude, geoPoint.longitude), + name: map['Name'] ?? '', + description: map['Description'] ?? '', + startDateTime: startTimestamp?.toDate() ?? DateTime.now(), + endDateTime: endTimestamp?.toDate() ?? + DateTime.now().add(const Duration(hours: 1)), + price: (map['Price'] ?? 0.0).toDouble(), + installationTime: map['InstallationTime'] ?? 0, + disassemblyTime: map['DisassemblyTime'] ?? 0, + eventTypeId: map['EventType'] is DocumentReference + ? (map['EventType'] as DocumentReference).id + : '', + customerId: map['customer'] is DocumentReference + ? (map['customer'] as DocumentReference).id + : '', + address: geoPoint != null + ? LatLng(geoPoint.latitude, geoPoint.longitude) + : const LatLng(0, 0), + workforce: workforceRefs.map((ref) { + if (ref is DocumentReference) { + return ref.id; + } + return ref.toString(); + }).toList(), ); } Map toMap() { return { - 'name': name, - 'description': description, - 'startDateTime': Timestamp.fromDate(startDateTime), - 'endDateTime': Timestamp.fromDate(endDateTime), - 'price': price, - 'installationTime': installationTime, - 'disassemblyTime': disassemblyTime, - 'eventType': eventTypeId, + 'Name': name, + 'Description': description, + 'StartDateTime': Timestamp.fromDate(startDateTime), + 'EndDateTime': Timestamp.fromDate(endDateTime), + 'Price': price, + 'InstallationTime': installationTime, + 'DisassemblyTime': disassemblyTime, + 'EventType': eventTypeId, 'customer': customerId, - 'address': GeoPoint(address.latitude, address.longitude), + 'Address': GeoPoint(address.latitude, address.longitude), + 'workforce': workforce, }; } } diff --git a/em2rp/lib/providers/event_provider.dart b/em2rp/lib/providers/event_provider.dart new file mode 100644 index 0000000..8c0986a --- /dev/null +++ b/em2rp/lib/providers/event_provider.dart @@ -0,0 +1,105 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:flutter/material.dart'; +import '../models/event_model.dart'; + +class EventProvider with ChangeNotifier { + final FirebaseFirestore _firestore = FirebaseFirestore.instance; + List _events = []; + bool _isLoading = false; + + List get events => _events; + bool get isLoading => _isLoading; + + // Récupérer les événements pour un utilisateur spécifique + Future loadUserEvents(String userId) async { + _isLoading = true; + notifyListeners(); + + try { + print('Loading events for user: $userId'); + + // Récupérer uniquement les événements où l'utilisateur est dans la workforce + final eventsSnapshot = await _firestore + .collection('events') + .where('workforce', arrayContains: userId) + .get(); + + print('Found ${eventsSnapshot.docs.length} events for user'); + + _events = eventsSnapshot.docs.map((doc) { + print('Event data: ${doc.data()}'); + return EventModel.fromMap(doc.data(), doc.id); + }).toList(); + + print('Parsed ${_events.length} events'); + + _isLoading = false; + notifyListeners(); + } catch (e) { + print('Error loading events: $e'); + _isLoading = false; + notifyListeners(); + rethrow; + } + } + + // Récupérer un événement spécifique + Future getEvent(String eventId) async { + try { + final doc = await _firestore.collection('events').doc(eventId).get(); + if (doc.exists) { + return EventModel.fromMap(doc.data()!, doc.id); + } + return null; + } catch (e) { + print('Error getting event: $e'); + rethrow; + } + } + + // Ajouter un nouvel événement + Future addEvent(EventModel event) async { + try { + final docRef = await _firestore.collection('events').add(event.toMap()); + final newEvent = EventModel.fromMap(event.toMap(), docRef.id); + _events.add(newEvent); + notifyListeners(); + } catch (e) { + print('Error adding event: $e'); + rethrow; + } + } + + // Mettre à jour un événement + Future updateEvent(EventModel event) async { + try { + await _firestore.collection('events').doc(event.id).update(event.toMap()); + final index = _events.indexWhere((e) => e.id == event.id); + if (index != -1) { + _events[index] = event; + notifyListeners(); + } + } catch (e) { + print('Error updating event: $e'); + rethrow; + } + } + + // Supprimer un événement + Future deleteEvent(String eventId) async { + try { + await _firestore.collection('events').doc(eventId).delete(); + _events.removeWhere((event) => event.id == eventId); + notifyListeners(); + } catch (e) { + print('Error deleting event: $e'); + rethrow; + } + } + + // Vider la liste des événements + void clearEvents() { + _events = []; + notifyListeners(); + } +} diff --git a/em2rp/lib/views/calendar_page.dart b/em2rp/lib/views/calendar_page.dart index f3f8301..243ee5a 100644 --- a/em2rp/lib/views/calendar_page.dart +++ b/em2rp/lib/views/calendar_page.dart @@ -1,14 +1,16 @@ import 'package:em2rp/providers/local_user_provider.dart'; +import 'package:em2rp/providers/event_provider.dart'; import 'package:flutter/material.dart'; import 'package:em2rp/widgets/custom_app_bar.dart'; import 'package:em2rp/views/widgets/nav/main_drawer.dart'; -import 'package:provider/provider.dart'; // Import Provider +import 'package:provider/provider.dart'; import 'package:em2rp/utils/colors.dart'; import 'package:table_calendar/table_calendar.dart'; import 'package:em2rp/models/event_model.dart'; import 'package:em2rp/widgets/event_details.dart'; import 'package:latlong2/latlong.dart'; import 'package:intl/date_symbol_data_local.dart'; +import 'package:cloud_firestore/cloud_firestore.dart'; class CalendarPage extends StatefulWidget { const CalendarPage({Key? key}) : super(key: key); @@ -27,37 +29,19 @@ class _CalendarPageState extends State { void initState() { super.initState(); initializeDateFormatting('fr_FR', null); + Future.microtask(() => _loadEvents()); } - // Événements de test - final List _testEvents = [ - EventModel( - id: '1', - name: 'Bal a Grammond', - description: 'Lorem Ipsum', - startDateTime: DateTime(2025, 3, 28, 12, 30), - endDateTime: DateTime(2025, 3, 28, 23, 30), - price: 950.34, - installationTime: 3, - disassemblyTime: 2, - eventTypeId: '/eventTypes/Bal', - customerId: '/customers/DnjJ1HOPBLqEeExs0nDl', - address: const LatLng(45.566521035268224, 4.439601075086365), - ), - EventModel( - id: '2', - name: 'Mariage à Lyon', - description: 'Cérémonie et réception', - startDateTime: DateTime(2025, 3, 28, 15, 0), - endDateTime: DateTime(2025, 3, 29, 4, 0), - price: 2500.00, - installationTime: 4, - disassemblyTime: 3, - eventTypeId: '/eventTypes/Mariage', - customerId: '/customers/Test123', - address: const LatLng(45.7578137, 4.8320114), - ), - ]; + Future _loadEvents() async { + final localAuthProvider = + Provider.of(context, listen: false); + final eventProvider = Provider.of(context, listen: false); + final userId = localAuthProvider.uid; + + if (userId != null) { + await eventProvider.loadUserEvents(userId); + } + } void _changeWeek(int delta) { setState(() { @@ -68,8 +52,17 @@ class _CalendarPageState extends State { @override Widget build(BuildContext context) { final localAuthProvider = Provider.of(context); + final eventProvider = Provider.of(context); final isMobile = MediaQuery.of(context).size.width < 600; + if (eventProvider.isLoading) { + return const Scaffold( + body: Center( + child: CircularProgressIndicator(), + ), + ); + } + return Scaffold( appBar: const CustomAppBar( title: 'Calendrier', @@ -452,7 +445,7 @@ class _CalendarPageState extends State { // Préparer les événements par jour (en tenant compte des multi-jours) List> eventsByDay = List.generate(7, (i) => []); - for (final event in _testEvents) { + for (final event in Provider.of(context).events) { // Pour chaque jour de la semaine for (int i = 0; i < 7; i++) { final day = weekStart.add(Duration(days: i)); @@ -735,7 +728,7 @@ class _CalendarPageState extends State { final dayStart = DateTime(day.year, day.month, day.day, 0, 0); final dayEnd = DateTime(day.year, day.month, day.day, 23, 59, 59); - return _testEvents.where((event) { + return Provider.of(context).events.where((event) { return !(event.endDateTime.isBefore(dayStart) || event.startDateTime.isAfter(dayEnd)); }).toList();