import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:intl/intl.dart'; import '../../../utils/definitions/color_pair.dart'; import '../../../utils/logic/preferences_service.dart'; // Correct the path as necessary class CalendarWidget extends StatefulWidget { final DateTime currentDate; const CalendarWidget({Key? key, required this.currentDate}) : super(key: key); @override State createState() => _CalendarWidget(); } class _CalendarWidget extends State { List dateList = []; // Initialized immediately as an empty list Map diaryEntries = {}; // Holds diary entries by date late ColorPair currentColorPair; // Holds the current color pair @override void initState() { super.initState(); dateList = _generateDateList(widget.currentDate); // Ensured initialization _loadColorPairAndDiaryData(); } void _loadColorPairAndDiaryData() async { // Load color pair currentColorPair = await PreferencesService().loadColorPair(); // Generate date list //dateList = _generateDateList(widget.currentDate); // Load diary entries for each date for (DateTime date in dateList) { DiaryEntry? entry = await PreferencesService().getDiaryEntryByDate(date); String key = DateFormat('yyyy-MM-dd').format(date); diaryEntries[key] = entry; } setState(() {}); // Update the state to reflect new data } List _generateDateList(DateTime date) { List list = []; DateTime firstOfMonth = DateTime(date.year, date.month, 1); int dayOfWeek = firstOfMonth.weekday; // Adjust to Monday start int startDay = dayOfWeek - 1; if (startDay < 0) startDay = 6; // Dates from previous month to fill the first row for (int i = startDay; i > 0; i--) { list.add(firstOfMonth.subtract(Duration(days: i))); } // Dates of current month up to the current date int daysInMonth = DateUtils.getDaysInMonth(date.year, date.month); DateTime today = DateTime.now(); for (int i = 0; i < daysInMonth; i++) { DateTime current = DateTime(date.year, date.month, i + 1); if (current.isAfter(today)) break; // Stop adding dates after today list.add(current); } // Add dates of the next month to complete the week, if necessary DateTime firstOfNextMonth = DateTime(date.year, date.month + 1, 1); while (list.length % 7 != 0 && !firstOfNextMonth.isAfter(DateTime.now())) { list.add(firstOfNextMonth); firstOfNextMonth = firstOfNextMonth.add(const Duration(days: 1)); } return list; } @override Widget build(BuildContext context) { double addon = dateList.length > 35 ? 50 : 0; String monthName = DateFormat("MMMM yyyy").format(widget.currentDate); // For month header return FutureBuilder( future: PreferencesService().loadColorPair(), builder: (context, snapshot) { if (!snapshot.hasData) { return const Center(child: CircularProgressIndicator()); } ColorPair colorPair = snapshot.data!; return SizedBox( height: 360 + addon, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 30), child: Text(monthName, style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold)), // Month Header ), Expanded( child: Padding( padding: const EdgeInsets.fromLTRB(25, 0, 25, 0), child: GridView.builder( physics: const NeverScrollableScrollPhysics(), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 7, ), itemBuilder: (context, index) { DateTime date = dateList[index]; bool isCurrentMonth = date.month == widget.currentDate.month; double opacity = isCurrentMonth ? 1.0 : 0.15; // Fetching diary entry percentage value DiaryEntry? entry = diaryEntries[DateFormat('yyyy-MM-dd').format(date)]; double fillPercentage = entry != null ? entry.percentValue / 100.0 : 0.0; return Center( child: GestureDetector( onTap: () { DiaryEntry? entry = diaryEntries[DateFormat('yyyy-MM-dd').format(date)]; if (entry != null) { context.go('/entry', extra: date); } else { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text("no entry there :("), duration: Duration(seconds: 2), ), ); } }, child: Container( width: 50, height: 50, decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all(color: Colors.black, width: 1), color: DateTime.now().day == date.day && DateTime.now().month == date.month && DateTime.now().year == date.year ? Colors.transparent // Setting background color for current day : isCurrentMonth ? Colors.transparent : Colors.grey.withOpacity(opacity), ), child: Stack( alignment: Alignment.center, children: [ CircleWidget( radius: 25 * fillPercentage, color: fillPercentage > 0 ? colorPair.backgroundColor : Colors.teal.withOpacity(opacity)), Text( DateTime.now().day == date.day && DateTime.now().month == date.month && DateTime.now().year == date.year ? "today" : DateFormat("d").format(date), style: const TextStyle(color: Colors.black, fontSize: 16), ), ], ), ), ), ); }, itemCount: dateList.length, ), ), ), ], ), ); }); } } class CircleWidget extends StatelessWidget { final double radius; final Color color; const CircleWidget({Key? key, required this.radius, required this.color}) : super(key: key); @override Widget build(BuildContext context) { return Container( width: radius * 2, height: radius * 2, decoration: BoxDecoration( shape: BoxShape.circle, color: color, ), ); } }