import 'package:flutter/material.dart'; import '../../app/app_controller.dart'; import '../../app/app_theme.dart'; import '../../domain/schedule_engine.dart'; import 'week_grid.dart'; class TimetablePage extends StatefulWidget { const TimetablePage({super.key, required this.controller}); final AppController controller; @override State createState() => _TimetablePageState(); } class _TimetablePageState extends State { int? _week; bool? _wasDemo; @override Widget build(BuildContext context) { final c = widget.controller, term = c.visibleSettings.semester; final today = ScheduleEngine.schoolDate(c.clock()); if (_wasDemo != c.isDemo) { _week = null; _wasDemo = c.isDemo; } final current = term == null ? 1 : (ScheduleEngine.weekNumber(term, today) ?? 1); final week = (_week ?? current).clamp(1, term?.totalWeeks ?? 1); final monday = term == null ? today.subtract(Duration(days: today.weekday - 1)) : term.firstMonday.add(Duration(days: (week - 1) * 7)); final sunday = monday.add(const Duration(days: 6)); return ListView( key: const PageStorageKey('timetable-scroll'), padding: EdgeInsets.fromLTRB( 8, 10, 8, 140 + MediaQuery.paddingOf(context).bottom, ), children: [ const Padding( padding: EdgeInsets.symmetric(horizontal: 14), child: Text( 'RSchedule', style: TextStyle(fontSize: 22, fontWeight: FontWeight.w700), ), ), const SizedBox(height: 10), SurfaceCard( padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 0), child: Row( children: [ IconButton( onPressed: term != null && week > 1 ? () => setState(() => _week = week - 1) : null, icon: const Icon(Icons.chevron_left_rounded), ), Expanded( child: Column( children: [ Text( term == null ? '本周' : '第 $week 周', style: const TextStyle( fontSize: 17, fontWeight: FontWeight.w700, ), ), const SizedBox(height: 4), Text( '${monday.month}.${monday.day.toString().padLeft(2, '0')} – ${sunday.month}.${sunday.day.toString().padLeft(2, '0')}', style: TextStyle( fontSize: 12, color: ink.withValues(alpha: 0.5), ), ), ], ), ), IconButton( onPressed: term != null && week < term.totalWeeks ? () => setState(() => _week = week + 1) : null, icon: const Icon(Icons.chevron_right_rounded), ), TextButton( onPressed: () => setState(() => _week = null), child: const Text('本周'), ), ], ), ), const SizedBox(height: 4), if (c.isDemo) Padding( padding: const EdgeInsets.only(bottom: 12), child: Wrap( crossAxisAlignment: WrapCrossAlignment.center, spacing: 8, children: [ Container( padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 7, ), decoration: BoxDecoration( color: const Color(0xFFE2EEFF), borderRadius: BorderRadius.circular(10), ), child: const Text( '示例课表', style: TextStyle( fontSize: 11, color: Color(0xFF356AA8), fontWeight: FontWeight.w600, ), ), ), const Text( '不会生成提醒或日历事件', style: TextStyle(fontSize: 10, color: Color(0xFF8193AB)), ), TextButton(onPressed: c.leaveDemo, child: const Text('退出示例')), ], ), ), if (term != null) ...[ WeekGrid( events: ScheduleEngine.occurrences( c.visibleCourses, term, ).where((e) => e.week == week).toList(), monday: monday, today: today, settings: c.visibleSettings, ), const SizedBox(height: 12), Text( '点击课程查看完整信息', textAlign: TextAlign.center, style: TextStyle(fontSize: 11, color: ink.withValues(alpha: 0.35)), ), ] else ...[ const SizedBox(height: 38), const Icon( Icons.calendar_month_outlined, size: 66, color: Color(0xFFB7CDF0), ), const SizedBox(height: 22), const Text( '让课表,陪你开启每一天', textAlign: TextAlign.center, style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600), ), const SizedBox(height: 12), Text( '在「个人设置」设置学期并导入课程,\n或先看看示例课表。', textAlign: TextAlign.center, style: TextStyle( fontSize: 13, height: 1.8, color: ink.withValues(alpha: 0.5), ), ), const SizedBox(height: 25), Center( child: FilledButton.icon( onPressed: c.showDemo, icon: const Icon(Icons.auto_awesome_outlined, size: 18), label: const Text('体验示例课表'), ), ), ], ], ); } }