import 'dart:developer'; import 'package:car_customer_app/view_models/appointments_view_model.dart'; import 'package:flutter/material.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/service_schedule_model.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:table_calendar/table_calendar.dart'; import 'package:provider/provider.dart'; import 'package:intl/intl.dart'; class CustomCalenderWidget extends StatefulWidget { final List? customTimeDateSlotList; const CustomCalenderWidget({super.key, required this.customTimeDateSlotList}); @override State createState() => _CustomCalenderWidgetState(); } class _CustomCalenderWidgetState extends State { List allDates = []; List allMonths = []; List datesInSelectedMonth = []; CalendarFormat _calendarFormat = CalendarFormat.month; late int selectedMonth; late int selectedYear; DateTime? _selectedDay; DateTime _focusedDay = DateTime.now(); @override void initState() { super.initState(); populateDateList(); } populateDateList() { for (var value in widget.customTimeDateSlotList!) { DateTime dt = DateFormat('dd MMMM, yyyy').parse(value.date!.date); // TODO: THIS COMPARISON NEEDS TO BE FIXED!!!!! // TODO: BECAUSE WE CAN ONLY VALUE IN DROPDOWN, SO SUBVALUE IS OF NO USE!! DropValue dv = DropValue(dt.month, "${dt.month.getMonthNameByNumber()}, ${dt.year}", ""); allDates.add(dt); if (!ifMonthAlreadyThere(dv)) { allMonths.add(dv); } } selectedMonth = allDates.first.month; selectedYear = allDates.first.year; datesInSelectedMonth = allDates.where((element) => element.month == selectedMonth).toList(); } bool ifMonthAlreadyThere(DropValue monthDate) { int index = allMonths.indexWhere((element) => element.id == monthDate.id && element.subValue == monthDate.subValue); if (index == -1) { return false; } return true; } bool ifDateAlreadyThere(DateTime dt) { int index = allDates.indexWhere((element) => dt.month == element.month && dt.year == element.year); if (index == -1) { return false; } return true; } @override Widget build(BuildContext context) { return Consumer( builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) { return Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Builder(builder: (context) { return DropdownField( (DropValue value) { setState(() { selectedYear = int.parse(value.value.split(',')[1]); selectedMonth = value.value.split(',')[0].getMonthNumberByName(); }); }, list: allMonths, // dropdownValue: DropValue(1, "${selectedMonth.getMonthNameByNumber()}jhvk,", "${selectedYear}"), hint: "${selectedMonth.getMonthNameByNumber()}, $selectedYear", errorValue: "", showAppointmentPickerVariant: true, ); }), ), Spacer(), Icon( Icons.calendar_today, color: Colors.black, size: 18, ).paddingOnly(right: 10) ], ).paddingOnly(left: 6, right: 0), TableCalendar( headerVisible: false, firstDay: datesInSelectedMonth.first, lastDay: datesInSelectedMonth.last, focusedDay: _focusedDay, calendarFormat: _calendarFormat, weekendDays: [DateTime.friday, DateTime.saturday], daysOfWeekHeight: 30, availableGestures: AvailableGestures.none, daysOfWeekStyle: DaysOfWeekStyle( weekdayStyle: TextStyle(fontSize: 14, color: MyColors.black), weekendStyle: TextStyle(fontSize: 14, color: MyColors.black.withOpacity(0.5)), ), calendarBuilders: CalendarBuilders( todayBuilder: (BuildContext context, DateTime dateTime1, DateTime dateTime2) { return Container( height: 50, width: 50, margin: EdgeInsets.all(5), decoration: BoxDecoration( color: Colors.blueAccent.withOpacity(0.4), border: Border.all(color: Colors.orange, width: 2), shape: BoxShape.circle, ), alignment: Alignment.center, child: Text( dateTime1.day.toString(), ), ); }, selectedBuilder: (BuildContext context, DateTime dateTime1, DateTime dateTime2) { return Container( height: 50, width: 50, margin: EdgeInsets.all(5), decoration: BoxDecoration( shape: BoxShape.circle, color: MyColors.darkIconColor, ), alignment: Alignment.center, child: Text( dateTime2.day.toString(), style: TextStyle(color: MyColors.white), ), ); }, defaultBuilder: (BuildContext context, DateTime dateTime1, DateTime dateTime2) { return Container( height: 50, width: 50, margin: EdgeInsets.all(5), decoration: BoxDecoration( border: Border.all(color: Colors.orange, width: 2), shape: BoxShape.circle, ), alignment: Alignment.center, child: Text( dateTime1.day.toString(), ), ); }, disabledBuilder: (BuildContext context, DateTime dateTime1, DateTime selectedDt) { return Container( height: 50, width: 50, margin: EdgeInsets.all(5), decoration: BoxDecoration( border: Border.all(color: Colors.grey), shape: BoxShape.circle, ), alignment: Alignment.center, child: Text( dateTime1.day.toString(), ), ); }, ), headerStyle: HeaderStyle(formatButtonVisible: false), selectedDayPredicate: (day) { // Use `selectedDayPredicate` to determine which day is currently selected. // If this returns true, then `day` will be marked as selected. // Using `isSameDay` is recommended to disregard // the time-part of compared DateTime objects. return isSameDay(_selectedDay, day); }, onDaySelected: (selectedDay, focusedDay) { if (!isSameDay(_selectedDay, selectedDay)) { // Call `setState()` when updating the selected day setState(() { _selectedDay = selectedDay; _focusedDay = selectedDay; }); } }, ), ], ); }, ); } }