mirror of
				https://gitlab.com/comunic/comunicmobile
				synced 2025-11-03 19:54:12 +00:00 
			
		
		
		
	Display Forez presence
This commit is contained in:
		
							
								
								
									
										165
									
								
								lib/ui/widgets/forez_presence_calendar_widget.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								lib/ui/widgets/forez_presence_calendar_widget.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,165 @@
 | 
			
		||||
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<PresenceCalendarWidget> {
 | 
			
		||||
  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<dynamic> 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<dynamic> events, List<dynamic> 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,
 | 
			
		||||
      );
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user