import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:lucide_icons/lucide_icons.dart'; import '../../../../core/theme/design_tokens.dart'; import '../widgets/bottom_dock.dart'; class CalendarDayWeekScreen extends StatefulWidget { const CalendarDayWeekScreen({super.key}); @override State createState() => _CalendarDayWeekScreenState(); } class _CalendarDayWeekScreenState extends State { DateTime _selectedDate = DateTime(2026, 2, 9); late DateTime _weekStart; @override void initState() { super.initState(); _weekStart = _getWeekStart(_selectedDate); } DateTime _getWeekStart(DateTime date) { return date.subtract(Duration(days: date.weekday % 7)); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFFF8FAFC), body: SafeArea( child: Column( children: [ _buildHeader(), Expanded( child: SingleChildScrollView( child: Padding( padding: const EdgeInsets.only( left: 16, right: 16, top: 2, bottom: 104, ), child: Column( children: [ _buildWeekStrip(), const SizedBox(height: 8), _buildTimelineBoard(), ], ), ), ), ), _buildBottomDock(), ], ), ), ); } Widget _buildHeader() { return SizedBox( height: 68, child: Padding( padding: const EdgeInsets.only(left: 20, right: 20, top: 12, bottom: 8), child: Row( children: [ GestureDetector( onTap: () => Navigator.of(context).pop(), child: Container( height: 36, padding: const EdgeInsets.symmetric(horizontal: 10), decoration: BoxDecoration( color: const Color(0xFFF8FAFF), borderRadius: BorderRadius.circular(18), border: Border.all(color: const Color(0xFFDEE7F6)), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ const Icon( LucideIcons.chevronLeft, size: 16, color: AppColors.slate700, ), const SizedBox(width: 6), Text( '${_selectedDate.year}年${_selectedDate.month}月', style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w600, color: AppColors.slate700, ), ), ], ), ), ), ], ), ), ); } Widget _buildWeekStrip() { return SizedBox( height: 86, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: List.generate(7, (index) { final date = _weekStart.add(Duration(days: index)); final isSelected = date.day == _selectedDate.day && date.month == _selectedDate.month && date.year == _selectedDate.year; final isWeekend = index == 0 || index == 6; return GestureDetector( onTap: () { setState(() { _selectedDate = date; }); }, child: _buildDayItem(date, isSelected, isWeekend), ); }), ), ); } Widget _buildDayItem(DateTime date, bool isSelected, bool isWeekend) { final dayNames = ['日', '一', '二', '三', '四', '五', '六']; return Column( mainAxisSize: MainAxisSize.min, children: [ Text( dayNames[date.weekday % 7], style: TextStyle( fontSize: 11, color: isWeekend ? AppColors.slate400 : AppColors.slate600, ), ), const SizedBox(height: 2), Text( '${date.day}', style: TextStyle( fontSize: isSelected ? 17 : (isWeekend ? 17 : 17), fontWeight: isSelected ? FontWeight.w700 : FontWeight.w600, color: isSelected ? AppColors.blue600 : (isWeekend ? AppColors.slate400 : AppColors.slate900), ), ), ], ); } Widget _buildTimelineBoard() { return Column( children: [ _buildTimelineRow('07:00', false), _buildTimelineRow('08:00', false), _buildTimelineRow( '09:00', true, eventText: '购票提醒', eventColor: AppColors.slate500, ), _buildTimelineRow('10:00', false), _buildTimelineRow('11:00', false), _buildTimelineRow('12:00', false), _buildTimelineRow('13:00', false), _buildTimelineRow('14:00', false), _buildTimelineRow('15:00', false), _buildTimelineRow('15:28', false, isCurrentTime: true), _buildTimelineRow( '16:00', true, eventText: '购票提醒', eventColor: const Color(0xFF6B21A8), eventBg: const Color(0xFFE9D5FF), eventBorder: const Color(0xFFD8B4FE), ), _buildTimelineRow('17:00', false), _buildTimelineRow('18:00', false), _buildTimelineRow('19:00', false), _buildTimelineRow('20:00', false), _buildTimelineRow('21:00', false), _buildTimelineRow('22:00', false), _buildTimelineRow('00:00', false, isDisabled: true), ], ); } Widget _buildTimelineRow( String time, bool hasEvent, { String? eventText, Color? eventColor, Color? eventBg, Color? eventBorder, bool isCurrentTime = false, bool isDisabled = false, }) { return SizedBox( height: 34, child: Row( children: [ SizedBox( width: 44, child: isCurrentTime ? Container( width: 44, height: 18, decoration: BoxDecoration( color: const Color(0xFFEF4444), borderRadius: BorderRadius.circular(9), ), child: Center( child: Text( time, style: const TextStyle( fontSize: 10, fontWeight: FontWeight.w700, color: Colors.white, ), ), ), ) : Text( time, textAlign: TextAlign.right, style: TextStyle( fontSize: 10, fontWeight: FontWeight.w600, color: isDisabled ? AppColors.slate300 : const Color(0xFF9CA3AF), ), ), ), const SizedBox(width: 8), Expanded( child: isCurrentTime ? Container( height: 2, decoration: BoxDecoration( color: const Color(0xFFEF4444), borderRadius: BorderRadius.circular(99), ), ) : hasEvent ? Container( height: 22, padding: const EdgeInsets.symmetric(horizontal: 8), decoration: BoxDecoration( color: eventBg ?? const Color(0xFFE5E7EB), borderRadius: BorderRadius.circular(8), border: Border.all( color: eventBorder ?? const Color(0xFFD1D5DB), ), ), child: Align( alignment: Alignment.centerLeft, child: Text( eventText ?? '', style: TextStyle( fontSize: 11, fontWeight: FontWeight.w600, color: eventColor ?? const Color(0xFF6B7280), ), ), ), ) : Container( height: 1, color: isDisabled ? const Color(0xFFECEFF4) : const Color(0xFFE5E7EB), ), ), ], ), ); } Widget _buildBottomDock() { return BottomDock( activeTab: DockTab.calendar, onTodoTap: () => context.push('/todo'), onCalendarTap: () {}, onHomeTap: () => Navigator.of(context).pop(), ); } }