Base solide de la page calendar, commit avant refacto
This commit is contained in:
@ -1,4 +1,5 @@
|
|||||||
import 'package:em2rp/providers/users_provider.dart';
|
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/utils/auth_guard_widget.dart';
|
||||||
import 'package:em2rp/views/calendar_page.dart';
|
import 'package:em2rp/views/calendar_page.dart';
|
||||||
import 'package:em2rp/views/login_page.dart';
|
import 'package:em2rp/views/login_page.dart';
|
||||||
@ -36,6 +37,11 @@ void main() async {
|
|||||||
ChangeNotifierProvider<UsersProvider>(
|
ChangeNotifierProvider<UsersProvider>(
|
||||||
create: (context) => UsersProvider(context.read<UserService>()),
|
create: (context) => UsersProvider(context.read<UserService>()),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// EventProvider pour la gestion des événements
|
||||||
|
ChangeNotifierProvider<EventProvider>(
|
||||||
|
create: (context) => EventProvider(),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
child: const MyApp(),
|
child: const MyApp(),
|
||||||
),
|
),
|
||||||
|
@ -13,6 +13,7 @@ class EventModel {
|
|||||||
final String eventTypeId;
|
final String eventTypeId;
|
||||||
final String customerId;
|
final String customerId;
|
||||||
final LatLng address;
|
final LatLng address;
|
||||||
|
final List<String> workforce;
|
||||||
|
|
||||||
EventModel({
|
EventModel({
|
||||||
required this.id,
|
required this.id,
|
||||||
@ -26,37 +27,56 @@ class EventModel {
|
|||||||
required this.eventTypeId,
|
required this.eventTypeId,
|
||||||
required this.customerId,
|
required this.customerId,
|
||||||
required this.address,
|
required this.address,
|
||||||
|
required this.workforce,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory EventModel.fromMap(Map<String, dynamic> map, String id) {
|
factory EventModel.fromMap(Map<String, dynamic> map, String id) {
|
||||||
final GeoPoint geoPoint = map['address'] as GeoPoint;
|
final GeoPoint? geoPoint = map['Address'] as GeoPoint?;
|
||||||
|
final List<dynamic> workforceRefs = map['workforce'] ?? [];
|
||||||
|
final Timestamp? startTimestamp = map['StartDateTime'] as Timestamp?;
|
||||||
|
final Timestamp? endTimestamp = map['EndDateTime'] as Timestamp?;
|
||||||
|
|
||||||
return EventModel(
|
return EventModel(
|
||||||
id: id,
|
id: id,
|
||||||
name: map['name'] ?? '',
|
name: map['Name'] ?? '',
|
||||||
description: map['description'] ?? '',
|
description: map['Description'] ?? '',
|
||||||
startDateTime: (map['startDateTime'] as Timestamp).toDate(),
|
startDateTime: startTimestamp?.toDate() ?? DateTime.now(),
|
||||||
endDateTime: (map['endDateTime'] as Timestamp).toDate(),
|
endDateTime: endTimestamp?.toDate() ??
|
||||||
price: (map['price'] ?? 0.0).toDouble(),
|
DateTime.now().add(const Duration(hours: 1)),
|
||||||
installationTime: map['installationTime'] ?? 0,
|
price: (map['Price'] ?? 0.0).toDouble(),
|
||||||
disassemblyTime: map['disassemblyTime'] ?? 0,
|
installationTime: map['InstallationTime'] ?? 0,
|
||||||
eventTypeId: map['eventType'] ?? '',
|
disassemblyTime: map['DisassemblyTime'] ?? 0,
|
||||||
customerId: map['customer'] ?? '',
|
eventTypeId: map['EventType'] is DocumentReference
|
||||||
address: LatLng(geoPoint.latitude, geoPoint.longitude),
|
? (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<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
return {
|
return {
|
||||||
'name': name,
|
'Name': name,
|
||||||
'description': description,
|
'Description': description,
|
||||||
'startDateTime': Timestamp.fromDate(startDateTime),
|
'StartDateTime': Timestamp.fromDate(startDateTime),
|
||||||
'endDateTime': Timestamp.fromDate(endDateTime),
|
'EndDateTime': Timestamp.fromDate(endDateTime),
|
||||||
'price': price,
|
'Price': price,
|
||||||
'installationTime': installationTime,
|
'InstallationTime': installationTime,
|
||||||
'disassemblyTime': disassemblyTime,
|
'DisassemblyTime': disassemblyTime,
|
||||||
'eventType': eventTypeId,
|
'EventType': eventTypeId,
|
||||||
'customer': customerId,
|
'customer': customerId,
|
||||||
'address': GeoPoint(address.latitude, address.longitude),
|
'Address': GeoPoint(address.latitude, address.longitude),
|
||||||
|
'workforce': workforce,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
105
em2rp/lib/providers/event_provider.dart
Normal file
105
em2rp/lib/providers/event_provider.dart
Normal file
@ -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<EventModel> _events = [];
|
||||||
|
bool _isLoading = false;
|
||||||
|
|
||||||
|
List<EventModel> get events => _events;
|
||||||
|
bool get isLoading => _isLoading;
|
||||||
|
|
||||||
|
// Récupérer les événements pour un utilisateur spécifique
|
||||||
|
Future<void> 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<EventModel?> 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<void> 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<void> 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<void> 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();
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +1,16 @@
|
|||||||
import 'package:em2rp/providers/local_user_provider.dart';
|
import 'package:em2rp/providers/local_user_provider.dart';
|
||||||
|
import 'package:em2rp/providers/event_provider.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:em2rp/widgets/custom_app_bar.dart';
|
import 'package:em2rp/widgets/custom_app_bar.dart';
|
||||||
import 'package:em2rp/views/widgets/nav/main_drawer.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:em2rp/utils/colors.dart';
|
||||||
import 'package:table_calendar/table_calendar.dart';
|
import 'package:table_calendar/table_calendar.dart';
|
||||||
import 'package:em2rp/models/event_model.dart';
|
import 'package:em2rp/models/event_model.dart';
|
||||||
import 'package:em2rp/widgets/event_details.dart';
|
import 'package:em2rp/widgets/event_details.dart';
|
||||||
import 'package:latlong2/latlong.dart';
|
import 'package:latlong2/latlong.dart';
|
||||||
import 'package:intl/date_symbol_data_local.dart';
|
import 'package:intl/date_symbol_data_local.dart';
|
||||||
|
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||||
|
|
||||||
class CalendarPage extends StatefulWidget {
|
class CalendarPage extends StatefulWidget {
|
||||||
const CalendarPage({Key? key}) : super(key: key);
|
const CalendarPage({Key? key}) : super(key: key);
|
||||||
@ -27,37 +29,19 @@ class _CalendarPageState extends State<CalendarPage> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
initializeDateFormatting('fr_FR', null);
|
initializeDateFormatting('fr_FR', null);
|
||||||
|
Future.microtask(() => _loadEvents());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Événements de test
|
Future<void> _loadEvents() async {
|
||||||
final List<EventModel> _testEvents = [
|
final localAuthProvider =
|
||||||
EventModel(
|
Provider.of<LocalUserProvider>(context, listen: false);
|
||||||
id: '1',
|
final eventProvider = Provider.of<EventProvider>(context, listen: false);
|
||||||
name: 'Bal a Grammond',
|
final userId = localAuthProvider.uid;
|
||||||
description: 'Lorem Ipsum',
|
|
||||||
startDateTime: DateTime(2025, 3, 28, 12, 30),
|
if (userId != null) {
|
||||||
endDateTime: DateTime(2025, 3, 28, 23, 30),
|
await eventProvider.loadUserEvents(userId);
|
||||||
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),
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
void _changeWeek(int delta) {
|
void _changeWeek(int delta) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -68,8 +52,17 @@ class _CalendarPageState extends State<CalendarPage> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final localAuthProvider = Provider.of<LocalUserProvider>(context);
|
final localAuthProvider = Provider.of<LocalUserProvider>(context);
|
||||||
|
final eventProvider = Provider.of<EventProvider>(context);
|
||||||
final isMobile = MediaQuery.of(context).size.width < 600;
|
final isMobile = MediaQuery.of(context).size.width < 600;
|
||||||
|
|
||||||
|
if (eventProvider.isLoading) {
|
||||||
|
return const Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: const CustomAppBar(
|
appBar: const CustomAppBar(
|
||||||
title: 'Calendrier',
|
title: 'Calendrier',
|
||||||
@ -452,7 +445,7 @@ class _CalendarPageState extends State<CalendarPage> {
|
|||||||
|
|
||||||
// Préparer les événements par jour (en tenant compte des multi-jours)
|
// Préparer les événements par jour (en tenant compte des multi-jours)
|
||||||
List<List<_PositionedEvent>> eventsByDay = List.generate(7, (i) => []);
|
List<List<_PositionedEvent>> eventsByDay = List.generate(7, (i) => []);
|
||||||
for (final event in _testEvents) {
|
for (final event in Provider.of<EventProvider>(context).events) {
|
||||||
// Pour chaque jour de la semaine
|
// Pour chaque jour de la semaine
|
||||||
for (int i = 0; i < 7; i++) {
|
for (int i = 0; i < 7; i++) {
|
||||||
final day = weekStart.add(Duration(days: i));
|
final day = weekStart.add(Duration(days: i));
|
||||||
@ -735,7 +728,7 @@ class _CalendarPageState extends State<CalendarPage> {
|
|||||||
final dayStart = DateTime(day.year, day.month, day.day, 0, 0);
|
final dayStart = DateTime(day.year, day.month, day.day, 0, 0);
|
||||||
final dayEnd = DateTime(day.year, day.month, day.day, 23, 59, 59);
|
final dayEnd = DateTime(day.year, day.month, day.day, 23, 59, 59);
|
||||||
|
|
||||||
return _testEvents.where((event) {
|
return Provider.of<EventProvider>(context).events.where((event) {
|
||||||
return !(event.endDateTime.isBefore(dayStart) ||
|
return !(event.endDateTime.isBefore(dayStart) ||
|
||||||
event.startDateTime.isAfter(dayEnd));
|
event.startDateTime.isAfter(dayEnd));
|
||||||
}).toList();
|
}).toList();
|
||||||
|
Reference in New Issue
Block a user