diff --git a/lib/pages/space_management_v2/modules/space_details/presentation/widgets/subspace_name_display_widget.dart b/lib/pages/space_management_v2/modules/space_details/presentation/widgets/subspace_name_display_widget.dart index 9169efda..bbc9549d 100644 --- a/lib/pages/space_management_v2/modules/space_details/presentation/widgets/subspace_name_display_widget.dart +++ b/lib/pages/space_management_v2/modules/space_details/presentation/widgets/subspace_name_display_widget.dart @@ -18,7 +18,9 @@ class SubspaceNameDisplayWidget extends StatefulWidget { class _SubspaceNameDisplayWidgetState extends State { late final TextEditingController _controller; late final FocusNode _focusNode; - bool isEditing = false; + bool _isEditing = false; + bool _hasDuplicateName = false; + @override void initState() { _controller = TextEditingController(text: widget.subSpace.name); @@ -33,6 +35,41 @@ class _SubspaceNameDisplayWidgetState extends State { super.dispose(); } + bool _checkForDuplicateName(String name) { + final bloc = context.read(); + return bloc.state.subspaces + .where((s) => s.uuid != widget.subSpace.uuid) + .any((s) => s.name.toLowerCase() == name.toLowerCase()); + } + + void _handleNameChange(String value) { + setState(() { + _hasDuplicateName = _checkForDuplicateName(value); + }); + } + + void _tryToFinishEditing() { + if (!_hasDuplicateName) { + _onFinishEditing(); + } + } + + void _tryToSubmit(String value) { + if (_hasDuplicateName) return; + + final bloc = context.read(); + bloc.add( + UpdateSpaceDetailsSubspaces( + bloc.state.subspaces + .map( + (e) => e.uuid == widget.subSpace.uuid ? e.copyWith(name: value) : e, + ) + .toList(), + ), + ); + _onFinishEditing(); + } + @override Widget build(BuildContext context) { final textStyle = context.textTheme.bodySmall?.copyWith( @@ -40,7 +77,7 @@ class _SubspaceNameDisplayWidgetState extends State { ); return InkWell( onTap: () { - setState(() => isEditing = true); + setState(() => _isEditing = true); _focusNode.requestFocus(); }, child: Chip( @@ -49,36 +86,48 @@ class _SubspaceNameDisplayWidgetState extends State { borderRadius: BorderRadius.circular(10), ), label: Visibility( - visible: isEditing, + visible: _isEditing, replacement: Text( widget.subSpace.name, style: textStyle, ), - child: SizedBox( - width: context.screenWidth * 0.065, - height: context.screenHeight * 0.025, - child: TextField( - focusNode: _focusNode, - controller: _controller, - style: textStyle, - decoration: const InputDecoration.collapsed(hintText: ''), - onTapOutside: (_) => _onFinishEditing(), - onSubmitted: (value) { - final bloc = context.read(); - bloc.add( - UpdateSpaceDetailsSubspaces( - bloc.state.subspaces - .map( - (e) => e.uuid == widget.subSpace.uuid - ? e.copyWith(name: value) - : e, - ) - .toList(), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: context.screenWidth * 0.065, + height: context.screenHeight * 0.025, + child: TextField( + focusNode: _focusNode, + controller: _controller, + style: textStyle?.copyWith( + color: _hasDuplicateName ? Colors.red : null, ), - ); - _onFinishEditing(); - }, - ), + decoration: const InputDecoration.collapsed( + hintText: '', + ), + onChanged: _handleNameChange, + onTapOutside: (_) => _tryToFinishEditing(), + onSubmitted: _tryToSubmit, + ), + ), + if (_hasDuplicateName) + AnimatedSwitcher( + duration: const Duration(milliseconds: 250), + child: Visibility( + key: ValueKey(_hasDuplicateName), + visible: _hasDuplicateName, + child: Text( + 'Name already exists', + style: textStyle?.copyWith( + color: Colors.red, + fontSize: 8, + ), + ), + ), + ), + ], ), ), ), @@ -86,7 +135,10 @@ class _SubspaceNameDisplayWidgetState extends State { } void _onFinishEditing() { - setState(() => isEditing = false); + setState(() { + _isEditing = false; + _hasDuplicateName = false; + }); _focusNode.unfocus(); } }