Passage en vue mobile du calendrier

This commit is contained in:
2025-05-29 12:41:43 +02:00
parent 77d0d5cc81
commit 004d442e67
4 changed files with 395 additions and 38 deletions

View File

@ -115,16 +115,9 @@ class EventDetails extends StatelessWidget {
EventModel.fromMap(snap.data()!, event.id);
onSelectEvent(updatedEvent,
selectedDate ?? updatedEvent.startDateTime);
// Recharge la liste des événements pour mettre à jour la vue calendrier
final localUserProvider =
Provider.of<LocalUserProvider>(context, listen: false);
final userId = localUserProvider.currentUser?.uid;
final canViewAll =
localUserProvider.hasPermission('view_all_users');
if (userId != null) {
await Provider.of<EventProvider>(context, listen: false)
.loadUserEvents(userId, canViewAllEvents: canViewAll);
}
// Met à jour uniquement l'événement dans le provider (rafraîchissement local et fluide)
await Provider.of<EventProvider>(context, listen: false)
.updateEvent(updatedEvent);
},
),
),

View File

@ -0,0 +1,139 @@
import 'package:flutter/material.dart';
import 'package:em2rp/models/event_model.dart';
class MobileCalendarView extends StatelessWidget {
final DateTime focusedDay;
final DateTime? selectedDay;
final List<EventModel> events;
final void Function(DateTime) onDaySelected;
const MobileCalendarView({
super.key,
required this.focusedDay,
required this.selectedDay,
required this.events,
required this.onDaySelected,
});
@override
Widget build(BuildContext context) {
final daysInMonth =
DateUtils.getDaysInMonth(focusedDay.year, focusedDay.month);
final firstDayOfMonth = DateTime(focusedDay.year, focusedDay.month, 1);
final firstWeekday = firstDayOfMonth.weekday;
final days = <DateTime>[];
// Ajoute les jours vides avant le 1er du mois (pour aligner sur le bon jour de la semaine)
for (int i = 1; i < firstWeekday; i++) {
days.add(DateTime(0)); // jour vide
}
// Ajoute les jours du mois
for (int i = 0; i < daysInMonth; i++) {
days.add(DateTime(focusedDay.year, focusedDay.month, i + 1));
}
// Complète la dernière semaine si besoin
while (days.length % 7 != 0) {
days.add(DateTime(0));
}
return Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: List.generate(7, (i) {
const daysShort = ['L', 'M', 'M', 'J', 'V', 'S', 'D'];
return Expanded(
child: Center(
child: Text(daysShort[i],
style: const TextStyle(fontWeight: FontWeight.bold)),
),
);
}),
),
),
...List.generate(days.length ~/ 7, (week) {
return Row(
children: List.generate(7, (i) {
final day = days[week * 7 + i];
if (day.year == 0) {
return const Expanded(child: SizedBox.shrink());
}
final isSelected =
selectedDay != null && _isSameDay(day, selectedDay!);
final eventsForDay = events
.where((e) => _isSameDay(e.startDateTime, day))
.toList();
return Expanded(
child: GestureDetector(
onTap: () => onDaySelected(day),
child: Container(
color: Colors.transparent,
padding: const EdgeInsets.symmetric(vertical: 6),
child: Column(
children: [
Container(
decoration: isSelected
? BoxDecoration(
color: Theme.of(context)
.colorScheme
.primary
.withOpacity(0.15),
shape: BoxShape.circle,
)
: null,
padding: const EdgeInsets.all(4),
child: Text(
'${day.day}',
style: TextStyle(
fontWeight: FontWeight.w600,
color: isSelected
? Theme.of(context).colorScheme.primary
: null,
),
),
),
const SizedBox(height: 2),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: eventsForDay
.map((event) => Container(
margin: const EdgeInsets.symmetric(
horizontal: 1),
width: 6,
height: 6,
decoration: BoxDecoration(
color: _getColorForStatus(event.status),
shape: BoxShape.circle,
),
))
.toList(),
),
],
),
),
),
);
}),
);
}),
],
);
}
bool _isSameDay(DateTime a, DateTime b) {
return a.year == b.year && a.month == b.month && a.day == b.day;
}
Color _getColorForStatus(EventStatus status) {
switch (status) {
case EventStatus.confirmed:
return Colors.green;
case EventStatus.canceled:
return Colors.red;
case EventStatus.waitingForApproval:
default:
return Colors.amber;
}
}
}

View File

@ -283,10 +283,6 @@ class WeekView extends StatelessWidget {
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(_getStatusIcon(e.event.status),
color: _getStatusTextColor(e.event.status),
size: 16),
const SizedBox(width: 4),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,