profile page

This commit is contained in:
mohammad
2024-07-25 16:19:02 +03:00
parent 21bed5c14d
commit 76b867d4b9
3 changed files with 57 additions and 22 deletions

View File

@ -45,6 +45,7 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
Future<void> saveName(SaveNameEvent event, Emitter<ProfileState> emit) async { Future<void> saveName(SaveNameEvent event, Emitter<ProfileState> emit) async {
if (_validateInputs()) return; if (_validateInputs()) return;
try { try {
add(const ChangeNameEvent(value: false)); add(const ChangeNameEvent(value: false));
isSaving = true; isSaving = true;
emit(LoadingInitialState()); emit(LoadingInitialState());
@ -55,7 +56,7 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
var response = await ProfileApi.saveName(firstName: firstName, lastName: lastName); var response = await ProfileApi.saveName(firstName: firstName, lastName: lastName);
add(InitialProfileEvent()); add(InitialProfileEvent());
await HomeCubit.getInstance().fetchUserInfo(); await HomeCubit.getInstance().fetchUserInfo();
Navigator.of(event.context).pop(true); // Navigator.of(event.context).pop(true);
CustomSnackBar.displaySnackBar('Save Successfully'); CustomSnackBar.displaySnackBar('Save Successfully');
emit(SaveState()); emit(SaveState());
} catch (_) { } catch (_) {
@ -229,14 +230,45 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
bool _validateInputs() { bool _validateInputs() {
if (nameController.text.length < 2) { final nameError = fullNameValidator(nameController.text);
CustomSnackBar.displaySnackBar('Name Must More than 2 '); if (nameError != null) {
CustomSnackBar.displaySnackBar(nameError);
return true; return true;
} }
return false; 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<bool> _requestPermission() async { Future<bool> _requestPermission() async {
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
if (Platform.isAndroid ) { if (Platform.isAndroid ) {

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.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_bloc.dart';
import 'package:syncrow_app/features/menu/bloc/profile_bloc/profile_event.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'; import 'package:syncrow_app/features/menu/bloc/profile_bloc/profile_state.dart';
@ -73,23 +74,26 @@ class ProfileView extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
IntrinsicWidth( IntrinsicWidth(
child: TextFormField( child: ConstrainedBox(
maxLength: 30, constraints: const BoxConstraints(maxWidth: 200),
style: const TextStyle( child: TextFormField(
color: Colors.black, maxLength: 30,
), style: const TextStyle(
textAlign: TextAlign.center, color: Colors.black,
focusNode: profileBloc.focusNode, ),
controller: profileBloc.nameController, textAlign: TextAlign.center,
enabled: profileBloc.editName, focusNode: profileBloc.focusNode,
onEditingComplete: () { controller: profileBloc.nameController,
profileBloc.add(SaveNameEvent(context: context)); enabled: profileBloc.editName,
}, onEditingComplete: () {
decoration: const InputDecoration( profileBloc.add(SaveNameEvent(context: context));
hintText: "Your Name", },
border: InputBorder.none, decoration: const InputDecoration(
fillColor: Colors.white10, hintText: "Your Name",
counterText: '', // Hides the character count border: InputBorder.none,
fillColor: Colors.white10,
counterText: '',
),
), ),
), ),
), ),

View File

@ -43,6 +43,7 @@ class ProfileApi {
rethrow; rethrow;
} }
} }
static Future saveTimeZone({String? regionUuid,}) async { static Future saveTimeZone({String? regionUuid,}) async {
try { try {
final response = await _httpService.put( final response = await _httpService.put(
@ -99,7 +100,6 @@ class ProfileApi {
return response as List<RegionModel>; return response as List<RegionModel>;
} }
static Future<List<TimeZone>> fetchTimeZone() async { static Future<List<TimeZone>> fetchTimeZone() async {
final response = await _httpService.get( final response = await _httpService.get(
path: ApiEndpoints.getTimezone, path: ApiEndpoints.getTimezone,
@ -111,5 +111,4 @@ class ProfileApi {
return response as List<TimeZone>; return response as List<TimeZone>;
} }
} }