diff --git a/lib/features/menu/bloc/profile_bloc/profile_bloc.dart b/lib/features/menu/bloc/profile_bloc/profile_bloc.dart index 7fa0889..91b452b 100644 --- a/lib/features/menu/bloc/profile_bloc/profile_bloc.dart +++ b/lib/features/menu/bloc/profile_bloc/profile_bloc.dart @@ -45,6 +45,7 @@ class ProfileBloc extends Bloc { Future saveName(SaveNameEvent event, Emitter emit) async { if (_validateInputs()) return; try { + add(const ChangeNameEvent(value: false)); isSaving = true; emit(LoadingInitialState()); @@ -55,7 +56,7 @@ class ProfileBloc extends Bloc { var response = await ProfileApi.saveName(firstName: firstName, lastName: lastName); add(InitialProfileEvent()); await HomeCubit.getInstance().fetchUserInfo(); - Navigator.of(event.context).pop(true); + // Navigator.of(event.context).pop(true); CustomSnackBar.displaySnackBar('Save Successfully'); emit(SaveState()); } catch (_) { @@ -229,14 +230,45 @@ class ProfileBloc extends Bloc { + bool _validateInputs() { - if (nameController.text.length < 2) { - CustomSnackBar.displaySnackBar('Name Must More than 2 '); + final nameError = fullNameValidator(nameController.text); + if (nameError != null) { + CustomSnackBar.displaySnackBar(nameError); return true; } return false; } + + String? fullNameValidator(String? value) { + if (value == null) return 'Full name is required'; + + final withoutExtraSpaces = value.replaceAll(RegExp(r"\s+"), ' ').trim(); + + if (withoutExtraSpaces.length < 2 || withoutExtraSpaces.length > 30) { + return 'Full name must be between 2 and 30 characters long'; + } + + // Test if it contains anything but alphanumeric spaces and single quote + + if (RegExp(r"/[^ a-zA-Z0-9-\']/").hasMatch(withoutExtraSpaces)) { + return 'Only alphanumeric characters, space, dash and single quote are allowed'; + } + + final parts = withoutExtraSpaces.split(' '); + + if (parts.length < 2) return 'Full name must contain first and last names'; + + if (parts.length > 3) return 'Full name can at most contain 3 parts'; + + if (parts.any((part) => part.length < 2 || part.length > 30)) { + return 'Full name parts must be between 2 and 30 characters long'; + } + return null; + } + + Future _requestPermission() async { DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); if (Platform.isAndroid ) { diff --git a/lib/features/menu/view/widgets/profile/profile_view.dart b/lib/features/menu/view/widgets/profile/profile_view.dart index 50d6699..22082b5 100644 --- a/lib/features/menu/view/widgets/profile/profile_view.dart +++ b/lib/features/menu/view/widgets/profile/profile_view.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; +import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart'; import 'package:syncrow_app/features/menu/bloc/profile_bloc/profile_bloc.dart'; import 'package:syncrow_app/features/menu/bloc/profile_bloc/profile_event.dart'; import 'package:syncrow_app/features/menu/bloc/profile_bloc/profile_state.dart'; @@ -73,23 +74,26 @@ class ProfileView extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ IntrinsicWidth( - child: TextFormField( - maxLength: 30, - style: const TextStyle( - color: Colors.black, - ), - textAlign: TextAlign.center, - focusNode: profileBloc.focusNode, - controller: profileBloc.nameController, - enabled: profileBloc.editName, - onEditingComplete: () { - profileBloc.add(SaveNameEvent(context: context)); - }, - decoration: const InputDecoration( - hintText: "Your Name", - border: InputBorder.none, - fillColor: Colors.white10, - counterText: '', // Hides the character count + child: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 200), + child: TextFormField( + maxLength: 30, + style: const TextStyle( + color: Colors.black, + ), + textAlign: TextAlign.center, + focusNode: profileBloc.focusNode, + controller: profileBloc.nameController, + enabled: profileBloc.editName, + onEditingComplete: () { + profileBloc.add(SaveNameEvent(context: context)); + }, + decoration: const InputDecoration( + hintText: "Your Name", + border: InputBorder.none, + fillColor: Colors.white10, + counterText: '', + ), ), ), ), diff --git a/lib/services/api/profile_api.dart b/lib/services/api/profile_api.dart index 5666923..3b617ce 100644 --- a/lib/services/api/profile_api.dart +++ b/lib/services/api/profile_api.dart @@ -43,6 +43,7 @@ class ProfileApi { rethrow; } } + static Future saveTimeZone({String? regionUuid,}) async { try { final response = await _httpService.put( @@ -99,7 +100,6 @@ class ProfileApi { return response as List; } - static Future> fetchTimeZone() async { final response = await _httpService.get( path: ApiEndpoints.getTimezone, @@ -111,5 +111,4 @@ class ProfileApi { return response as List; } - }