import 'package:comunic/lists/forez_presences_set.dart'; import 'package:comunic/utils/date_utils.dart' as date_utils; /// Forez presence calendar widget /// /// This widget is used only by Forez groups /// /// @author Pierre Hubert import 'package:flutter/material.dart'; import 'package:table_calendar/table_calendar.dart'; enum CalendarDisplayMode { SINGLE_USER, MULTIPLE_USERS } extension DateOnlyCompare on DateTime { bool isSameDate(DateTime other) => date_utils.isSameDate(this, other); } class PresenceCalendarWidget extends StatefulWidget { final PresenceSet presenceSet; final void Function(DateTime) onDayClicked; final CalendarDisplayMode mode; final DateTime selectedDay; const PresenceCalendarWidget({ Key key, @required this.presenceSet, this.onDayClicked, this.mode = CalendarDisplayMode.SINGLE_USER, this.selectedDay, }) : assert(presenceSet != null), assert(mode != null), super(key: key); @override _PresenceCalendarWidgetState createState() => _PresenceCalendarWidgetState(); } class _PresenceCalendarWidgetState extends State { CalendarController _calendarController; @override void initState() { super.initState(); _calendarController = CalendarController(); } @override void dispose() { _calendarController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return TableCalendar( calendarController: _calendarController, locale: "fr_FR", weekendDays: [], onHeaderTapped: _pickDate, builders: CalendarBuilders(dayBuilder: _dayBuilder), onDaySelected: _selectedDay, availableCalendarFormats: const {CalendarFormat.month: "Mois"}, ); } void _pickDate(DateTime date) async { final pickedDate = await showDatePicker( context: context, initialDate: date, firstDate: DateTime.now().subtract(Duration(days: 20)), lastDate: DateTime.now().add(Duration(days: 365 * 5)), ); if (pickedDate != null) { _calendarController.setSelectedDay(pickedDate, animate: true); setState(() {}); } } Widget _dayBuilder( BuildContext context, DateTime date, List events) { if (widget.presenceSet.containsDate(date)) { // Show the number of users who are present if (widget.mode == CalendarDisplayMode.MULTIPLE_USERS) return Stack( children: [ CellWidget( text: date.day.toString(), color: Colors.green, textColor: Colors.white, circle: false, selected: date.isSameDate(widget.selectedDay), ), Positioned( child: Material( child: Padding( padding: const EdgeInsets.all(2.0), child: Text(widget.presenceSet.countAtDate(date).toString()), ), textStyle: TextStyle(color: Colors.white), color: Colors.red, ), bottom: 4, right: 4, ), ], ); // Only show green circle else return CellWidget( text: date.day.toString(), color: Colors.green, textColor: Colors.white, ); } return CellWidget( text: date.day.toString(), selected: date.isSameDate(widget.selectedDay), ); } void _selectedDay( DateTime day, List events, List holidays) { if (widget.onDayClicked != null) widget.onDayClicked(day); } } class CellWidget extends StatelessWidget { final String text; final Color color; final Color textColor; final bool circle; final bool selected; const CellWidget({ Key key, @required this.text, this.color, this.textColor, this.circle = true, this.selected, }) : assert(text != null), super(key: key); @override Widget build(BuildContext context) { return AnimatedContainer( duration: const Duration(milliseconds: 250), decoration: _buildCellDecoration(), margin: const EdgeInsets.all(6.0), alignment: Alignment.center, child: Text( text, textAlign: TextAlign.center, style: TextStyle(color: selected ?? false ? Colors.white : textColor), ), ); } Decoration _buildCellDecoration() => BoxDecoration( shape: circle ? BoxShape.circle : BoxShape.rectangle, color: selected ?? false ? Colors.deepPurple : color, ); }