// features/challenge/add/add_challenge_screen.dart import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:intl/intl.dart'; import 'package:japp_flutter/core/constants/options.dart'; import 'package:japp_flutter/core/models/challenge_model.dart'; import 'package:japp_flutter/features/challenge/view_models/challenge_add_vm.dart'; import 'package:japp_flutter/features/widgets/app_dropdown.dart'; import 'package:japp_flutter/features/widgets/date_picker.dart'; class AddChallengeScreen extends ConsumerWidget { const AddChallengeScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final challengeState = ref.watch(addChallengeProvider); final theme = Theme.of(context); return Scaffold( appBar: AppBar( title: const Text('创建新挑战'), actions: [ IconButton( icon: const Icon(Icons.check), onPressed: () async { await ref.read(addChallengeProvider.notifier).submitChallenge(); if (context.mounted) Navigator.pop(context); }, tooltip: '提交', ), ], ), body: challengeState.when( loading: () => const Center(child: CircularProgressIndicator()), error: (error, _) => Center(child: Text('错误: $error')), data: (challenge) => _BuildForm(challenge: challenge), ), ); } } class _BuildForm extends ConsumerWidget { final ChallengeModel challenge; const _BuildForm({required this.challenge}); @override Widget build(BuildContext context, WidgetRef ref) { return SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ TextFormField( initialValue: challenge.title, decoration: const InputDecoration( labelText: '目标', hintText: '请输入目标名称', border: OutlineInputBorder(), ), onChanged: (value) => ref.read(addChallengeProvider.notifier).updateTitle(value), ), const SizedBox(height: 16), TextFormField( initialValue: challenge.description, decoration: const InputDecoration( labelText: '简介', hintText: '请输入目标的简介', border: OutlineInputBorder(), alignLabelWithHint: true, ), maxLines: 3, onChanged: (value) => ref .read(addChallengeProvider.notifier) .updateDescription(value), ), const SizedBox(height: 16), AppDropdown( label: '目标类型', value: challenge.actionType, items: challengeActionTypeOpts, onChanged: (value) => ref .read(addChallengeProvider.notifier) .updateActionType(value ?? 0), ), const SizedBox(height: 16), AppDropdown( label: '挑战状态', value: challenge.status, items: challengeStatusOpts, onChanged: (value) => ref .read(addChallengeProvider.notifier) .updateStatus(value ?? 0), ), const SizedBox(height: 16), AppDropdown( label: '挑战难度', value: challenge.difficulty, items: challengeDifficultyOpts, onChanged: (value) => ref .read(addChallengeProvider.notifier) .updateDifficulty(value ?? 0), ), const SizedBox(height: 16), _DateRangeField( startDate: challenge.startDate!, endDate: challenge.endDate!, ), const SizedBox(height: 16), TextFormField( keyboardType: TextInputType.number, initialValue: challenge.sort.toString(), decoration: const InputDecoration( labelText: '排序', border: OutlineInputBorder(), alignLabelWithHint: true, ), onChanged: (value) => ref .read(addChallengeProvider.notifier) .updateSort(int.parse(value)), ), const SizedBox(height: 16), DatePickerField( labelText: '计划完成日期', onDateSelected: (date) => ref .read(addChallengeProvider.notifier) .updatePlanFinishDate(date!), ), const SizedBox(height: 16), DatePickerField( labelText: '完成日期', onDateSelected: (date) => ref .read(addChallengeProvider.notifier) .updateFinishDate(date!), ), const SizedBox(height: 16), TextFormField( initialValue: challenge.remark, decoration: const InputDecoration( labelText: '备注', border: OutlineInputBorder(), alignLabelWithHint: true, ), maxLines: 3, onChanged: (value) => ref.read(addChallengeProvider.notifier).updateRemark(value), ), const SizedBox(height: 16), ], ), ); } } class _DateRangeField extends ConsumerWidget { final DateTime startDate; final DateTime endDate; const _DateRangeField({required this.startDate, required this.endDate}); Future _selectDate( BuildContext context, bool isStartDate, WidgetRef ref, ) async { final initialDate = isStartDate ? startDate : endDate; final picked = await showDatePicker( context: context, initialDate: initialDate, firstDate: DateTime.now(), lastDate: DateTime(2100), ); if (picked != null) { final newStart = isStartDate ? picked : startDate; final newEnd = isStartDate ? endDate : picked; ref.read(addChallengeProvider.notifier).updateDateRange(newStart, newEnd); } } @override Widget build(BuildContext context, WidgetRef ref) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('挑战周期*', style: TextStyle(fontSize: 16)), const SizedBox(height: 8), Row( children: [ Expanded( child: OutlinedButton( onPressed: () => _selectDate(context, true, ref), child: Text(DateFormat('yyyy/MM/dd').format(startDate)), ), ), const Padding( padding: EdgeInsets.symmetric(horizontal: 8), child: Text('至'), ), Expanded( child: OutlinedButton( onPressed: () => _selectDate(context, false, ref), child: Text(DateFormat('yyyy/MM/dd').format(endDate)), ), ), ], ), const SizedBox(height: 4), Text( '总天数: ${endDate.difference(startDate).inDays}天', style: const TextStyle(color: Colors.grey), ), ], ); } }