import 'package:flisp_app/models/calendar.dart'; import 'package:flisp_app/provider/calendar_provider.dart'; import 'package:flisp_app/widgets/common.dart'; import 'package:flutter/material.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; class CalendarForm extends StatefulWidget { final GlobalKey formKey; final bool isEditing; final Calendar? initialCalendar; const CalendarForm({ super.key, required this.formKey, required this.isEditing, this.initialCalendar, }); @override State createState() => _CalendarFormState(); } class _CalendarFormState extends State { final int maxTitleCount = 10; @override void initState() { super.initState(); } Widget buildTitle() { final colors = Theme.of(context).colorScheme; return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( widget.isEditing ? Icons.edit_note : Icons.add_task, color: colors.primary, size: 24, ), SizedBox(width: 8), Text( widget.isEditing ? '编辑日程事项' : '添加日程事项', style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: colors.primary, ), ), ], ); } String? titleFieldValidator(value) { if (value == null || value.isEmpty) { return '请输入标题'; } if (value.length > maxTitleCount) { return '标题不能超过$maxTitleCount个字符'; } return null; } FormBuilderTextField buildTitleField(CalendarProvider provider) { final colors = Theme.of(context).colorScheme; return FormBuilderTextField( name: 'title', initialValue: provider.formItem.title, onChanged: (value) { setState(() { provider.formItem.title = value ?? ''; }); }, decoration: InputDecoration( label: RichText( text: TextSpan( text: '内容', style: TextStyle( color: Colors.grey, fontSize: 16, fontFamily: 'CustomFont', ), children: const [ TextSpan( text: '*', style: TextStyle( color: Colors.red, fontSize: 18, fontWeight: FontWeight.bold, ), ), ], ), ), hintText: '请输入日程标题...', hintStyle: TextStyle(color: Colors.grey), counterText: '', suffixText: '${provider.formItem.title.length}/$maxTitleCount', border: buildFormBoard(), enabledBorder: buildFormEnabledBoard(), focusedBorder: buildFormFocusedBoard(colors), filled: true, fillColor: colors.surface, prefixIcon: Icon(Icons.title, color: Colors.blue), contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 14), ), maxLength: maxTitleCount, validator: (value) => titleFieldValidator(value), ); } String? startTimeFieldValidator(CalendarProvider provider, value) { if (value == null) { return '请选择开始时间'; } if (value.isBefore(DateTime.now())) { return '不能选择过去的日期'; } final endTime = provider.formItem.endTime; if (endTime != null && endTime.isBefore(value)) { return '结束时间不能早于开始时间'; } if (endTime != null && endTime.isAtSameMomentAs(value)) { return '开始时间不能等于结束时间'; } return null; } FormBuilderDateTimePicker buildStartTimeField(CalendarProvider provider) { final colors = Theme.of(context).colorScheme; var startTime = provider.formItem.startTime; return FormBuilderDateTimePicker( name: 'startTime', format: DateFormat('yyyy-MM-dd HH:mm:ss'), initialValue: startTime, inputType: InputType.both, onChanged: (value) { setState(() { provider.formItem.startTime = value!; }); }, decoration: InputDecoration( labelText: startTime == null ? '选择开始时间' : '开始时间: ', labelStyle: TextStyle(color: Colors.grey), prefixIcon: Icon(Icons.calendar_month, color: Colors.purple), border: buildFormBoard(), enabledBorder: buildFormEnabledBoard(), focusedBorder: buildFormFocusedBoard(colors), filled: true, fillColor: colors.surface, contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 14), ), validator: (value) => startTimeFieldValidator(provider, value), ); } String? endTimeFieldValidator(CalendarProvider provider, value) { if (value == null) { return '请选择结束时间'; } if (value.isBefore(DateTime.now())) { return '不能选择过去的日期'; } final startTime = provider.formItem.startTime; if (startTime != null && value.isBefore(startTime)) { return '结束时间不能早于开始时间'; } if (startTime != null && startTime.isAtSameMomentAs(value)) { return '开始时间不能等于结束时间'; } return null; } FormBuilderDateTimePicker buildEndTimeField(CalendarProvider provider) { final colors = Theme.of(context).colorScheme; var endTime = provider.formItem.endTime; return FormBuilderDateTimePicker( name: 'endTime', format: DateFormat('yyyy-MM-dd HH:mm:ss'), initialValue: endTime, inputType: InputType.both, onChanged: (value) { setState(() { provider.formItem.endTime = value!; }); }, decoration: InputDecoration( labelText: endTime == null ? '选择结束时间' : '结束时间: ', labelStyle: TextStyle(color: Colors.grey), prefixIcon: Icon(Icons.calendar_month, color: Colors.purple), border: buildFormBoard(), enabledBorder: buildFormEnabledBoard(), focusedBorder: buildFormFocusedBoard(colors), filled: true, fillColor: colors.surface, contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 14), ), validator: (value) => endTimeFieldValidator(provider, value), ); } IconButton buildClearScheduled(CalendarProvider provider) { return IconButton( icon: Icon(Icons.clear, size: 18), onPressed: () { setState(() { provider.formItem.scheduledTime = null; }); widget.formKey.currentState?.fields['scheduledTime']?.didChange(null); }, ); } String? scheduledTimeFieldValidator(value) { if (value != null && value.isBefore(DateTime.now())) { return '不能选择过去的日期'; } return null; } FormBuilderDateTimePicker buildScheduledTimeField(CalendarProvider provider) { final colors = Theme.of(context).colorScheme; var scheduledTime = provider.formItem.scheduledTime; return FormBuilderDateTimePicker( name: 'scheduledTime', format: DateFormat('yyyy-MM-dd HH:mm:ss'), initialValue: scheduledTime, inputType: InputType.both, onChanged: (value) { setState(() { provider.formItem.scheduledTime = value; }); }, decoration: InputDecoration( labelText: scheduledTime == null ? '选择提醒时间' : '提醒时间: ', labelStyle: TextStyle(color: Colors.grey), prefixIcon: Icon(Icons.calendar_month, color: Colors.purple), border: buildFormBoard(), enabledBorder: buildFormEnabledBoard(), focusedBorder: buildFormFocusedBoard(colors), filled: true, fillColor: colors.surface, contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 14), suffixIcon: scheduledTime != null ? buildClearScheduled(provider) : null, ), validator: (value) => scheduledTimeFieldValidator(value), ); } FormBuilder buildForm(CalendarProvider provider) { return FormBuilder( key: widget.formKey, child: Column( mainAxisSize: MainAxisSize.min, children: [ buildTitleField(provider), SizedBox(height: 12), buildStartTimeField(provider), SizedBox(height: 12), buildEndTimeField(provider), SizedBox(height: 12), buildScheduledTimeField(provider), ], ), ); } @override Widget build(BuildContext context) { final provider = Provider.of(context); return Padding( padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 10), child: Column( mainAxisSize: MainAxisSize.min, children: [buildTitle(), SizedBox(height: 20), buildForm(provider)], ), ); } }