Files
flisp_app/lib/widgets/reminder_form.dart
2025-11-08 22:06:16 +08:00

209 lines
6.5 KiB
Dart

import 'package:flisp_app/models/reminder.dart';
import 'package:flisp_app/provider/reminder_provider.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';
import 'package:flisp_app/utils/date_utils.dart';
class ReminderForm extends StatefulWidget {
final GlobalKey<FormBuilderState> formKey;
final bool isEditing;
final Reminder? initialReminder;
const ReminderForm({
super.key,
required this.formKey,
required this.isEditing,
this.initialReminder,
});
@override
State<ReminderForm> createState() => _ReminderFormState();
}
class _ReminderFormState extends State<ReminderForm> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
final int maxTitleCount = 10;
final int maxContentCount = 20;
final provider = Provider.of<ReminderProvider>(context);
Widget buildTitle() {
return Row(
children: [
Icon(
widget.isEditing ? Icons.edit_note : Icons.add_task,
color: Colors.orange,
size: 24,
),
SizedBox(width: 8),
Text(
widget.isEditing ? '编辑提醒事项' : '添加提醒事项',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.orange,
),
),
],
);
}
FormBuilderTextField buildTitleField() {
return FormBuilderTextField(
name: 'title',
initialValue: provider.formItem.title,
onChanged: (value) {
setState(() {
provider.formItem.title = value ?? '';
});
},
decoration: InputDecoration(
labelText: '标题',
hintText: '请输入提醒事项标题...',
counterText: '',
suffixText: '${provider.formItem.title.length}/$maxTitleCount',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Colors.grey.shade200),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Colors.grey.shade200),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Colors.orange),
),
filled: true,
fillColor: Colors.white,
prefixIcon: Icon(Icons.title, color: Colors.blue),
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 14),
),
maxLength: maxTitleCount,
validator: (value) {
if (value == null || value.isEmpty) {
return '请输入标题';
}
if (value.length > maxTitleCount) {
return '标题不能超过$maxTitleCount个字符';
}
return null;
},
);
}
FormBuilderTextField buildContentField() {
return FormBuilderTextField(
name: 'content',
initialValue: provider.formItem.content,
onChanged: (value) {
setState(() {
provider.formItem.content = value ?? '';
});
},
decoration: InputDecoration(
labelText: '内容',
hintText: '请输入提醒事项内容...',
counterText: '',
suffixText: '${provider.formItem.content.length}/$maxContentCount',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Colors.grey.shade200),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Colors.grey.shade200),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Colors.orange),
),
filled: true,
fillColor: Colors.white,
prefixIcon: Icon(Icons.description, color: Colors.green),
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 14),
),
maxLines: 2,
maxLength: maxContentCount,
validator: (value) {
if (value != null && value.length > maxContentCount) {
return '内容不能超过$maxContentCount个字符';
}
return null;
},
);
}
FormBuilderDateTimePicker buildDateField() {
return FormBuilderDateTimePicker(
name: 'dueDate',
format: DateFormat('yyyy-MM-dd HH:mm:ss'),
initialValue: provider.formItem.scheduledTime,
inputType: InputType.both,
onChanged: (value) {
setState(() {
provider.formItem.scheduledTime = value!;
});
},
decoration: InputDecoration(
labelText: '提醒时间',
labelStyle: TextStyle(color: Colors.black87),
prefixIcon: Icon(Icons.calendar_today, color: Colors.purple),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Colors.grey.shade200),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Colors.grey.shade200),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Colors.orange),
),
filled: true,
fillColor: Colors.white,
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 14),
),
validator: (value) {
if (value != null && value.isBefore(DateTime.now())) {
return '不能选择过去的时间';
}
return null;
},
);
}
FormBuilder buildForm() {
return FormBuilder(
key: widget.formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
buildTitleField(),
SizedBox(height: 12),
buildContentField(),
SizedBox(height: 12),
buildDateField(),
],
),
);
}
return Padding(
padding: const EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [buildTitle(), SizedBox(height: 20), buildForm()],
),
);
}
}