import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import '../../../../core/di/injection.dart'; import '../../../../core/theme/design_tokens.dart'; import '../../../calendar/ui/calendar_state_manager.dart'; import '../../../calendar/ui/widgets/bottom_dock.dart'; class TodoQuadrantsScreen extends StatefulWidget { const TodoQuadrantsScreen({super.key}); @override State createState() => _TodoQuadrantsScreenState(); } class _TodoQuadrantsScreenState extends State { late List<_TodoItem> _importantUrgent; late List<_TodoItem> _urgentNotImportant; late List<_TodoItem> _importantNotUrgent; @override void initState() { super.initState(); _importantUrgent = [ _TodoItem(title: '18:00 前提交活动方案'), _TodoItem(title: '回复客户邀约确认'), ]; _urgentNotImportant = [ _TodoItem(title: '确认会场停车信息'), _TodoItem(title: '代订明早高铁票'), ]; _importantNotUrgent = [ _TodoItem(title: '本周复盘与下周规划'), _TodoItem(title: '整理个人知识库结构'), _TodoItem(title: '优化三月目标里程碑'), ]; } void _removeItem(String id, List<_TodoItem> list) { setState(() { list.removeWhere((item) => item.id == id); }); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColors.todoBg, body: SafeArea( child: Column( children: [ _buildHeader(), Expanded(child: _buildContent()), _buildBottomDock(), ], ), ), ); } Widget _buildHeader() { return SizedBox( height: 72, child: Padding( padding: const EdgeInsets.only(left: 16, right: 16, top: 14, bottom: 8), child: Align( alignment: Alignment.centerLeft, child: const Text( '待办事项', style: TextStyle( fontFamily: 'Inter', fontSize: 22, fontWeight: FontWeight.w700, color: AppColors.slate900, ), ), ), ), ); } Widget _buildContent() { return Padding( padding: const EdgeInsets.only(left: 16, right: 16, top: 4, bottom: 96), child: ListView( children: [ _buildQuadrant( title: '重要紧急', textColor: AppColors.g1Text, dividerColor: AppColors.g1Divider, borderColor: AppColors.g1Border, items: _importantUrgent, onRemove: (id) => _removeItem(id, _importantUrgent), ), const SizedBox(height: 12), _buildQuadrant( title: '紧急不重要', textColor: AppColors.g2Text, dividerColor: AppColors.g2Divider, borderColor: AppColors.g2Border, items: _urgentNotImportant, onRemove: (id) => _removeItem(id, _urgentNotImportant), ), const SizedBox(height: 12), _buildQuadrant( title: '重要不紧急', textColor: AppColors.g3Text, dividerColor: AppColors.g3Divider, borderColor: AppColors.g3Border, items: _importantNotUrgent, onRemove: (id) => _removeItem(id, _importantNotUrgent), ), ], ), ); } Widget _buildQuadrant({ required String title, required Color textColor, required Color dividerColor, required Color borderColor, required List<_TodoItem> items, required void Function(String) onRemove, }) { return Container( width: double.infinity, padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: AppColors.todoCardBg, borderRadius: BorderRadius.circular(14), border: Border.all(color: borderColor, width: 1), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( title, style: TextStyle( fontFamily: 'Inter', fontSize: 15, fontWeight: FontWeight.w700, color: textColor, ), ), Text( '${items.length}项', style: TextStyle( fontFamily: 'Inter', fontSize: 12, fontWeight: FontWeight.w700, color: textColor, ), ), ], ), const SizedBox(height: 8), Container(height: 1, color: dividerColor), const SizedBox(height: 8), ...items.map((item) => _buildTodoItem(item, onRemove)), ], ), ); } Widget _buildTodoItem(_TodoItem item, void Function(String) onRemove) { return _TodoItemWidget( key: ValueKey(item.id), item: item, onRemove: onRemove, ); } Widget _buildBottomDock() { return BottomDock( activeTab: DockTab.todo, onTodoTap: () {}, onCalendarTap: () { final manager = sl(); final viewType = manager.viewType; final date = manager.selectedDate; final dateStr = '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}'; if (viewType == CalendarViewType.month) { context.push('/calendar/month'); } else { context.push('/calendar/dayweek?date=$dateStr'); } }, onHomeTap: () => context.go('/home'), ); } } class _TodoItem { final String id; final String title; _TodoItem({required this.title}) : id = DateTime.now().microsecondsSinceEpoch.toString(); } class _TodoItemWidget extends StatefulWidget { final _TodoItem item; final void Function(String) onRemove; const _TodoItemWidget({ super.key, required this.item, required this.onRemove, }); @override State<_TodoItemWidget> createState() => _TodoItemWidgetState(); } class _TodoItemWidgetState extends State<_TodoItemWidget> with SingleTickerProviderStateMixin { bool _isChecked = false; late AnimationController _controller; late Animation _scaleAnimation; @override void initState() { super.initState(); _controller = AnimationController( duration: const Duration(milliseconds: 200), vsync: this, ); _scaleAnimation = Tween( begin: 0.0, end: 1.0, ).animate(CurvedAnimation(parent: _controller, curve: Curves.easeOutBack)); } @override void dispose() { _controller.dispose(); super.dispose(); } void _handleTap() { if (_isChecked) return; setState(() { _isChecked = true; }); _controller.forward().then((_) { widget.onRemove(widget.item.id); }); } @override Widget build(BuildContext context) { return SizedBox( height: 42, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( child: Text( widget.item.title, style: const TextStyle( fontFamily: 'Inter', fontSize: 13, fontWeight: FontWeight.w600, color: AppColors.slate700, ), ), ), GestureDetector( onTap: _handleTap, child: AnimatedBuilder( animation: _controller, builder: (context, child) { return Container( width: 20, height: 20, decoration: BoxDecoration( color: _isChecked ? AppColors.blue600 : Colors.white, border: Border.all( color: _isChecked ? AppColors.blue600 : AppColors.slate300, width: 1.5, ), borderRadius: BorderRadius.circular(4), ), child: _isChecked ? Transform.scale( scale: _scaleAnimation.value, child: const Icon( Icons.check, size: 14, color: Colors.white, ), ) : null, ); }, ), ), ], ), ); } }