From fa36037aacbb28cc6707ee3a1bb1d50a92be5cb3 Mon Sep 17 00:00:00 2001 From: aitorarana Date: Mon, 16 Mar 2026 17:45:00 +0100 Subject: [PATCH] personal data dial code --- .../presentation/personal_data_screen.dart | 33 +++++++++++--- .../state/personal_data_view_model.dart | 18 ++++++-- .../state/personal_data_view_state.dart | 1 + .../personal_data_view_state.freezed.dart | 43 ++++++++++--------- modules/legacy/modules/account/pubspec.lock | 26 +++++------ modules/legacy/modules/account/pubspec.yaml | 1 + 6 files changed, 80 insertions(+), 42 deletions(-) diff --git a/modules/legacy/modules/account/lib/src/features/personal_data/presentation/personal_data_screen.dart b/modules/legacy/modules/account/lib/src/features/personal_data/presentation/personal_data_screen.dart index c426f0a5..34b6a185 100644 --- a/modules/legacy/modules/account/lib/src/features/personal_data/presentation/personal_data_screen.dart +++ b/modules/legacy/modules/account/lib/src/features/personal_data/presentation/personal_data_screen.dart @@ -77,7 +77,7 @@ class PersonalDataScreen extends ConsumerWidget { child: Column( children: [ Text(context.translate(I18n.personalDataMessage)), - const SizedBox(height: 14), + const SizedBox(height: 4), const _SaveButton(), ], ), @@ -169,12 +169,33 @@ class _PhoneField extends ConsumerWidget { final hint = ref.watch( personalDataViewModelProvider.select((s) => s.user?.phone ?? ''), ); + final dialCode = ref.read( + personalDataViewModelProvider.select((s)=>s.dialCode) + ); - return CustomTextField( - controller: vm.phoneController, - hint: hint, - label: context.translate(I18n.phoneLabel), - keyboardType: TextInputType.phone, + return Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + CountryPrefixPicker( + headerText: context.translate(I18n.selectYourCountry), + initialSelection: dialCode, + onChanged: (country) { + vm.updateDialCode( + country.dialCode ?? dialCode, + ); + }, + width: 80, + ), + SizedBox(width: 8), + Expanded( + child: CustomTextField( + controller: vm.phoneController, + hint: hint, + label: context.translate(I18n.phoneLabel), + keyboardType: TextInputType.phone, + ) + ), + ], ); } } diff --git a/modules/legacy/modules/account/lib/src/features/personal_data/presentation/state/personal_data_view_model.dart b/modules/legacy/modules/account/lib/src/features/personal_data/presentation/state/personal_data_view_model.dart index e5587898..ce378172 100644 --- a/modules/legacy/modules/account/lib/src/features/personal_data/presentation/state/personal_data_view_model.dart +++ b/modules/legacy/modules/account/lib/src/features/personal_data/presentation/state/personal_data_view_model.dart @@ -39,12 +39,26 @@ class PersonalDataViewModel extends Notifier { state = state.copyWith(user: user, isLoading: false); } + void updateDialCode(String value) { + if (value == state.dialCode) return; + + state = state.copyWith( + dialCode: value, + errorMessage: '', + ); + } + bool get _hasChanges => firstNameController.text.trim().isNotEmpty || lastNameController.text.trim().isNotEmpty || phoneController.text.trim().isNotEmpty; UpdateUserRequestEntity _toRequest() { + final dialCode = state.dialCode; + final fullPhone = phoneController.text.trim().isNotEmpty + ? dialCode+phoneController.text.trim() + : null; + return UpdateUserRequestEntity( firstName: firstNameController.text.trim().isNotEmpty ? firstNameController.text.trim() @@ -52,9 +66,7 @@ class PersonalDataViewModel extends Notifier { lastName: lastNameController.text.trim().isNotEmpty ? lastNameController.text.trim() : null, - phone: phoneController.text.trim().isNotEmpty - ? phoneController.text.trim() - : null, + phone: fullPhone, ); } diff --git a/modules/legacy/modules/account/lib/src/features/personal_data/presentation/state/personal_data_view_state.dart b/modules/legacy/modules/account/lib/src/features/personal_data/presentation/state/personal_data_view_state.dart index 1b05c3a6..805e2e98 100644 --- a/modules/legacy/modules/account/lib/src/features/personal_data/presentation/state/personal_data_view_state.dart +++ b/modules/legacy/modules/account/lib/src/features/personal_data/presentation/state/personal_data_view_state.dart @@ -8,6 +8,7 @@ abstract class PersonalDataViewState with _$PersonalDataViewState { const factory PersonalDataViewState({ @Default(true) bool isLoading, @Default(false) bool isComplete, + @Default('+34') String dialCode, UserEntity? user, @Default('') String errorMessage, }) = _PersonalDataViewState; diff --git a/modules/legacy/modules/account/lib/src/features/personal_data/presentation/state/personal_data_view_state.freezed.dart b/modules/legacy/modules/account/lib/src/features/personal_data/presentation/state/personal_data_view_state.freezed.dart index e932c958..f26f58ab 100644 --- a/modules/legacy/modules/account/lib/src/features/personal_data/presentation/state/personal_data_view_state.freezed.dart +++ b/modules/legacy/modules/account/lib/src/features/personal_data/presentation/state/personal_data_view_state.freezed.dart @@ -14,7 +14,7 @@ T _$identity(T value) => value; /// @nodoc mixin _$PersonalDataViewState { - bool get isLoading; bool get isComplete; UserEntity? get user; String get errorMessage; + bool get isLoading; bool get isComplete; String get dialCode; UserEntity? get user; String get errorMessage; /// Create a copy of PersonalDataViewState /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @@ -25,16 +25,16 @@ $PersonalDataViewStateCopyWith get copyWith => _$Personal @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is PersonalDataViewState&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isComplete, isComplete) || other.isComplete == isComplete)&&(identical(other.user, user) || other.user == user)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is PersonalDataViewState&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isComplete, isComplete) || other.isComplete == isComplete)&&(identical(other.dialCode, dialCode) || other.dialCode == dialCode)&&(identical(other.user, user) || other.user == user)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)); } @override -int get hashCode => Object.hash(runtimeType,isLoading,isComplete,user,errorMessage); +int get hashCode => Object.hash(runtimeType,isLoading,isComplete,dialCode,user,errorMessage); @override String toString() { - return 'PersonalDataViewState(isLoading: $isLoading, isComplete: $isComplete, user: $user, errorMessage: $errorMessage)'; + return 'PersonalDataViewState(isLoading: $isLoading, isComplete: $isComplete, dialCode: $dialCode, user: $user, errorMessage: $errorMessage)'; } @@ -45,7 +45,7 @@ abstract mixin class $PersonalDataViewStateCopyWith<$Res> { factory $PersonalDataViewStateCopyWith(PersonalDataViewState value, $Res Function(PersonalDataViewState) _then) = _$PersonalDataViewStateCopyWithImpl; @useResult $Res call({ - bool isLoading, bool isComplete, UserEntity? user, String errorMessage + bool isLoading, bool isComplete, String dialCode, UserEntity? user, String errorMessage }); @@ -62,11 +62,12 @@ class _$PersonalDataViewStateCopyWithImpl<$Res> /// Create a copy of PersonalDataViewState /// with the given fields replaced by the non-null parameter values. -@pragma('vm:prefer-inline') @override $Res call({Object? isLoading = null,Object? isComplete = null,Object? user = freezed,Object? errorMessage = null,}) { +@pragma('vm:prefer-inline') @override $Res call({Object? isLoading = null,Object? isComplete = null,Object? dialCode = null,Object? user = freezed,Object? errorMessage = null,}) { return _then(_self.copyWith( isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable as bool,isComplete: null == isComplete ? _self.isComplete : isComplete // ignore: cast_nullable_to_non_nullable -as bool,user: freezed == user ? _self.user : user // ignore: cast_nullable_to_non_nullable +as bool,dialCode: null == dialCode ? _self.dialCode : dialCode // ignore: cast_nullable_to_non_nullable +as String,user: freezed == user ? _self.user : user // ignore: cast_nullable_to_non_nullable as UserEntity?,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable as String, )); @@ -165,10 +166,10 @@ return $default(_that);case _: /// } /// ``` -@optionalTypeArgs TResult maybeWhen(TResult Function( bool isLoading, bool isComplete, UserEntity? user, String errorMessage)? $default,{required TResult orElse(),}) {final _that = this; +@optionalTypeArgs TResult maybeWhen(TResult Function( bool isLoading, bool isComplete, String dialCode, UserEntity? user, String errorMessage)? $default,{required TResult orElse(),}) {final _that = this; switch (_that) { case _PersonalDataViewState() when $default != null: -return $default(_that.isLoading,_that.isComplete,_that.user,_that.errorMessage);case _: +return $default(_that.isLoading,_that.isComplete,_that.dialCode,_that.user,_that.errorMessage);case _: return orElse(); } @@ -186,10 +187,10 @@ return $default(_that.isLoading,_that.isComplete,_that.user,_that.errorMessage); /// } /// ``` -@optionalTypeArgs TResult when(TResult Function( bool isLoading, bool isComplete, UserEntity? user, String errorMessage) $default,) {final _that = this; +@optionalTypeArgs TResult when(TResult Function( bool isLoading, bool isComplete, String dialCode, UserEntity? user, String errorMessage) $default,) {final _that = this; switch (_that) { case _PersonalDataViewState(): -return $default(_that.isLoading,_that.isComplete,_that.user,_that.errorMessage);case _: +return $default(_that.isLoading,_that.isComplete,_that.dialCode,_that.user,_that.errorMessage);case _: throw StateError('Unexpected subclass'); } @@ -206,10 +207,10 @@ return $default(_that.isLoading,_that.isComplete,_that.user,_that.errorMessage); /// } /// ``` -@optionalTypeArgs TResult? whenOrNull(TResult? Function( bool isLoading, bool isComplete, UserEntity? user, String errorMessage)? $default,) {final _that = this; +@optionalTypeArgs TResult? whenOrNull(TResult? Function( bool isLoading, bool isComplete, String dialCode, UserEntity? user, String errorMessage)? $default,) {final _that = this; switch (_that) { case _PersonalDataViewState() when $default != null: -return $default(_that.isLoading,_that.isComplete,_that.user,_that.errorMessage);case _: +return $default(_that.isLoading,_that.isComplete,_that.dialCode,_that.user,_that.errorMessage);case _: return null; } @@ -221,11 +222,12 @@ return $default(_that.isLoading,_that.isComplete,_that.user,_that.errorMessage); class _PersonalDataViewState implements PersonalDataViewState { - const _PersonalDataViewState({this.isLoading = true, this.isComplete = false, this.user, this.errorMessage = ''}); + const _PersonalDataViewState({this.isLoading = true, this.isComplete = false, this.dialCode = '+34', this.user, this.errorMessage = ''}); @override@JsonKey() final bool isLoading; @override@JsonKey() final bool isComplete; +@override@JsonKey() final String dialCode; @override final UserEntity? user; @override@JsonKey() final String errorMessage; @@ -239,16 +241,16 @@ _$PersonalDataViewStateCopyWith<_PersonalDataViewState> get copyWith => __$Perso @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is _PersonalDataViewState&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isComplete, isComplete) || other.isComplete == isComplete)&&(identical(other.user, user) || other.user == user)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is _PersonalDataViewState&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isComplete, isComplete) || other.isComplete == isComplete)&&(identical(other.dialCode, dialCode) || other.dialCode == dialCode)&&(identical(other.user, user) || other.user == user)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)); } @override -int get hashCode => Object.hash(runtimeType,isLoading,isComplete,user,errorMessage); +int get hashCode => Object.hash(runtimeType,isLoading,isComplete,dialCode,user,errorMessage); @override String toString() { - return 'PersonalDataViewState(isLoading: $isLoading, isComplete: $isComplete, user: $user, errorMessage: $errorMessage)'; + return 'PersonalDataViewState(isLoading: $isLoading, isComplete: $isComplete, dialCode: $dialCode, user: $user, errorMessage: $errorMessage)'; } @@ -259,7 +261,7 @@ abstract mixin class _$PersonalDataViewStateCopyWith<$Res> implements $PersonalD factory _$PersonalDataViewStateCopyWith(_PersonalDataViewState value, $Res Function(_PersonalDataViewState) _then) = __$PersonalDataViewStateCopyWithImpl; @override @useResult $Res call({ - bool isLoading, bool isComplete, UserEntity? user, String errorMessage + bool isLoading, bool isComplete, String dialCode, UserEntity? user, String errorMessage }); @@ -276,11 +278,12 @@ class __$PersonalDataViewStateCopyWithImpl<$Res> /// Create a copy of PersonalDataViewState /// with the given fields replaced by the non-null parameter values. -@override @pragma('vm:prefer-inline') $Res call({Object? isLoading = null,Object? isComplete = null,Object? user = freezed,Object? errorMessage = null,}) { +@override @pragma('vm:prefer-inline') $Res call({Object? isLoading = null,Object? isComplete = null,Object? dialCode = null,Object? user = freezed,Object? errorMessage = null,}) { return _then(_PersonalDataViewState( isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable as bool,isComplete: null == isComplete ? _self.isComplete : isComplete // ignore: cast_nullable_to_non_nullable -as bool,user: freezed == user ? _self.user : user // ignore: cast_nullable_to_non_nullable +as bool,dialCode: null == dialCode ? _self.dialCode : dialCode // ignore: cast_nullable_to_non_nullable +as String,user: freezed == user ? _self.user : user // ignore: cast_nullable_to_non_nullable as UserEntity?,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable as String, )); diff --git a/modules/legacy/modules/account/pubspec.lock b/modules/legacy/modules/account/pubspec.lock index 1d2b4b2b..b3f22f00 100644 --- a/modules/legacy/modules/account/pubspec.lock +++ b/modules/legacy/modules/account/pubspec.lock @@ -96,7 +96,7 @@ packages: source: hosted version: "3.0.3" build_runner: - dependency: transitive + dependency: "direct main" description: name: build_runner sha256: b24597fceb695969d47025c958f3837f9f0122e237c6a22cb082a5ac66c3ca30 @@ -338,10 +338,10 @@ packages: dependency: transitive description: name: fl_chart - sha256: "7ca9a40f4eb85949190e54087be8b4d6ac09dc4c54238d782a34cf1f7c011de9" + sha256: b938f77d042cbcd822936a7a359a7235bad8bd72070de1f827efc2cc297ac888 url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.2.0" flutter: dependency: "direct main" description: flutter @@ -367,18 +367,18 @@ packages: dependency: "direct main" description: name: flutter_riverpod - sha256: e2026c72738a925a60db30258ff1f29974e40716749f3c9850aabf34ffc1a14c + sha256: "4e166be88e1dbbaa34a280bdb744aeae73b7ef25fdf8db7a3bb776760a3648e2" url: "https://pub.dev" source: hosted - version: "3.2.1" + version: "3.3.1" flutter_svg: dependency: "direct main" description: name: flutter_svg - sha256: "87fbd7c534435b6c5d9d98b01e1fd527812b82e68ddd8bd35fc45ed0fa8f0a95" + sha256: "1ded017b39c8e15c8948ea855070a5ff8ff8b3d5e83f3446e02d6bb12add7ad9" url: "https://pub.dev" source: hosted - version: "2.2.3" + version: "2.2.4" flutter_test: dependency: "direct dev" description: flutter @@ -620,10 +620,10 @@ packages: dependency: transitive description: name: logger - sha256: a7967e31b703831a893bbc3c3dd11db08126fe5f369b5c648a36f821979f5be3 + sha256: "25aee487596a6257655a1e091ec2ae66bc30e7af663592cc3a27e6591e05035c" url: "https://pub.dev" source: hosted - version: "2.6.2" + version: "2.7.0" logging: dependency: transitive description: @@ -1257,10 +1257,10 @@ packages: dependency: transitive description: name: vector_graphics - sha256: a4f059dc26fc8295b5921376600a194c4ec7d55e72f2fe4c7d2831e103d461e6 + sha256: "7076216a10d5c390315fbe536a30f1254c341e7543e6c4c8a815e591307772b1" url: "https://pub.dev" source: hosted - version: "1.1.19" + version: "1.1.20" vector_graphics_codec: dependency: transitive description: @@ -1361,10 +1361,10 @@ packages: dependency: transitive description: name: webview_flutter_wkwebview - sha256: fc0af89d403e1c053f03d023d97550412fa79f35332e2939514c82e6fe633198 + sha256: "2df8fd9ada04d699b9db8e79aa783a16e5d89b69e5b74009b87e16b59912cf98" url: "https://pub.dev" source: hosted - version: "3.23.8" + version: "3.24.0" wkt_parser: dependency: transitive description: diff --git a/modules/legacy/modules/account/pubspec.yaml b/modules/legacy/modules/account/pubspec.yaml index 4d1ffcc4..c9dd115d 100644 --- a/modules/legacy/modules/account/pubspec.yaml +++ b/modules/legacy/modules/account/pubspec.yaml @@ -56,6 +56,7 @@ dependencies: uuid: ^4.5.2 qr_flutter: ^4.1.0 url_launcher: ^6.3.2 + build_runner: ^2.7.1 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons.