import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../core/app_colors.dart'; import '../../core/app_design_tokens.dart'; import '../../core/app_theme.dart'; import '../../core/navigation_provider.dart'; import '../../providers/auth_provider.dart'; import '../../providers/data_providers.dart'; import '../../widgets/app_error_state.dart'; import '../../widgets/app_toast.dart'; import '../../widgets/common_widgets.dart'; class ProfileEditPage extends ConsumerStatefulWidget { const ProfileEditPage({super.key}); @override ConsumerState createState() => _ProfileEditPageState(); } class _ProfileEditPageState extends ConsumerState { final _nameController = TextEditingController(); bool _loading = true; bool _saving = false; String? _error; String _gender = ''; DateTime? _birthDate; @override void initState() { super.initState(); _load(); } @override void dispose() { _nameController.dispose(); super.dispose(); } Future _load() async { try { final profile = await ref.read(userServiceProvider).getProfile(); if (!mounted) return; setState(() { _nameController.text = profile?['name']?.toString() ?? ''; _gender = profile?['gender']?.toString() ?? ''; _birthDate = DateTime.tryParse(profile?['birthDate']?.toString() ?? ''); _loading = false; _error = null; }); } catch (_) { if (!mounted) return; setState(() { _loading = false; _error = '个人资料加载失败'; }); } } Future _save() async { final name = _nameController.text.trim(); if (name.isEmpty) { AppToast.show(context, '请填写姓名', type: AppToastType.warning); return; } setState(() => _saving = true); try { await ref .read(userServiceProvider) .updateProfile( name: name, gender: _gender.isEmpty ? null : _gender, birthDate: _birthDate == null ? null : _formatDate(_birthDate!), ); await ref.read(authProvider.notifier).refreshProfile(); if (!mounted) return; AppToast.show(context, '个人资料已保存', type: AppToastType.success); popRoute(ref); } catch (_) { if (mounted) { AppToast.show(context, '保存失败,请稍后重试', type: AppToastType.error); } } finally { if (mounted) setState(() => _saving = false); } } Future _pickBirthDate() async { final now = DateTime.now(); final selected = await showDatePicker( context: context, initialDate: _birthDate ?? DateTime(now.year - 30), firstDate: DateTime(1900), lastDate: now, ); if (selected != null && mounted) setState(() => _birthDate = selected); } @override Widget build(BuildContext context) { return GradientScaffold( appBar: AppBar( leading: IconButton( icon: const Icon(Icons.arrow_back_ios_new_rounded, size: 19), onPressed: _saving ? null : () => popRoute(ref), ), title: const Text('基本资料'), centerTitle: true, ), bottomNavigationBar: _loading || _error != null ? null : SafeArea( minimum: const EdgeInsets.fromLTRB(18, 8, 18, 14), child: AppGradientOutlineButton( label: _saving ? '保存中...' : '保存', loading: _saving, onPressed: _saving ? null : _save, ), ), body: _loading ? const Center(child: CircularProgressIndicator(strokeWidth: 2)) : _error != null ? AppErrorState(title: _error!, subtitle: '请检查网络后重试', onRetry: _load) : ListView( keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, padding: const EdgeInsets.fromLTRB(18, 12, 18, 28), children: [ _FormPanel( children: [ const _FieldLabel('姓名'), const SizedBox(height: 8), TextField( controller: _nameController, maxLength: 30, textInputAction: TextInputAction.done, decoration: const InputDecoration( hintText: '请输入姓名', counterText: '', ), ), const SizedBox(height: 18), const _FieldLabel('性别'), const SizedBox(height: 8), SegmentedButton( segments: const [ ButtonSegment(value: 'Male', label: Text('男')), ButtonSegment(value: 'Female', label: Text('女')), ButtonSegment(value: 'Other', label: Text('其他')), ], selected: _gender.isEmpty ? const {} : {_gender}, emptySelectionAllowed: true, showSelectedIcon: false, onSelectionChanged: (value) { setState( () => _gender = value.isEmpty ? '' : value.first, ); }, ), const SizedBox(height: 18), const _FieldLabel('出生日期'), const SizedBox(height: 8), InkWell( onTap: _pickBirthDate, borderRadius: AppRadius.mdBorder, child: Container( height: 52, padding: const EdgeInsets.symmetric(horizontal: 14), decoration: BoxDecoration( border: Border.all(color: AppColors.border), borderRadius: AppRadius.mdBorder, ), child: Row( children: [ Expanded( child: Text( _birthDate == null ? '请选择出生日期' : _formatDate(_birthDate!), style: TextStyle( fontSize: 15, color: _birthDate == null ? AppColors.textHint : AppColors.textPrimary, ), ), ), const Icon( Icons.calendar_today_outlined, size: 19, color: AppColors.primary, ), ], ), ), ), ], ), const SizedBox(height: 16), _ReadOnlyPhone(phone: ref.read(authProvider).user?.phone ?? ''), ], ), ); } String _formatDate(DateTime value) => '${value.year.toString().padLeft(4, '0')}-${value.month.toString().padLeft(2, '0')}-${value.day.toString().padLeft(2, '0')}'; } class _FormPanel extends StatelessWidget { final List children; const _FormPanel({required this.children}); @override Widget build(BuildContext context) => Container( padding: const EdgeInsets.all(18), decoration: BoxDecoration( color: Colors.white, borderRadius: AppRadius.lgBorder, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: children, ), ); } class _FieldLabel extends StatelessWidget { final String text; const _FieldLabel(this.text); @override Widget build(BuildContext context) => Text( text, style: const TextStyle( fontSize: 15, fontWeight: FontWeight.w600, color: AppColors.textPrimary, ), ); } class _ReadOnlyPhone extends StatelessWidget { final String phone; const _ReadOnlyPhone({required this.phone}); @override Widget build(BuildContext context) => Container( padding: const EdgeInsets.all(18), decoration: BoxDecoration( color: Colors.white, borderRadius: AppRadius.lgBorder, ), child: Row( children: [ const Icon(Icons.phone_iphone_rounded, color: AppColors.textSecondary), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('手机号', style: AppTextStyles.listTitle), const SizedBox(height: 4), Text( phone.isEmpty ? '未绑定' : phone, style: AppTextStyles.listSubtitle, ), ], ), ), const Text( '手机号不可修改', style: TextStyle(fontSize: 12, color: AppColors.textHint), ), ], ), ); }