import 'package:ac_web/Api/AcApi.dart'; import 'package:ac_web/Api/Dtos/EReportType.dart'; import 'package:ac_web/Api/Dtos/ReportDto.dart'; import 'package:ac_web/Pages/ReportDetails.dart'; import 'package:ac_web/Widgets/LatestReportEntry.dart'; import 'package:ac_web/Widgets/LatestReportHeader.dart'; import 'package:ac_web/Widgets/ReportTypeIcons.dart'; import 'package:flutter/material.dart'; class LatestReportColumn extends StatefulWidget{ const LatestReportColumn({super.key, this.title = "Latest Reports", this.filterType}); /// Headline drawn above the first day header. final String title; /// When set, only reports of this type are shown. final EReportType? filterType; @override State createState() => _LatestReportColumnState(); } class _LatestReportColumnState extends State{ late Future> mReportsFuture; @override void initState() { super.initState(); mReportsFuture = AcApi.instance.reports.getReports(); } @override Widget build(BuildContext context) { return FutureBuilder>( future: mReportsFuture, builder: (context, snapshot) { if (snapshot.connectionState != ConnectionState.done) { return const Center(child: CircularProgressIndicator()); } if (snapshot.hasError) { return Center(child: Text('Could not load reports: ${snapshot.error}')); } // The list of reports fetched from the ReportsController. List reports = snapshot.data ?? []; if (widget.filterType != null) { reports = reports .where((report) => report.type == widget.filterType) .toList(); } return _buildList(reports); }, ); } Widget _buildList(List reports) { List widgets = []; if (reports.isEmpty) { return ListView( padding: EdgeInsetsGeometry.all(8), children: [ LatestReportHeader(text: widget.title, bigHeader: true,), const SizedBox(height: 16), const Text("No reports available."), ], ); } // Title Entry widgets.add(LatestReportHeader(text: widget.title, bigHeader: true,)); DateTime? lastDay; // Iterate through the reports and create Report entries accordingly for(int i = 0; i < reports.length; i++){ // Add a day header above the first entry of every day final DateTime day = _dayOf(reports[i].timestamp); if(lastDay == null || day != lastDay){ widgets.add(LatestReportHeader(text: _dayLabel(day))); lastDay = day; } final ReportDto report = reports[i]; final IconData icon = reports[i].type.icon; widgets.add(LatestReportEntry( text: reports[i].title, icon: icon, author: reports[i].author, timestamp: reports[i].timestamp, onTap: () => _openReport(report), )); } return ListView( padding: EdgeInsetsGeometry.all(8), children: widgets, ); } /// Opens a new page that shows all details of the given report. void _openReport(ReportDto report) { Navigator.of(context).push( MaterialPageRoute( builder: (context) => ReportDetails(report: report), ), ); } /// Strips the time part, so that two timestamps of the same day are equal. DateTime _dayOf(DateTime timestamp) { final DateTime local = timestamp.toLocal(); return DateTime(local.year, local.month, local.day); } /// "Today", "Yesterday" or e.g. "15. August" for all other days. String _dayLabel(DateTime day) { final DateTime today = _dayOf(DateTime.now()); final DateTime yesterday = DateTime(today.year, today.month, today.day - 1); if (day == today) { return "Today"; } if (day == yesterday) { return "Yesterday"; } return "${day.day}. ${_monthNames[day.month - 1]}"; } static const List _monthNames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", ]; }