import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:pweb/models/edit_state.dart'; import 'package:pshared/provider/account.dart'; class AccountName extends StatefulWidget { final String name; final String title; final String hintText; final String errorText; const AccountName({ super.key, required this.name, required this.title, required this.hintText, required this.errorText, }); @override State createState() => _AccountNameState(); } class _AccountNameState extends State { static const double _inputWidth = 200; static const double _spacing = 8; static const double _errorSpacing = 4; static const double _borderWidth = 2; late final TextEditingController _controller; EditState _editState = EditState.view; late String _originalName; String _errorText = ''; @override void initState() { super.initState(); _controller = TextEditingController(text: widget.name); _originalName = widget.name; } @override void dispose() { _controller.dispose(); super.dispose(); } void _startEditing() => setState(() => _editState = EditState.edit); void _cancelEditing() { setState(() { _controller.text = _originalName; _editState = EditState.view; _errorText = ''; }); } Future _saveEditing(AccountProvider provider) async { final newName = _controller.text.trim(); if (newName.isEmpty || newName == _originalName) { _cancelEditing(); return; } setState(() { _editState = EditState.saving; _errorText = ''; }); try { await provider.resetUsername(newName); if (!mounted) return; setState(() { _originalName = newName; _editState = EditState.view; }); } catch (_) { if (!mounted) return; setState(() { _errorText = widget.errorText; _editState = EditState.edit; }); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(widget.errorText)), ); return; } finally { if (!mounted) return; if (_editState == EditState.saving) { setState(() => _editState = EditState.edit); } } } @override Widget build(BuildContext context) { final theme = Theme.of(context); return Consumer( builder: (context, provider, _) { final isEditing = _editState != EditState.view; final currentName = provider.account?.name ?? _originalName; final isBusy = provider.isLoading || _editState == EditState.saving; if (!isEditing && currentName != _originalName) { _originalName = currentName; _controller.text = currentName; } return Column( mainAxisSize: MainAxisSize.min, children: [ Row( mainAxisAlignment: MainAxisAlignment.center, children: [ if (isEditing) SizedBox( width: _inputWidth, child: TextFormField( controller: _controller, style: theme.textTheme.headlineMedium?.copyWith( fontWeight: FontWeight.bold, ), autofocus: true, enabled: !isBusy, decoration: InputDecoration( hintText: widget.hintText, isDense: true, border: UnderlineInputBorder( borderSide: BorderSide( color: theme.colorScheme.primary, width: _borderWidth, ), ), ), ), ) else Text( _originalName, style: theme.textTheme.headlineMedium?.copyWith( fontWeight: FontWeight.bold, ), ), const SizedBox(width: _spacing), if (isEditing) ...[ IconButton( icon: Icon(Icons.check, color: theme.colorScheme.primary), onPressed: isBusy ? null : () => _saveEditing(provider), ), IconButton( icon: Icon(Icons.close, color: theme.colorScheme.error), onPressed: isBusy ? null : _cancelEditing, ), ] else IconButton( icon: Icon(Icons.edit, color: theme.colorScheme.primary), onPressed: isBusy ? null : _startEditing, ), ], ), const SizedBox(height: _errorSpacing), if (_errorText.isNotEmpty) Text( _errorText, style: theme.textTheme.bodySmall?.copyWith( color: theme.colorScheme.error, ), ), ], ); }, ); } }