// 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/models/challenge_model.dart'; import 'package:japp_flutter/features/challenge/view_models/challenge_add_vm.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: [ _TitleField(initialValue: challenge.title), const SizedBox(height: 24), _DateRangeField( startDate: challenge.startDate, endDate: challenge.endDate, ), const SizedBox(height: 24), _DifficultySelector(currentDifficulty: challenge.difficulty), const SizedBox(height: 24), _DescriptionField(initialValue: challenge.description), ], ), ); } } class _TitleField extends ConsumerWidget { final String initialValue; const _TitleField({required this.initialValue}); @override Widget build(BuildContext context, WidgetRef ref) { return TextFormField( initialValue: initialValue, decoration: const InputDecoration( labelText: '挑战标题*', border: OutlineInputBorder(), ), onChanged: (value) => ref.read(addChallengeProvider.notifier).updateTitle(value), ); } } class _DescriptionField extends ConsumerWidget { final String initialValue; const _DescriptionField({required this.initialValue}); @override Widget build(BuildContext context, WidgetRef ref) { return TextFormField( initialValue: initialValue, decoration: const InputDecoration( labelText: '挑战描述', border: OutlineInputBorder(), alignLabelWithHint: true, ), maxLines: 5, onChanged: (value) => ref.read(addChallengeProvider.notifier).updateDescription(value), ); } } class _DifficultySelector extends ConsumerWidget { final String currentDifficulty; static const difficulties = ['简单', '中等', '困难']; const _DifficultySelector({required this.currentDifficulty}); @override Widget build(BuildContext context, WidgetRef ref) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('难度级别*', style: TextStyle(fontSize: 16)), const SizedBox(height: 8), Wrap( spacing: 8, children: difficulties.map((level) { return ChoiceChip( label: Text(level), selected: currentDifficulty == level, onSelected: (selected) { if (selected) { ref.read(addChallengeProvider.notifier).updateDifficulty(level); } }, ); }).toList(), ), ], ); } } 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), ), ], ); } }