Compare commits
18 Commits
golden_tes
...
auth-login
| Author | SHA1 | Date | |
|---|---|---|---|
| 8754884544 | |||
| 0e3fd8e6d5 | |||
| 4c46b2f498 | |||
| 0b2f1ff869 | |||
|
|
076951af24 | ||
| f8a3b038b6 | |||
|
|
0f30c7f422 | ||
| bbe77f6a8a | |||
|
|
760e94ffe9 | ||
|
|
ad10ad3b59 | ||
| cbc991b2fd | |||
|
|
6b3776f618 | ||
| 7bfc4039ab | |||
| 16e3c68d1a | |||
| 4869850c43 | |||
| 99f544e24c | |||
|
|
14a925659a | ||
| 91e47f28fb |
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"workspaceRoot": "../.."
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_secure_storage","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage-9.2.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.3/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"flutter_secure_storage","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage-9.2.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_android","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_android-2.2.20/","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"flutter_secure_storage_macos","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage_macos-3.1.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.3/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"flutter_secure_storage_linux","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage_linux-1.2.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_linux","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[],"dev_dependency":false}],"windows":[{"name":"flutter_secure_storage_windows","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage_windows-3.1.2/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_windows","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[],"dev_dependency":false}],"web":[{"name":"flutter_secure_storage_web","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage_web-1.2.1/","dependencies":[],"dev_dependency":false}]},"dependencyGraph":[{"name":"flutter_secure_storage","dependencies":["flutter_secure_storage_linux","flutter_secure_storage_macos","flutter_secure_storage_web","flutter_secure_storage_windows"]},{"name":"flutter_secure_storage_linux","dependencies":[]},{"name":"flutter_secure_storage_macos","dependencies":[]},{"name":"flutter_secure_storage_web","dependencies":[]},{"name":"flutter_secure_storage_windows","dependencies":["path_provider"]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]}],"date_created":"2025-11-10 13:39:20.696891","version":"3.35.7","swift_package_manager_enabled":{"ios":false,"macos":false}}
|
||||
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_secure_storage","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage-9.2.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.3/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"flutter_secure_storage","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage-9.2.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_android","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_android-2.2.20/","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"flutter_secure_storage_macos","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage_macos-3.1.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.3/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"flutter_secure_storage_linux","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage_linux-1.2.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_linux","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[],"dev_dependency":false}],"windows":[{"name":"flutter_secure_storage_windows","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage_windows-3.1.2/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_windows","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[],"dev_dependency":false}],"web":[{"name":"flutter_secure_storage_web","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage_web-1.2.1/","dependencies":[],"dev_dependency":false}]},"dependencyGraph":[{"name":"flutter_secure_storage","dependencies":["flutter_secure_storage_linux","flutter_secure_storage_macos","flutter_secure_storage_web","flutter_secure_storage_windows"]},{"name":"flutter_secure_storage_linux","dependencies":[]},{"name":"flutter_secure_storage_macos","dependencies":[]},{"name":"flutter_secure_storage_web","dependencies":[]},{"name":"flutter_secure_storage_windows","dependencies":["path_provider"]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]}],"date_created":"2025-12-04 12:33:12.174628","version":"3.35.7","swift_package_manager_enabled":{"ios":false,"macos":false}}
|
||||
2
.idea/modules.xml
generated
2
.idea/modules.xml
generated
@@ -5,11 +5,13 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/modules/auth/melos_auth.iml" filepath="$PROJECT_DIR$/modules/auth/melos_auth.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/modules/dashboard_shell/melos_dashboard_shell.iml" filepath="$PROJECT_DIR$/modules/dashboard_shell/melos_dashboard_shell.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/packages/design_system/melos_design_system.iml" filepath="$PROJECT_DIR$/packages/design_system/melos_design_system.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/packages/fonts/melos_fonts.iml" filepath="$PROJECT_DIR$/packages/fonts/melos_fonts.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/modules/home/melos_home.iml" filepath="$PROJECT_DIR$/modules/home/melos_home.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/packages/navigation/melos_navigation.iml" filepath="$PROJECT_DIR$/packages/navigation/melos_navigation.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/modules/notifications/melos_notifications.iml" filepath="$PROJECT_DIR$/modules/notifications/melos_notifications.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/modules/profile/melos_profile.iml" filepath="$PROJECT_DIR$/modules/profile/melos_profile.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/apps/mobile_app/melos_sf_app_platform.iml" filepath="$PROJECT_DIR$/apps/mobile_app/melos_sf_app_platform.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/packages/sf_infrastructure/melos_sf_infrastructure.iml" filepath="$PROJECT_DIR$/packages/sf_infrastructure/melos_sf_infrastructure.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/packages/sf_localizations/melos_sf_localizations.iml" filepath="$PROJECT_DIR$/packages/sf_localizations/melos_sf_localizations.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/packages/sf_shared/melos_sf_shared.iml" filepath="$PROJECT_DIR$/packages/sf_shared/melos_sf_shared.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/packages/utils/melos_utils.iml" filepath="$PROJECT_DIR$/packages/utils/melos_utils.iml" />
|
||||
|
||||
7
.idea/runConfigurations/melos_flutter_test_sf_infrastructure.xml
generated
Normal file
7
.idea/runConfigurations/melos_flutter_test_sf_infrastructure.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<!-- Generated by Melos -->
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Flutter Test -> 'sf_infrastructure'" type="FlutterTestConfigType" factoryName="Flutter Test">
|
||||
<option name="testDir" value="$PROJECT_DIR$/packages/sf_infrastructure/test" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
2
apps/mobile_app/.env
Normal file
2
apps/mobile_app/.env
Normal file
@@ -0,0 +1,2 @@
|
||||
API_BASE_URL=https://api-neki-b2b.neki.es/gateway/api/
|
||||
API_ORIGIN =https://neki-b2b.neki.es
|
||||
@@ -1,4 +1,6 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<application
|
||||
android:label="sf_payments"
|
||||
android:name="${applicationName}"
|
||||
|
||||
8
apps/mobile_app/lib/config/env/env.dart
vendored
Normal file
8
apps/mobile_app/lib/config/env/env.dart
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
|
||||
class Env {
|
||||
static String get apiBaseUrl => dotenv.env['API_BASE_URL'] ?? '';
|
||||
static String get apiOrigin => dotenv.env['API_ORIGIN'] ?? '';
|
||||
|
||||
// static String get apiKey => dotenv.env['API_KEY'] ?? '';
|
||||
}
|
||||
12
apps/mobile_app/lib/config/env/questia_env_config.dart
vendored
Normal file
12
apps/mobile_app/lib/config/env/questia_env_config.dart
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
import 'env.dart';
|
||||
|
||||
class QuestiaEnvConfig implements EnvConfig {
|
||||
@override
|
||||
String get apiBaseUrl => Env.apiBaseUrl;
|
||||
@override
|
||||
String get apiOrigin => Env.apiOrigin;
|
||||
|
||||
// @override
|
||||
// String get apiKey => Env.apiKey;
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:sf_app_platform/config/env/questia_env_config.dart';
|
||||
import 'package:sf_app_platform/navigation/app_router.dart';
|
||||
import 'package:navigation/navigation_module.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
|
||||
Future<void> main() async {
|
||||
@@ -11,7 +15,9 @@ Future<void> main() async {
|
||||
navigationModule();
|
||||
configureAppRouter();
|
||||
themePackages();
|
||||
await dotenv.load(fileName: '.env');
|
||||
|
||||
await configureDependencies(QuestiaEnvConfig(), log: kDebugMode);
|
||||
runApp(const ProviderScope(child: PlatformApp()));
|
||||
}
|
||||
|
||||
@@ -29,7 +35,8 @@ class PlatformApp extends ConsumerWidget {
|
||||
),
|
||||
routerConfig: appRouter,
|
||||
debugShowCheckedModeBanner: false,
|
||||
localizationsDelegates: const [
|
||||
localizationsDelegates: [
|
||||
// CountryLocalizations.getDelegate(enableLocalization: false),
|
||||
SFLocalizations.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
@@ -48,4 +55,4 @@ class PlatformApp extends ConsumerWidget {
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,13 +35,13 @@ void configureAppRouter() {
|
||||
),
|
||||
GoRoute(
|
||||
path: AppRoutes.linkPhone,
|
||||
name: 'link_phone',
|
||||
pageBuilder: LinkPhoneBuilder().buildPage,
|
||||
name: 'request_link_phone',
|
||||
pageBuilder: RequestLinkPhoneBuilder().buildPage,
|
||||
),
|
||||
GoRoute(
|
||||
path: AppRoutes.phoneCode,
|
||||
name: 'phone_code',
|
||||
pageBuilder: PhoneCodeBuilder().buildPage,
|
||||
name: 'Verify_link_phone_code',
|
||||
pageBuilder: VerifyLinkPhoneCodeBuilder().buildPage,
|
||||
),
|
||||
GoRoute(
|
||||
path: AppRoutes.recoverPassword,
|
||||
|
||||
@@ -168,6 +168,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
country_code_picker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: country_code_picker
|
||||
sha256: f0411f4833b6f98e8b7215f4fa3813bcc88e50f13925f70a170dbd36e3e447f5
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.4.1"
|
||||
coverage:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -214,6 +222,30 @@ packages:
|
||||
relative: true
|
||||
source: path
|
||||
version: "0.0.1"
|
||||
diacritic:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: diacritic
|
||||
sha256: "12981945ec38931748836cd76f2b38773118d0baef3c68404bdfde9566147876"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.6"
|
||||
dio:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dio
|
||||
sha256: d90ee57923d1828ac14e492ca49440f65477f4bb1263575900be731a3dac66a9
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.9.0"
|
||||
dio_web_adapter:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dio_web_adapter
|
||||
sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
equatable:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -259,6 +291,14 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_dotenv:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_dotenv
|
||||
sha256: d4130c4a43e0b13fefc593bc3961f2cb46e30cb79e253d4a526b1b5d24ae1ce4
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.0"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
@@ -284,10 +324,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_svg
|
||||
sha256: b9c2ad5872518a27507ab432d1fb97e8813b05f0fc693f9d40fad06d073e0678
|
||||
sha256: "87fbd7c534435b6c5d9d98b01e1fd527812b82e68ddd8bd35fc45ed0fa8f0a95"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
version: "2.2.3"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
@@ -298,6 +338,13 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
fonts:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "../../packages/fonts"
|
||||
relative: true
|
||||
source: path
|
||||
version: "0.0.1"
|
||||
freezed:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -425,6 +472,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.9.0"
|
||||
json_serializable:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: json_serializable
|
||||
sha256: c5b2ee75210a0f263c6c7b9eeea80553dbae96ea1bf57f02484e806a3ffdffa3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.11.2"
|
||||
leak_tracker:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -590,6 +645,13 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.3"
|
||||
sf_infrastructure:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "../../packages/sf_infrastructure"
|
||||
relative: true
|
||||
source: path
|
||||
version: "0.0.1"
|
||||
sf_localizations:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -776,6 +838,14 @@ packages:
|
||||
relative: true
|
||||
source: path
|
||||
version: "0.0.1"
|
||||
uuid:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: uuid
|
||||
sha256: a11b666489b1954e01d992f3d601b1804a33937b5a8fe677bd26b8a9f96f96e8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.5.2"
|
||||
vector_graphics:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -874,4 +944,4 @@ packages:
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.9.2 <4.0.0"
|
||||
flutter: ">=3.29.0"
|
||||
flutter: ">=3.32.0"
|
||||
|
||||
@@ -57,12 +57,16 @@ dependencies:
|
||||
path: ../../packages/sf_localizations
|
||||
fonts:
|
||||
path: ../../packages/fonts
|
||||
sf_infrastructure:
|
||||
path: ../../packages/sf_infrastructure
|
||||
|
||||
#dependencies go here
|
||||
cupertino_icons: ^1.0.8
|
||||
flutter_svg: ^2.2.1
|
||||
go_router_builder: ^4.1.1
|
||||
build_runner: ^2.7.1
|
||||
flutter_dotenv: ^6.0.0
|
||||
country_code_picker: ^3.4.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
@@ -89,7 +93,7 @@ flutter:
|
||||
# To add assets to your application, add an assets section, like this:
|
||||
assets:
|
||||
- assets/images/ui/
|
||||
|
||||
- .env
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.dev/to/resolution-aware-images
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# melos_managed_dependency_overrides: auth,dashboard_shell,design_system,home,navigation,notifications,profile,sf_shared,utils,sf_localizations
|
||||
# melos_managed_dependency_overrides: auth,dashboard_shell,design_system,home,navigation,notifications,profile,sf_shared,utils,sf_localizations,fonts,sf_infrastructure
|
||||
dependency_overrides:
|
||||
auth:
|
||||
path: ../../modules/auth
|
||||
@@ -6,6 +6,8 @@ dependency_overrides:
|
||||
path: ../../modules/dashboard_shell
|
||||
design_system:
|
||||
path: ../../packages/design_system
|
||||
fonts:
|
||||
path: ../../packages/fonts
|
||||
home:
|
||||
path: ../../modules/home
|
||||
navigation:
|
||||
@@ -14,6 +16,8 @@ dependency_overrides:
|
||||
path: ../../modules/notifications
|
||||
profile:
|
||||
path: ../../modules/profile
|
||||
sf_infrastructure:
|
||||
path: ../../packages/sf_infrastructure
|
||||
sf_localizations:
|
||||
path: ../../packages/sf_localizations
|
||||
sf_shared:
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
export 'src/device_sign_up/link_watch/create_profile_screen.dart';
|
||||
export 'src/onboarding/onboarding_builder.dart';
|
||||
export 'src/login/link_phone_builder.dart';
|
||||
export 'src/login/phone_code_builder.dart';
|
||||
export 'src/login/login_builder.dart';
|
||||
export 'src/recover_password/recover_password_builder.dart';
|
||||
export 'src/device_sign_up/device_signup_builder.dart';
|
||||
export 'src/sign_up/signup_builder.dart';
|
||||
export 'src/features/device_sign_up/link_watch/create_profile_screen.dart';
|
||||
export 'src/features/onboarding/onboarding_builder.dart';
|
||||
export 'src/features/link_phone/presentation/request_phone/request_link_phone_builder.dart';
|
||||
export 'src/features/link_phone/presentation/verify_code/verify_link_phone_code_builder.dart';
|
||||
export 'src/features/login/login_builder.dart';
|
||||
export 'src/features/recover_password/recover_password_builder.dart';
|
||||
export 'src/features/device_sign_up/device_signup_builder.dart';
|
||||
export 'src/features/sign_up/sign_up_builder.dart';
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import 'package:auth/src/features/sign_up/domain/entities/sign_up_request_entity.dart';
|
||||
import 'package:auth/src/features/sign_up/domain/entities/two_fa_secret_entity.dart';
|
||||
|
||||
abstract class AuthRemoteDatasource {
|
||||
Future<void> requestPhoneCode({required String phone});
|
||||
|
||||
Future<void> verifyPhoneCode({required String phone, required String code});
|
||||
|
||||
Future<String> login({required String email, required String password});
|
||||
|
||||
Future<void> twoFALogin({required String token, required String code});
|
||||
|
||||
Future<String> signUp({required SignUpRequestEntity request});
|
||||
|
||||
Future<TwoFASecretEntity> generateTwoFASignUp({required String token});
|
||||
Future<void> verifyTwoFACodeSignUp({
|
||||
required String token,
|
||||
required String code,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:auth/src/core/data/models/sign_up_request_model.dart';
|
||||
import 'package:auth/src/core/data/models/sign_up_response_model.dart';
|
||||
import 'package:auth/src/core/data/models/two_fa_secret_response_model.dart';
|
||||
import 'package:auth/src/features/sign_up/domain/entities/sign_up_request_entity.dart';
|
||||
import 'package:auth/src/features/sign_up/domain/entities/two_fa_secret_entity.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
|
||||
import 'auth_remote_datasource.dart';
|
||||
|
||||
class AuthRemoteDatasourceImpl implements AuthRemoteDatasource {
|
||||
AuthRemoteDatasourceImpl(this._repository);
|
||||
|
||||
final QuestiaRepository _repository;
|
||||
|
||||
@override
|
||||
Future<void> requestPhoneCode({required String phone}) async {
|
||||
try {
|
||||
await _repository.post<void>(
|
||||
'/auth/link-phone/request-code',
|
||||
body: <String, dynamic>{'phone': phone},
|
||||
);
|
||||
} on DioException catch (error) {
|
||||
throw _mapDioError(
|
||||
error,
|
||||
defaultMessage: error.response?.data ?? 'Error to request phone code',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> verifyPhoneCode({
|
||||
required String phone,
|
||||
required String code,
|
||||
}) async {
|
||||
try {
|
||||
await _repository.post<void>(
|
||||
'/auth/link-phone/verify-code',
|
||||
body: <String, dynamic>{'phone': phone, 'code': code},
|
||||
);
|
||||
} on DioException catch (error) {
|
||||
throw _mapDioError(error, defaultMessage: 'Error in verification code');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> login({
|
||||
required String email,
|
||||
required String password,
|
||||
}) async {
|
||||
try {
|
||||
final response = await _repository.post<Map<String, dynamic>>(
|
||||
'/auth/login',
|
||||
body: <String, dynamic>{'email': email, 'password': password},
|
||||
);
|
||||
final token = response.data!['token'];
|
||||
return token;
|
||||
} on DioException catch (error) {
|
||||
throw _mapDioError(
|
||||
error,
|
||||
defaultMessage: error.message ?? 'Error in login',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> twoFALogin({
|
||||
required String token,
|
||||
required String code,
|
||||
}) async {
|
||||
try {
|
||||
final response = await _repository.post<String>(
|
||||
'/auth/totp/login',
|
||||
body: <String, dynamic>{
|
||||
'token': token,
|
||||
'code': code,
|
||||
'rememberMe': true,
|
||||
},
|
||||
);
|
||||
|
||||
final data = response.data;
|
||||
if (data == null || data.isEmpty) {
|
||||
throw Exception('Empty response from /auth/totp/login');
|
||||
}
|
||||
|
||||
return data;
|
||||
} on DioException catch (error) {
|
||||
throw _mapDioError(error, defaultMessage: 'Error in twoFALogin');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> signUp({required SignUpRequestEntity request}) async {
|
||||
try {
|
||||
final body = request.toModel().toJson();
|
||||
debugPrint(body.toString());
|
||||
debugPrint(const JsonEncoder.withIndent(' ').convert(body));
|
||||
|
||||
final response = await _repository.post<Map<String, dynamic>>(
|
||||
'/payment-profiles/signup',
|
||||
body: body,
|
||||
);
|
||||
|
||||
final data = response.data;
|
||||
if (data == null || data.isEmpty) {
|
||||
throw Exception('Empty response from /payment-profiles/signup');
|
||||
}
|
||||
|
||||
final parsed = SignUpResponseModel.fromJson(data);
|
||||
|
||||
if (!parsed.isCreated) {
|
||||
throw Exception('Sign up failed: isCreated=false');
|
||||
}
|
||||
|
||||
final token = parsed.item.token.trim();
|
||||
if (token.isEmpty) {
|
||||
throw Exception('Sign up response has empty token');
|
||||
}
|
||||
|
||||
return token;
|
||||
} on DioException catch (error) {
|
||||
throw _mapDioError(error, defaultMessage: 'Error in signUp');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<TwoFASecretEntity> generateTwoFASignUp({required String token}) async {
|
||||
try {
|
||||
final response = await _repository.post<Map<String, dynamic>>(
|
||||
'/auth/totp/secret',
|
||||
body: <String, dynamic>{'token': token},
|
||||
);
|
||||
|
||||
final data = response.data;
|
||||
if (data == null || data.isEmpty) {
|
||||
throw Exception('Empty response from /auth/totp/secret');
|
||||
}
|
||||
|
||||
final model = TwoFASecretResponseModel.fromJson(data);
|
||||
return model.toEntity();
|
||||
} on DioException catch (error) {
|
||||
throw _mapDioError(error, defaultMessage: 'Error in twoFASignUp');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> verifyTwoFACodeSignUp({
|
||||
required String token,
|
||||
required String code,
|
||||
}) async {
|
||||
try {
|
||||
final response = await _repository.post<String>(
|
||||
'/auth/totp/code',
|
||||
body: <String, dynamic>{'token': token, 'code': code},
|
||||
);
|
||||
|
||||
final data = response.data;
|
||||
if (data == null || data.isEmpty) {
|
||||
throw Exception('Empty response from /auth/totp/code');
|
||||
}
|
||||
|
||||
return data;
|
||||
} on DioException catch (error) {
|
||||
throw _mapDioError(error, defaultMessage: 'Error in twoFaCodeSignUp');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Exception _mapDioError(DioException error, {required String defaultMessage}) {
|
||||
final apiMsg = _extractApiMessage(error.response?.data);
|
||||
final msg = apiMsg ?? error.message ?? defaultMessage;
|
||||
return Exception(msg);
|
||||
}
|
||||
|
||||
String? _extractApiMessage(Object? data) {
|
||||
if (data == null) return null;
|
||||
|
||||
if (data is Map) {
|
||||
final errorObj = data['error'];
|
||||
if (errorObj is Map && errorObj['message'] is String) {
|
||||
return (errorObj['message'] as String).trim();
|
||||
}
|
||||
if (data['message'] is String) {
|
||||
return (data['message'] as String).trim();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (data is String) {
|
||||
final raw = data.trim();
|
||||
if (raw.isEmpty) return null;
|
||||
|
||||
try {
|
||||
final decoded = jsonDecode(raw);
|
||||
return _extractApiMessage(decoded);
|
||||
} catch (_) {
|
||||
return raw;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
31
modules/auth/lib/src/core/data/models/address_model.dart
Normal file
31
modules/auth/lib/src/core/data/models/address_model.dart
Normal file
@@ -0,0 +1,31 @@
|
||||
import 'package:auth/src/features/sign_up/domain/entities/address_entity.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'address_model.freezed.dart';
|
||||
part 'address_model.g.dart';
|
||||
|
||||
@freezed
|
||||
abstract class AddressModel with _$AddressModel {
|
||||
const factory AddressModel({
|
||||
required String street,
|
||||
required String city,
|
||||
required String province,
|
||||
required String state,
|
||||
required String country,
|
||||
required int postCode,
|
||||
}) = _AddressModel;
|
||||
|
||||
factory AddressModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$AddressModelFromJson(json);
|
||||
}
|
||||
|
||||
extension AddressModelMapper on AddressEntity {
|
||||
AddressModel toModel() => AddressModel(
|
||||
street: street,
|
||||
city: city,
|
||||
province: province,
|
||||
state: state,
|
||||
country: country,
|
||||
postCode: postCode,
|
||||
);
|
||||
}
|
||||
292
modules/auth/lib/src/core/data/models/address_model.freezed.dart
Normal file
292
modules/auth/lib/src/core/data/models/address_model.freezed.dart
Normal file
@@ -0,0 +1,292 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'address_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
/// @nodoc
|
||||
mixin _$AddressModel {
|
||||
|
||||
String get street; String get city; String get province; String get state; String get country; int get postCode;
|
||||
/// Create a copy of AddressModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$AddressModelCopyWith<AddressModel> get copyWith => _$AddressModelCopyWithImpl<AddressModel>(this as AddressModel, _$identity);
|
||||
|
||||
/// Serializes this AddressModel to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is AddressModel&&(identical(other.street, street) || other.street == street)&&(identical(other.city, city) || other.city == city)&&(identical(other.province, province) || other.province == province)&&(identical(other.state, state) || other.state == state)&&(identical(other.country, country) || other.country == country)&&(identical(other.postCode, postCode) || other.postCode == postCode));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,street,city,province,state,country,postCode);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AddressModel(street: $street, city: $city, province: $province, state: $state, country: $country, postCode: $postCode)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $AddressModelCopyWith<$Res> {
|
||||
factory $AddressModelCopyWith(AddressModel value, $Res Function(AddressModel) _then) = _$AddressModelCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String street, String city, String province, String state, String country, int postCode
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$AddressModelCopyWithImpl<$Res>
|
||||
implements $AddressModelCopyWith<$Res> {
|
||||
_$AddressModelCopyWithImpl(this._self, this._then);
|
||||
|
||||
final AddressModel _self;
|
||||
final $Res Function(AddressModel) _then;
|
||||
|
||||
/// Create a copy of AddressModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? street = null,Object? city = null,Object? province = null,Object? state = null,Object? country = null,Object? postCode = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
street: null == street ? _self.street : street // ignore: cast_nullable_to_non_nullable
|
||||
as String,city: null == city ? _self.city : city // ignore: cast_nullable_to_non_nullable
|
||||
as String,province: null == province ? _self.province : province // ignore: cast_nullable_to_non_nullable
|
||||
as String,state: null == state ? _self.state : state // ignore: cast_nullable_to_non_nullable
|
||||
as String,country: null == country ? _self.country : country // ignore: cast_nullable_to_non_nullable
|
||||
as String,postCode: null == postCode ? _self.postCode : postCode // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [AddressModel].
|
||||
extension AddressModelPatterns on AddressModel {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _AddressModel value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _AddressModel() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _AddressModel value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _AddressModel():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _AddressModel value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _AddressModel() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String street, String city, String province, String state, String country, int postCode)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AddressModel() when $default != null:
|
||||
return $default(_that.street,_that.city,_that.province,_that.state,_that.country,_that.postCode);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String street, String city, String province, String state, String country, int postCode) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AddressModel():
|
||||
return $default(_that.street,_that.city,_that.province,_that.state,_that.country,_that.postCode);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String street, String city, String province, String state, String country, int postCode)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AddressModel() when $default != null:
|
||||
return $default(_that.street,_that.city,_that.province,_that.state,_that.country,_that.postCode);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _AddressModel implements AddressModel {
|
||||
const _AddressModel({required this.street, required this.city, required this.province, required this.state, required this.country, required this.postCode});
|
||||
factory _AddressModel.fromJson(Map<String, dynamic> json) => _$AddressModelFromJson(json);
|
||||
|
||||
@override final String street;
|
||||
@override final String city;
|
||||
@override final String province;
|
||||
@override final String state;
|
||||
@override final String country;
|
||||
@override final int postCode;
|
||||
|
||||
/// Create a copy of AddressModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$AddressModelCopyWith<_AddressModel> get copyWith => __$AddressModelCopyWithImpl<_AddressModel>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$AddressModelToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AddressModel&&(identical(other.street, street) || other.street == street)&&(identical(other.city, city) || other.city == city)&&(identical(other.province, province) || other.province == province)&&(identical(other.state, state) || other.state == state)&&(identical(other.country, country) || other.country == country)&&(identical(other.postCode, postCode) || other.postCode == postCode));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,street,city,province,state,country,postCode);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AddressModel(street: $street, city: $city, province: $province, state: $state, country: $country, postCode: $postCode)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$AddressModelCopyWith<$Res> implements $AddressModelCopyWith<$Res> {
|
||||
factory _$AddressModelCopyWith(_AddressModel value, $Res Function(_AddressModel) _then) = __$AddressModelCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String street, String city, String province, String state, String country, int postCode
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$AddressModelCopyWithImpl<$Res>
|
||||
implements _$AddressModelCopyWith<$Res> {
|
||||
__$AddressModelCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _AddressModel _self;
|
||||
final $Res Function(_AddressModel) _then;
|
||||
|
||||
/// Create a copy of AddressModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? street = null,Object? city = null,Object? province = null,Object? state = null,Object? country = null,Object? postCode = null,}) {
|
||||
return _then(_AddressModel(
|
||||
street: null == street ? _self.street : street // ignore: cast_nullable_to_non_nullable
|
||||
as String,city: null == city ? _self.city : city // ignore: cast_nullable_to_non_nullable
|
||||
as String,province: null == province ? _self.province : province // ignore: cast_nullable_to_non_nullable
|
||||
as String,state: null == state ? _self.state : state // ignore: cast_nullable_to_non_nullable
|
||||
as String,country: null == country ? _self.country : country // ignore: cast_nullable_to_non_nullable
|
||||
as String,postCode: null == postCode ? _self.postCode : postCode // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
27
modules/auth/lib/src/core/data/models/address_model.g.dart
Normal file
27
modules/auth/lib/src/core/data/models/address_model.g.dart
Normal file
@@ -0,0 +1,27 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'address_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_AddressModel _$AddressModelFromJson(Map<String, dynamic> json) =>
|
||||
_AddressModel(
|
||||
street: json['street'] as String,
|
||||
city: json['city'] as String,
|
||||
province: json['province'] as String,
|
||||
state: json['state'] as String,
|
||||
country: json['country'] as String,
|
||||
postCode: (json['postCode'] as num).toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$AddressModelToJson(_AddressModel instance) =>
|
||||
<String, dynamic>{
|
||||
'street': instance.street,
|
||||
'city': instance.city,
|
||||
'province': instance.province,
|
||||
'state': instance.state,
|
||||
'country': instance.country,
|
||||
'postCode': instance.postCode,
|
||||
};
|
||||
@@ -0,0 +1,61 @@
|
||||
import 'package:auth/src/features/sign_up/domain/entities/sign_up_request_entity.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'address_model.dart';
|
||||
|
||||
part 'sign_up_request_model.freezed.dart';
|
||||
part 'sign_up_request_model.g.dart';
|
||||
|
||||
@freezed
|
||||
abstract class SignUpRequestModel with _$SignUpRequestModel {
|
||||
const factory SignUpRequestModel({
|
||||
required String firstName,
|
||||
required String lastName,
|
||||
required String email,
|
||||
required String phone,
|
||||
required String language,
|
||||
required String password,
|
||||
required List<AddressModel> taxResidences,
|
||||
required List<AddressModel> addresses,
|
||||
required int bornAt,
|
||||
required String userId,
|
||||
required String placeOfBirth,
|
||||
required String birthCountry,
|
||||
// ignore: invalid_annotation_target
|
||||
@JsonKey(name: 'document') required String documentNumber,
|
||||
required String documentType,
|
||||
// ignore: invalid_annotation_target
|
||||
@JsonKey(name: 'relationType') required String relationship,
|
||||
}) = _SignUpRequestModel;
|
||||
|
||||
factory SignUpRequestModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$SignUpRequestModelFromJson(json);
|
||||
|
||||
@override
|
||||
@JsonKey(name: 'document')
|
||||
String get documentNumber;
|
||||
@override
|
||||
@JsonKey(name: 'relationType')
|
||||
String get relationship;
|
||||
}
|
||||
|
||||
extension SignUpRequestModelMapper on SignUpRequestEntity {
|
||||
SignUpRequestModel toModel() => SignUpRequestModel(
|
||||
firstName: firstName,
|
||||
lastName: lastName,
|
||||
email: email,
|
||||
phone: phone,
|
||||
language: language,
|
||||
password: password,
|
||||
taxResidences: taxResidences
|
||||
.map((e) => e.toModel())
|
||||
.toList(growable: false),
|
||||
addresses: addresses.map((e) => e.toModel()).toList(growable: false),
|
||||
bornAt: bornAt,
|
||||
userId: userId,
|
||||
placeOfBirth: placeOfBirth,
|
||||
birthCountry: birthCountry,
|
||||
documentNumber: documentNumber,
|
||||
documentType: documentType,
|
||||
relationship: relationship,
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,335 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'sign_up_request_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
/// @nodoc
|
||||
mixin _$SignUpRequestModel {
|
||||
|
||||
String get firstName; String get lastName; String get email; String get phone; String get language; String get password; List<AddressModel> get taxResidences; List<AddressModel> get addresses; int get bornAt; String get userId; String get placeOfBirth; String get birthCountry;// ignore: invalid_annotation_target
|
||||
@JsonKey(name: 'document') String get documentNumber; String get documentType;// ignore: invalid_annotation_target
|
||||
@JsonKey(name: 'relationType') String get relationship;
|
||||
/// Create a copy of SignUpRequestModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$SignUpRequestModelCopyWith<SignUpRequestModel> get copyWith => _$SignUpRequestModelCopyWithImpl<SignUpRequestModel>(this as SignUpRequestModel, _$identity);
|
||||
|
||||
/// Serializes this SignUpRequestModel to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SignUpRequestModel&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.email, email) || other.email == email)&&(identical(other.phone, phone) || other.phone == phone)&&(identical(other.language, language) || other.language == language)&&(identical(other.password, password) || other.password == password)&&const DeepCollectionEquality().equals(other.taxResidences, taxResidences)&&const DeepCollectionEquality().equals(other.addresses, addresses)&&(identical(other.bornAt, bornAt) || other.bornAt == bornAt)&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.placeOfBirth, placeOfBirth) || other.placeOfBirth == placeOfBirth)&&(identical(other.birthCountry, birthCountry) || other.birthCountry == birthCountry)&&(identical(other.documentNumber, documentNumber) || other.documentNumber == documentNumber)&&(identical(other.documentType, documentType) || other.documentType == documentType)&&(identical(other.relationship, relationship) || other.relationship == relationship));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,firstName,lastName,email,phone,language,password,const DeepCollectionEquality().hash(taxResidences),const DeepCollectionEquality().hash(addresses),bornAt,userId,placeOfBirth,birthCountry,documentNumber,documentType,relationship);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SignUpRequestModel(firstName: $firstName, lastName: $lastName, email: $email, phone: $phone, language: $language, password: $password, taxResidences: $taxResidences, addresses: $addresses, bornAt: $bornAt, userId: $userId, placeOfBirth: $placeOfBirth, birthCountry: $birthCountry, documentNumber: $documentNumber, documentType: $documentType, relationship: $relationship)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $SignUpRequestModelCopyWith<$Res> {
|
||||
factory $SignUpRequestModelCopyWith(SignUpRequestModel value, $Res Function(SignUpRequestModel) _then) = _$SignUpRequestModelCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String firstName, String lastName, String email, String phone, String language, String password, List<AddressModel> taxResidences, List<AddressModel> addresses, int bornAt, String userId, String placeOfBirth, String birthCountry,@JsonKey(name: 'document') String documentNumber, String documentType,@JsonKey(name: 'relationType') String relationship
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$SignUpRequestModelCopyWithImpl<$Res>
|
||||
implements $SignUpRequestModelCopyWith<$Res> {
|
||||
_$SignUpRequestModelCopyWithImpl(this._self, this._then);
|
||||
|
||||
final SignUpRequestModel _self;
|
||||
final $Res Function(SignUpRequestModel) _then;
|
||||
|
||||
/// Create a copy of SignUpRequestModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? firstName = null,Object? lastName = null,Object? email = null,Object? phone = null,Object? language = null,Object? password = null,Object? taxResidences = null,Object? addresses = null,Object? bornAt = null,Object? userId = null,Object? placeOfBirth = null,Object? birthCountry = null,Object? documentNumber = null,Object? documentType = null,Object? relationship = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
firstName: null == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable
|
||||
as String,lastName: null == lastName ? _self.lastName : lastName // ignore: cast_nullable_to_non_nullable
|
||||
as String,email: null == email ? _self.email : email // ignore: cast_nullable_to_non_nullable
|
||||
as String,phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable
|
||||
as String,language: null == language ? _self.language : language // ignore: cast_nullable_to_non_nullable
|
||||
as String,password: null == password ? _self.password : password // ignore: cast_nullable_to_non_nullable
|
||||
as String,taxResidences: null == taxResidences ? _self.taxResidences : taxResidences // ignore: cast_nullable_to_non_nullable
|
||||
as List<AddressModel>,addresses: null == addresses ? _self.addresses : addresses // ignore: cast_nullable_to_non_nullable
|
||||
as List<AddressModel>,bornAt: null == bornAt ? _self.bornAt : bornAt // ignore: cast_nullable_to_non_nullable
|
||||
as int,userId: null == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable
|
||||
as String,placeOfBirth: null == placeOfBirth ? _self.placeOfBirth : placeOfBirth // ignore: cast_nullable_to_non_nullable
|
||||
as String,birthCountry: null == birthCountry ? _self.birthCountry : birthCountry // ignore: cast_nullable_to_non_nullable
|
||||
as String,documentNumber: null == documentNumber ? _self.documentNumber : documentNumber // ignore: cast_nullable_to_non_nullable
|
||||
as String,documentType: null == documentType ? _self.documentType : documentType // ignore: cast_nullable_to_non_nullable
|
||||
as String,relationship: null == relationship ? _self.relationship : relationship // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [SignUpRequestModel].
|
||||
extension SignUpRequestModelPatterns on SignUpRequestModel {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _SignUpRequestModel value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpRequestModel() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _SignUpRequestModel value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpRequestModel():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _SignUpRequestModel value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpRequestModel() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String firstName, String lastName, String email, String phone, String language, String password, List<AddressModel> taxResidences, List<AddressModel> addresses, int bornAt, String userId, String placeOfBirth, String birthCountry, @JsonKey(name: 'document') String documentNumber, String documentType, @JsonKey(name: 'relationType') String relationship)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpRequestModel() when $default != null:
|
||||
return $default(_that.firstName,_that.lastName,_that.email,_that.phone,_that.language,_that.password,_that.taxResidences,_that.addresses,_that.bornAt,_that.userId,_that.placeOfBirth,_that.birthCountry,_that.documentNumber,_that.documentType,_that.relationship);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String firstName, String lastName, String email, String phone, String language, String password, List<AddressModel> taxResidences, List<AddressModel> addresses, int bornAt, String userId, String placeOfBirth, String birthCountry, @JsonKey(name: 'document') String documentNumber, String documentType, @JsonKey(name: 'relationType') String relationship) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpRequestModel():
|
||||
return $default(_that.firstName,_that.lastName,_that.email,_that.phone,_that.language,_that.password,_that.taxResidences,_that.addresses,_that.bornAt,_that.userId,_that.placeOfBirth,_that.birthCountry,_that.documentNumber,_that.documentType,_that.relationship);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String firstName, String lastName, String email, String phone, String language, String password, List<AddressModel> taxResidences, List<AddressModel> addresses, int bornAt, String userId, String placeOfBirth, String birthCountry, @JsonKey(name: 'document') String documentNumber, String documentType, @JsonKey(name: 'relationType') String relationship)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpRequestModel() when $default != null:
|
||||
return $default(_that.firstName,_that.lastName,_that.email,_that.phone,_that.language,_that.password,_that.taxResidences,_that.addresses,_that.bornAt,_that.userId,_that.placeOfBirth,_that.birthCountry,_that.documentNumber,_that.documentType,_that.relationship);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _SignUpRequestModel implements SignUpRequestModel {
|
||||
const _SignUpRequestModel({required this.firstName, required this.lastName, required this.email, required this.phone, required this.language, required this.password, required final List<AddressModel> taxResidences, required final List<AddressModel> addresses, required this.bornAt, required this.userId, required this.placeOfBirth, required this.birthCountry, @JsonKey(name: 'document') required this.documentNumber, required this.documentType, @JsonKey(name: 'relationType') required this.relationship}): _taxResidences = taxResidences,_addresses = addresses;
|
||||
factory _SignUpRequestModel.fromJson(Map<String, dynamic> json) => _$SignUpRequestModelFromJson(json);
|
||||
|
||||
@override final String firstName;
|
||||
@override final String lastName;
|
||||
@override final String email;
|
||||
@override final String phone;
|
||||
@override final String language;
|
||||
@override final String password;
|
||||
final List<AddressModel> _taxResidences;
|
||||
@override List<AddressModel> get taxResidences {
|
||||
if (_taxResidences is EqualUnmodifiableListView) return _taxResidences;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_taxResidences);
|
||||
}
|
||||
|
||||
final List<AddressModel> _addresses;
|
||||
@override List<AddressModel> get addresses {
|
||||
if (_addresses is EqualUnmodifiableListView) return _addresses;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_addresses);
|
||||
}
|
||||
|
||||
@override final int bornAt;
|
||||
@override final String userId;
|
||||
@override final String placeOfBirth;
|
||||
@override final String birthCountry;
|
||||
// ignore: invalid_annotation_target
|
||||
@override@JsonKey(name: 'document') final String documentNumber;
|
||||
@override final String documentType;
|
||||
// ignore: invalid_annotation_target
|
||||
@override@JsonKey(name: 'relationType') final String relationship;
|
||||
|
||||
/// Create a copy of SignUpRequestModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$SignUpRequestModelCopyWith<_SignUpRequestModel> get copyWith => __$SignUpRequestModelCopyWithImpl<_SignUpRequestModel>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$SignUpRequestModelToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SignUpRequestModel&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.email, email) || other.email == email)&&(identical(other.phone, phone) || other.phone == phone)&&(identical(other.language, language) || other.language == language)&&(identical(other.password, password) || other.password == password)&&const DeepCollectionEquality().equals(other._taxResidences, _taxResidences)&&const DeepCollectionEquality().equals(other._addresses, _addresses)&&(identical(other.bornAt, bornAt) || other.bornAt == bornAt)&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.placeOfBirth, placeOfBirth) || other.placeOfBirth == placeOfBirth)&&(identical(other.birthCountry, birthCountry) || other.birthCountry == birthCountry)&&(identical(other.documentNumber, documentNumber) || other.documentNumber == documentNumber)&&(identical(other.documentType, documentType) || other.documentType == documentType)&&(identical(other.relationship, relationship) || other.relationship == relationship));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,firstName,lastName,email,phone,language,password,const DeepCollectionEquality().hash(_taxResidences),const DeepCollectionEquality().hash(_addresses),bornAt,userId,placeOfBirth,birthCountry,documentNumber,documentType,relationship);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SignUpRequestModel(firstName: $firstName, lastName: $lastName, email: $email, phone: $phone, language: $language, password: $password, taxResidences: $taxResidences, addresses: $addresses, bornAt: $bornAt, userId: $userId, placeOfBirth: $placeOfBirth, birthCountry: $birthCountry, documentNumber: $documentNumber, documentType: $documentType, relationship: $relationship)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$SignUpRequestModelCopyWith<$Res> implements $SignUpRequestModelCopyWith<$Res> {
|
||||
factory _$SignUpRequestModelCopyWith(_SignUpRequestModel value, $Res Function(_SignUpRequestModel) _then) = __$SignUpRequestModelCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String firstName, String lastName, String email, String phone, String language, String password, List<AddressModel> taxResidences, List<AddressModel> addresses, int bornAt, String userId, String placeOfBirth, String birthCountry,@JsonKey(name: 'document') String documentNumber, String documentType,@JsonKey(name: 'relationType') String relationship
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$SignUpRequestModelCopyWithImpl<$Res>
|
||||
implements _$SignUpRequestModelCopyWith<$Res> {
|
||||
__$SignUpRequestModelCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _SignUpRequestModel _self;
|
||||
final $Res Function(_SignUpRequestModel) _then;
|
||||
|
||||
/// Create a copy of SignUpRequestModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? firstName = null,Object? lastName = null,Object? email = null,Object? phone = null,Object? language = null,Object? password = null,Object? taxResidences = null,Object? addresses = null,Object? bornAt = null,Object? userId = null,Object? placeOfBirth = null,Object? birthCountry = null,Object? documentNumber = null,Object? documentType = null,Object? relationship = null,}) {
|
||||
return _then(_SignUpRequestModel(
|
||||
firstName: null == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable
|
||||
as String,lastName: null == lastName ? _self.lastName : lastName // ignore: cast_nullable_to_non_nullable
|
||||
as String,email: null == email ? _self.email : email // ignore: cast_nullable_to_non_nullable
|
||||
as String,phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable
|
||||
as String,language: null == language ? _self.language : language // ignore: cast_nullable_to_non_nullable
|
||||
as String,password: null == password ? _self.password : password // ignore: cast_nullable_to_non_nullable
|
||||
as String,taxResidences: null == taxResidences ? _self._taxResidences : taxResidences // ignore: cast_nullable_to_non_nullable
|
||||
as List<AddressModel>,addresses: null == addresses ? _self._addresses : addresses // ignore: cast_nullable_to_non_nullable
|
||||
as List<AddressModel>,bornAt: null == bornAt ? _self.bornAt : bornAt // ignore: cast_nullable_to_non_nullable
|
||||
as int,userId: null == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable
|
||||
as String,placeOfBirth: null == placeOfBirth ? _self.placeOfBirth : placeOfBirth // ignore: cast_nullable_to_non_nullable
|
||||
as String,birthCountry: null == birthCountry ? _self.birthCountry : birthCountry // ignore: cast_nullable_to_non_nullable
|
||||
as String,documentNumber: null == documentNumber ? _self.documentNumber : documentNumber // ignore: cast_nullable_to_non_nullable
|
||||
as String,documentType: null == documentType ? _self.documentType : documentType // ignore: cast_nullable_to_non_nullable
|
||||
as String,relationship: null == relationship ? _self.relationship : relationship // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,49 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'sign_up_request_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_SignUpRequestModel _$SignUpRequestModelFromJson(Map<String, dynamic> json) =>
|
||||
_SignUpRequestModel(
|
||||
firstName: json['firstName'] as String,
|
||||
lastName: json['lastName'] as String,
|
||||
email: json['email'] as String,
|
||||
phone: json['phone'] as String,
|
||||
language: json['language'] as String,
|
||||
password: json['password'] as String,
|
||||
taxResidences: (json['taxResidences'] as List<dynamic>)
|
||||
.map((e) => AddressModel.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
addresses: (json['addresses'] as List<dynamic>)
|
||||
.map((e) => AddressModel.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
bornAt: (json['bornAt'] as num).toInt(),
|
||||
userId: json['userId'] as String,
|
||||
placeOfBirth: json['placeOfBirth'] as String,
|
||||
birthCountry: json['birthCountry'] as String,
|
||||
documentNumber: json['document'] as String,
|
||||
documentType: json['documentType'] as String,
|
||||
relationship: json['relationType'] as String,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$SignUpRequestModelToJson(_SignUpRequestModel instance) =>
|
||||
<String, dynamic>{
|
||||
'firstName': instance.firstName,
|
||||
'lastName': instance.lastName,
|
||||
'email': instance.email,
|
||||
'phone': instance.phone,
|
||||
'language': instance.language,
|
||||
'password': instance.password,
|
||||
'taxResidences': instance.taxResidences,
|
||||
'addresses': instance.addresses,
|
||||
'bornAt': instance.bornAt,
|
||||
'userId': instance.userId,
|
||||
'placeOfBirth': instance.placeOfBirth,
|
||||
'birthCountry': instance.birthCountry,
|
||||
'document': instance.documentNumber,
|
||||
'documentType': instance.documentType,
|
||||
'relationType': instance.relationship,
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'sign_up_response_model.freezed.dart';
|
||||
part 'sign_up_response_model.g.dart';
|
||||
|
||||
@freezed
|
||||
abstract class SignUpResponseModel with _$SignUpResponseModel {
|
||||
const factory SignUpResponseModel({
|
||||
required bool isCreated,
|
||||
required SignUpResponseItemModel item,
|
||||
}) = _SignUpResponseModel;
|
||||
|
||||
factory SignUpResponseModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$SignUpResponseModelFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class SignUpResponseItemModel with _$SignUpResponseItemModel {
|
||||
const factory SignUpResponseItemModel({required String token}) =
|
||||
_SignUpResponseItemModel;
|
||||
|
||||
factory SignUpResponseItemModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$SignUpResponseItemModelFromJson(json);
|
||||
}
|
||||
@@ -0,0 +1,561 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'sign_up_response_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
/// @nodoc
|
||||
mixin _$SignUpResponseModel {
|
||||
|
||||
bool get isCreated; SignUpResponseItemModel get item;
|
||||
/// Create a copy of SignUpResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$SignUpResponseModelCopyWith<SignUpResponseModel> get copyWith => _$SignUpResponseModelCopyWithImpl<SignUpResponseModel>(this as SignUpResponseModel, _$identity);
|
||||
|
||||
/// Serializes this SignUpResponseModel to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SignUpResponseModel&&(identical(other.isCreated, isCreated) || other.isCreated == isCreated)&&(identical(other.item, item) || other.item == item));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,isCreated,item);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SignUpResponseModel(isCreated: $isCreated, item: $item)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $SignUpResponseModelCopyWith<$Res> {
|
||||
factory $SignUpResponseModelCopyWith(SignUpResponseModel value, $Res Function(SignUpResponseModel) _then) = _$SignUpResponseModelCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
bool isCreated, SignUpResponseItemModel item
|
||||
});
|
||||
|
||||
|
||||
$SignUpResponseItemModelCopyWith<$Res> get item;
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$SignUpResponseModelCopyWithImpl<$Res>
|
||||
implements $SignUpResponseModelCopyWith<$Res> {
|
||||
_$SignUpResponseModelCopyWithImpl(this._self, this._then);
|
||||
|
||||
final SignUpResponseModel _self;
|
||||
final $Res Function(SignUpResponseModel) _then;
|
||||
|
||||
/// Create a copy of SignUpResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? isCreated = null,Object? item = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
isCreated: null == isCreated ? _self.isCreated : isCreated // ignore: cast_nullable_to_non_nullable
|
||||
as bool,item: null == item ? _self.item : item // ignore: cast_nullable_to_non_nullable
|
||||
as SignUpResponseItemModel,
|
||||
));
|
||||
}
|
||||
/// Create a copy of SignUpResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$SignUpResponseItemModelCopyWith<$Res> get item {
|
||||
|
||||
return $SignUpResponseItemModelCopyWith<$Res>(_self.item, (value) {
|
||||
return _then(_self.copyWith(item: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [SignUpResponseModel].
|
||||
extension SignUpResponseModelPatterns on SignUpResponseModel {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _SignUpResponseModel value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpResponseModel() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _SignUpResponseModel value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpResponseModel():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _SignUpResponseModel value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpResponseModel() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool isCreated, SignUpResponseItemModel item)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpResponseModel() when $default != null:
|
||||
return $default(_that.isCreated,_that.item);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool isCreated, SignUpResponseItemModel item) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpResponseModel():
|
||||
return $default(_that.isCreated,_that.item);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool isCreated, SignUpResponseItemModel item)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpResponseModel() when $default != null:
|
||||
return $default(_that.isCreated,_that.item);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _SignUpResponseModel implements SignUpResponseModel {
|
||||
const _SignUpResponseModel({required this.isCreated, required this.item});
|
||||
factory _SignUpResponseModel.fromJson(Map<String, dynamic> json) => _$SignUpResponseModelFromJson(json);
|
||||
|
||||
@override final bool isCreated;
|
||||
@override final SignUpResponseItemModel item;
|
||||
|
||||
/// Create a copy of SignUpResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$SignUpResponseModelCopyWith<_SignUpResponseModel> get copyWith => __$SignUpResponseModelCopyWithImpl<_SignUpResponseModel>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$SignUpResponseModelToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SignUpResponseModel&&(identical(other.isCreated, isCreated) || other.isCreated == isCreated)&&(identical(other.item, item) || other.item == item));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,isCreated,item);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SignUpResponseModel(isCreated: $isCreated, item: $item)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$SignUpResponseModelCopyWith<$Res> implements $SignUpResponseModelCopyWith<$Res> {
|
||||
factory _$SignUpResponseModelCopyWith(_SignUpResponseModel value, $Res Function(_SignUpResponseModel) _then) = __$SignUpResponseModelCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
bool isCreated, SignUpResponseItemModel item
|
||||
});
|
||||
|
||||
|
||||
@override $SignUpResponseItemModelCopyWith<$Res> get item;
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$SignUpResponseModelCopyWithImpl<$Res>
|
||||
implements _$SignUpResponseModelCopyWith<$Res> {
|
||||
__$SignUpResponseModelCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _SignUpResponseModel _self;
|
||||
final $Res Function(_SignUpResponseModel) _then;
|
||||
|
||||
/// Create a copy of SignUpResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? isCreated = null,Object? item = null,}) {
|
||||
return _then(_SignUpResponseModel(
|
||||
isCreated: null == isCreated ? _self.isCreated : isCreated // ignore: cast_nullable_to_non_nullable
|
||||
as bool,item: null == item ? _self.item : item // ignore: cast_nullable_to_non_nullable
|
||||
as SignUpResponseItemModel,
|
||||
));
|
||||
}
|
||||
|
||||
/// Create a copy of SignUpResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$SignUpResponseItemModelCopyWith<$Res> get item {
|
||||
|
||||
return $SignUpResponseItemModelCopyWith<$Res>(_self.item, (value) {
|
||||
return _then(_self.copyWith(item: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// @nodoc
|
||||
mixin _$SignUpResponseItemModel {
|
||||
|
||||
String get token;
|
||||
/// Create a copy of SignUpResponseItemModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$SignUpResponseItemModelCopyWith<SignUpResponseItemModel> get copyWith => _$SignUpResponseItemModelCopyWithImpl<SignUpResponseItemModel>(this as SignUpResponseItemModel, _$identity);
|
||||
|
||||
/// Serializes this SignUpResponseItemModel to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SignUpResponseItemModel&&(identical(other.token, token) || other.token == token));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,token);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SignUpResponseItemModel(token: $token)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $SignUpResponseItemModelCopyWith<$Res> {
|
||||
factory $SignUpResponseItemModelCopyWith(SignUpResponseItemModel value, $Res Function(SignUpResponseItemModel) _then) = _$SignUpResponseItemModelCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String token
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$SignUpResponseItemModelCopyWithImpl<$Res>
|
||||
implements $SignUpResponseItemModelCopyWith<$Res> {
|
||||
_$SignUpResponseItemModelCopyWithImpl(this._self, this._then);
|
||||
|
||||
final SignUpResponseItemModel _self;
|
||||
final $Res Function(SignUpResponseItemModel) _then;
|
||||
|
||||
/// Create a copy of SignUpResponseItemModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? token = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
token: null == token ? _self.token : token // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [SignUpResponseItemModel].
|
||||
extension SignUpResponseItemModelPatterns on SignUpResponseItemModel {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _SignUpResponseItemModel value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpResponseItemModel() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _SignUpResponseItemModel value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpResponseItemModel():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _SignUpResponseItemModel value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpResponseItemModel() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String token)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpResponseItemModel() when $default != null:
|
||||
return $default(_that.token);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String token) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpResponseItemModel():
|
||||
return $default(_that.token);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String token)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpResponseItemModel() when $default != null:
|
||||
return $default(_that.token);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _SignUpResponseItemModel implements SignUpResponseItemModel {
|
||||
const _SignUpResponseItemModel({required this.token});
|
||||
factory _SignUpResponseItemModel.fromJson(Map<String, dynamic> json) => _$SignUpResponseItemModelFromJson(json);
|
||||
|
||||
@override final String token;
|
||||
|
||||
/// Create a copy of SignUpResponseItemModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$SignUpResponseItemModelCopyWith<_SignUpResponseItemModel> get copyWith => __$SignUpResponseItemModelCopyWithImpl<_SignUpResponseItemModel>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$SignUpResponseItemModelToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SignUpResponseItemModel&&(identical(other.token, token) || other.token == token));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,token);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SignUpResponseItemModel(token: $token)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$SignUpResponseItemModelCopyWith<$Res> implements $SignUpResponseItemModelCopyWith<$Res> {
|
||||
factory _$SignUpResponseItemModelCopyWith(_SignUpResponseItemModel value, $Res Function(_SignUpResponseItemModel) _then) = __$SignUpResponseItemModelCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String token
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$SignUpResponseItemModelCopyWithImpl<$Res>
|
||||
implements _$SignUpResponseItemModelCopyWith<$Res> {
|
||||
__$SignUpResponseItemModelCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _SignUpResponseItemModel _self;
|
||||
final $Res Function(_SignUpResponseItemModel) _then;
|
||||
|
||||
/// Create a copy of SignUpResponseItemModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? token = null,}) {
|
||||
return _then(_SignUpResponseItemModel(
|
||||
token: null == token ? _self.token : token // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,27 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'sign_up_response_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_SignUpResponseModel _$SignUpResponseModelFromJson(Map<String, dynamic> json) =>
|
||||
_SignUpResponseModel(
|
||||
isCreated: json['isCreated'] as bool,
|
||||
item: SignUpResponseItemModel.fromJson(
|
||||
json['item'] as Map<String, dynamic>,
|
||||
),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$SignUpResponseModelToJson(
|
||||
_SignUpResponseModel instance,
|
||||
) => <String, dynamic>{'isCreated': instance.isCreated, 'item': instance.item};
|
||||
|
||||
_SignUpResponseItemModel _$SignUpResponseItemModelFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _SignUpResponseItemModel(token: json['token'] as String);
|
||||
|
||||
Map<String, dynamic> _$SignUpResponseItemModelToJson(
|
||||
_SignUpResponseItemModel instance,
|
||||
) => <String, dynamic>{'token': instance.token};
|
||||
@@ -0,0 +1,37 @@
|
||||
import 'package:auth/src/features/sign_up/domain/entities/two_fa_secret_entity.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'two_fa_secret_response_model.freezed.dart';
|
||||
part 'two_fa_secret_response_model.g.dart';
|
||||
|
||||
@freezed
|
||||
abstract class TwoFASecretResponseModel with _$TwoFASecretResponseModel {
|
||||
const factory TwoFASecretResponseModel({
|
||||
required bool isCreated,
|
||||
required TwoFASecretItemResponseModel item,
|
||||
}) = _TwoFASecretResponseModel;
|
||||
|
||||
factory TwoFASecretResponseModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$TwoFASecretResponseModelFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class TwoFASecretItemResponseModel
|
||||
with _$TwoFASecretItemResponseModel {
|
||||
const factory TwoFASecretItemResponseModel({
|
||||
required String secret,
|
||||
required String qr,
|
||||
}) = _TwoFASecretItemResponseModel;
|
||||
|
||||
factory TwoFASecretItemResponseModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$TwoFASecretItemResponseModelFromJson(json);
|
||||
}
|
||||
|
||||
extension TwoFASecretResponseModelMapper on TwoFASecretResponseModel {
|
||||
TwoFASecretEntity toEntity() {
|
||||
return TwoFASecretEntity(
|
||||
isCreated: isCreated,
|
||||
item: TwoFASecretItemEntity(secret: item.secret, qr: item.qr),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,564 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'two_fa_secret_response_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
/// @nodoc
|
||||
mixin _$TwoFASecretResponseModel {
|
||||
|
||||
bool get isCreated; TwoFASecretItemResponseModel get item;
|
||||
/// Create a copy of TwoFASecretResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$TwoFASecretResponseModelCopyWith<TwoFASecretResponseModel> get copyWith => _$TwoFASecretResponseModelCopyWithImpl<TwoFASecretResponseModel>(this as TwoFASecretResponseModel, _$identity);
|
||||
|
||||
/// Serializes this TwoFASecretResponseModel to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is TwoFASecretResponseModel&&(identical(other.isCreated, isCreated) || other.isCreated == isCreated)&&(identical(other.item, item) || other.item == item));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,isCreated,item);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'TwoFASecretResponseModel(isCreated: $isCreated, item: $item)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $TwoFASecretResponseModelCopyWith<$Res> {
|
||||
factory $TwoFASecretResponseModelCopyWith(TwoFASecretResponseModel value, $Res Function(TwoFASecretResponseModel) _then) = _$TwoFASecretResponseModelCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
bool isCreated, TwoFASecretItemResponseModel item
|
||||
});
|
||||
|
||||
|
||||
$TwoFASecretItemResponseModelCopyWith<$Res> get item;
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$TwoFASecretResponseModelCopyWithImpl<$Res>
|
||||
implements $TwoFASecretResponseModelCopyWith<$Res> {
|
||||
_$TwoFASecretResponseModelCopyWithImpl(this._self, this._then);
|
||||
|
||||
final TwoFASecretResponseModel _self;
|
||||
final $Res Function(TwoFASecretResponseModel) _then;
|
||||
|
||||
/// Create a copy of TwoFASecretResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? isCreated = null,Object? item = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
isCreated: null == isCreated ? _self.isCreated : isCreated // ignore: cast_nullable_to_non_nullable
|
||||
as bool,item: null == item ? _self.item : item // ignore: cast_nullable_to_non_nullable
|
||||
as TwoFASecretItemResponseModel,
|
||||
));
|
||||
}
|
||||
/// Create a copy of TwoFASecretResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$TwoFASecretItemResponseModelCopyWith<$Res> get item {
|
||||
|
||||
return $TwoFASecretItemResponseModelCopyWith<$Res>(_self.item, (value) {
|
||||
return _then(_self.copyWith(item: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [TwoFASecretResponseModel].
|
||||
extension TwoFASecretResponseModelPatterns on TwoFASecretResponseModel {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _TwoFASecretResponseModel value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretResponseModel() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _TwoFASecretResponseModel value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretResponseModel():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _TwoFASecretResponseModel value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretResponseModel() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool isCreated, TwoFASecretItemResponseModel item)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretResponseModel() when $default != null:
|
||||
return $default(_that.isCreated,_that.item);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool isCreated, TwoFASecretItemResponseModel item) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretResponseModel():
|
||||
return $default(_that.isCreated,_that.item);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool isCreated, TwoFASecretItemResponseModel item)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretResponseModel() when $default != null:
|
||||
return $default(_that.isCreated,_that.item);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _TwoFASecretResponseModel implements TwoFASecretResponseModel {
|
||||
const _TwoFASecretResponseModel({required this.isCreated, required this.item});
|
||||
factory _TwoFASecretResponseModel.fromJson(Map<String, dynamic> json) => _$TwoFASecretResponseModelFromJson(json);
|
||||
|
||||
@override final bool isCreated;
|
||||
@override final TwoFASecretItemResponseModel item;
|
||||
|
||||
/// Create a copy of TwoFASecretResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$TwoFASecretResponseModelCopyWith<_TwoFASecretResponseModel> get copyWith => __$TwoFASecretResponseModelCopyWithImpl<_TwoFASecretResponseModel>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$TwoFASecretResponseModelToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _TwoFASecretResponseModel&&(identical(other.isCreated, isCreated) || other.isCreated == isCreated)&&(identical(other.item, item) || other.item == item));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,isCreated,item);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'TwoFASecretResponseModel(isCreated: $isCreated, item: $item)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$TwoFASecretResponseModelCopyWith<$Res> implements $TwoFASecretResponseModelCopyWith<$Res> {
|
||||
factory _$TwoFASecretResponseModelCopyWith(_TwoFASecretResponseModel value, $Res Function(_TwoFASecretResponseModel) _then) = __$TwoFASecretResponseModelCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
bool isCreated, TwoFASecretItemResponseModel item
|
||||
});
|
||||
|
||||
|
||||
@override $TwoFASecretItemResponseModelCopyWith<$Res> get item;
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$TwoFASecretResponseModelCopyWithImpl<$Res>
|
||||
implements _$TwoFASecretResponseModelCopyWith<$Res> {
|
||||
__$TwoFASecretResponseModelCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _TwoFASecretResponseModel _self;
|
||||
final $Res Function(_TwoFASecretResponseModel) _then;
|
||||
|
||||
/// Create a copy of TwoFASecretResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? isCreated = null,Object? item = null,}) {
|
||||
return _then(_TwoFASecretResponseModel(
|
||||
isCreated: null == isCreated ? _self.isCreated : isCreated // ignore: cast_nullable_to_non_nullable
|
||||
as bool,item: null == item ? _self.item : item // ignore: cast_nullable_to_non_nullable
|
||||
as TwoFASecretItemResponseModel,
|
||||
));
|
||||
}
|
||||
|
||||
/// Create a copy of TwoFASecretResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$TwoFASecretItemResponseModelCopyWith<$Res> get item {
|
||||
|
||||
return $TwoFASecretItemResponseModelCopyWith<$Res>(_self.item, (value) {
|
||||
return _then(_self.copyWith(item: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// @nodoc
|
||||
mixin _$TwoFASecretItemResponseModel {
|
||||
|
||||
String get secret; String get qr;
|
||||
/// Create a copy of TwoFASecretItemResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$TwoFASecretItemResponseModelCopyWith<TwoFASecretItemResponseModel> get copyWith => _$TwoFASecretItemResponseModelCopyWithImpl<TwoFASecretItemResponseModel>(this as TwoFASecretItemResponseModel, _$identity);
|
||||
|
||||
/// Serializes this TwoFASecretItemResponseModel to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is TwoFASecretItemResponseModel&&(identical(other.secret, secret) || other.secret == secret)&&(identical(other.qr, qr) || other.qr == qr));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,secret,qr);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'TwoFASecretItemResponseModel(secret: $secret, qr: $qr)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $TwoFASecretItemResponseModelCopyWith<$Res> {
|
||||
factory $TwoFASecretItemResponseModelCopyWith(TwoFASecretItemResponseModel value, $Res Function(TwoFASecretItemResponseModel) _then) = _$TwoFASecretItemResponseModelCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String secret, String qr
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$TwoFASecretItemResponseModelCopyWithImpl<$Res>
|
||||
implements $TwoFASecretItemResponseModelCopyWith<$Res> {
|
||||
_$TwoFASecretItemResponseModelCopyWithImpl(this._self, this._then);
|
||||
|
||||
final TwoFASecretItemResponseModel _self;
|
||||
final $Res Function(TwoFASecretItemResponseModel) _then;
|
||||
|
||||
/// Create a copy of TwoFASecretItemResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? secret = null,Object? qr = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
secret: null == secret ? _self.secret : secret // ignore: cast_nullable_to_non_nullable
|
||||
as String,qr: null == qr ? _self.qr : qr // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [TwoFASecretItemResponseModel].
|
||||
extension TwoFASecretItemResponseModelPatterns on TwoFASecretItemResponseModel {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _TwoFASecretItemResponseModel value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretItemResponseModel() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _TwoFASecretItemResponseModel value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretItemResponseModel():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _TwoFASecretItemResponseModel value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretItemResponseModel() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String secret, String qr)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretItemResponseModel() when $default != null:
|
||||
return $default(_that.secret,_that.qr);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String secret, String qr) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretItemResponseModel():
|
||||
return $default(_that.secret,_that.qr);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String secret, String qr)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretItemResponseModel() when $default != null:
|
||||
return $default(_that.secret,_that.qr);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _TwoFASecretItemResponseModel implements TwoFASecretItemResponseModel {
|
||||
const _TwoFASecretItemResponseModel({required this.secret, required this.qr});
|
||||
factory _TwoFASecretItemResponseModel.fromJson(Map<String, dynamic> json) => _$TwoFASecretItemResponseModelFromJson(json);
|
||||
|
||||
@override final String secret;
|
||||
@override final String qr;
|
||||
|
||||
/// Create a copy of TwoFASecretItemResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$TwoFASecretItemResponseModelCopyWith<_TwoFASecretItemResponseModel> get copyWith => __$TwoFASecretItemResponseModelCopyWithImpl<_TwoFASecretItemResponseModel>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$TwoFASecretItemResponseModelToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _TwoFASecretItemResponseModel&&(identical(other.secret, secret) || other.secret == secret)&&(identical(other.qr, qr) || other.qr == qr));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,secret,qr);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'TwoFASecretItemResponseModel(secret: $secret, qr: $qr)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$TwoFASecretItemResponseModelCopyWith<$Res> implements $TwoFASecretItemResponseModelCopyWith<$Res> {
|
||||
factory _$TwoFASecretItemResponseModelCopyWith(_TwoFASecretItemResponseModel value, $Res Function(_TwoFASecretItemResponseModel) _then) = __$TwoFASecretItemResponseModelCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String secret, String qr
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$TwoFASecretItemResponseModelCopyWithImpl<$Res>
|
||||
implements _$TwoFASecretItemResponseModelCopyWith<$Res> {
|
||||
__$TwoFASecretItemResponseModelCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _TwoFASecretItemResponseModel _self;
|
||||
final $Res Function(_TwoFASecretItemResponseModel) _then;
|
||||
|
||||
/// Create a copy of TwoFASecretItemResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? secret = null,Object? qr = null,}) {
|
||||
return _then(_TwoFASecretItemResponseModel(
|
||||
secret: null == secret ? _self.secret : secret // ignore: cast_nullable_to_non_nullable
|
||||
as String,qr: null == qr ? _self.qr : qr // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,31 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'two_fa_secret_response_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_TwoFASecretResponseModel _$TwoFASecretResponseModelFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _TwoFASecretResponseModel(
|
||||
isCreated: json['isCreated'] as bool,
|
||||
item: TwoFASecretItemResponseModel.fromJson(
|
||||
json['item'] as Map<String, dynamic>,
|
||||
),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$TwoFASecretResponseModelToJson(
|
||||
_TwoFASecretResponseModel instance,
|
||||
) => <String, dynamic>{'isCreated': instance.isCreated, 'item': instance.item};
|
||||
|
||||
_TwoFASecretItemResponseModel _$TwoFASecretItemResponseModelFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _TwoFASecretItemResponseModel(
|
||||
secret: json['secret'] as String,
|
||||
qr: json['qr'] as String,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$TwoFASecretItemResponseModelToJson(
|
||||
_TwoFASecretItemResponseModel instance,
|
||||
) => <String, dynamic>{'secret': instance.secret, 'qr': instance.qr};
|
||||
@@ -0,0 +1,48 @@
|
||||
import 'package:auth/src/core/data/datasource/auth_remote_datasource.dart';
|
||||
import 'package:auth/src/core/domain/repositories/auth_repository.dart';
|
||||
import 'package:auth/src/features/sign_up/domain/entities/sign_up_request_entity.dart';
|
||||
import 'package:auth/src/features/sign_up/domain/entities/two_fa_secret_entity.dart';
|
||||
|
||||
class AuthRepositoryImpl implements AuthRepository {
|
||||
const AuthRepositoryImpl(this._remote);
|
||||
|
||||
final AuthRemoteDatasource _remote;
|
||||
|
||||
@override
|
||||
Future<void> requestPhoneCode({required String phone}) {
|
||||
return _remote.requestPhoneCode(phone: phone);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> verifyPhoneCode({required String phone, required String code}) {
|
||||
return _remote.verifyPhoneCode(phone: phone, code: code);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> login({required String email, required String password}) {
|
||||
return _remote.login(email: email, password: password);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> twoFactor({required String token, required String code}) {
|
||||
return _remote.twoFALogin(token: token, code: code);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> signUp({required SignUpRequestEntity request}) {
|
||||
return _remote.signUp(request: request);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<TwoFASecretEntity> generateTwoFASignUp({required String token}) {
|
||||
return _remote.generateTwoFASignUp(token: token);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> verifyTwoFACodeSignUp({
|
||||
required String token,
|
||||
required String code,
|
||||
}) {
|
||||
return _remote.verifyTwoFACodeSignUp(token: token, code: code);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import 'package:auth/src/features/sign_up/domain/entities/sign_up_request_entity.dart';
|
||||
import 'package:auth/src/features/sign_up/domain/entities/two_fa_secret_entity.dart';
|
||||
|
||||
abstract class AuthRepository {
|
||||
Future<void> requestPhoneCode({required String phone});
|
||||
|
||||
Future<void> verifyPhoneCode({required String phone, required String code});
|
||||
|
||||
Future<String> login({required String email, required String password});
|
||||
|
||||
Future<void> twoFactor({required String token, required String code});
|
||||
|
||||
Future<String> signUp({required SignUpRequestEntity request});
|
||||
|
||||
Future<TwoFASecretEntity> generateTwoFASignUp({required String token});
|
||||
Future<void> verifyTwoFACodeSignUp({
|
||||
required String token,
|
||||
required String code,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import 'package:auth/src/core/data/datasource/auth_remote_datasource.dart';
|
||||
import 'package:auth/src/core/data/datasource/auth_remote_datasource_impl.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
|
||||
final authRemoteDatasourceProvider = Provider<AuthRemoteDatasource>((ref) {
|
||||
final questiaRepository = getIt<QuestiaRepository>();
|
||||
return AuthRemoteDatasourceImpl(questiaRepository);
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
import 'package:auth/src/core/data/repositories/auth_repository_impl.dart';
|
||||
import 'package:auth/src/core/domain/repositories/auth_repository.dart';
|
||||
import 'package:auth/src/core/providers/auth_remote_datasource_provider.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
final authRepositoryProvider = Provider<AuthRepository>((ref) {
|
||||
final remote = ref.read(authRemoteDatasourceProvider);
|
||||
return AuthRepositoryImpl(remote);
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:auth/src/device_sign_up/device_signup_screen.dart';
|
||||
import 'package:auth/src/features/device_sign_up/device_signup_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
@@ -1,24 +1,25 @@
|
||||
import 'package:auth/auth.dart';
|
||||
import 'package:auth/src/device_sign_up/add_kid_screen.dart';
|
||||
import 'package:auth/src/device_sign_up/link_watch/link_watch_screen.dart';
|
||||
import 'package:auth/src/device_sign_up/link_watch/link_watch_previous_screen.dart';
|
||||
import 'package:auth/src/sign_up/account_created_screen.dart';
|
||||
import 'package:auth/src/features/device_sign_up/add_kid_screen.dart';
|
||||
import 'package:auth/src/features/device_sign_up/link_watch/link_watch_screen.dart';
|
||||
import 'package:auth/src/features/device_sign_up/link_watch/link_watch_previous_screen.dart';
|
||||
import 'package:auth/src/features/sign_up/presentation/screens/account_created_screen.dart';
|
||||
import 'package:auth/src/widgets/layouts/form_step_layout.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
|
||||
class DeviceSignupScreen extends ConsumerStatefulWidget{
|
||||
class DeviceSignupScreen extends ConsumerStatefulWidget {
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
const DeviceSignupScreen({super.key, required this.navigationContract});
|
||||
|
||||
@override
|
||||
ConsumerState<DeviceSignupScreen> createState() => DeviceSignupScreenState(navigationContract);
|
||||
ConsumerState<DeviceSignupScreen> createState() =>
|
||||
DeviceSignupScreenState(navigationContract);
|
||||
}
|
||||
|
||||
class DeviceSignupScreenState extends ConsumerState<DeviceSignupScreen>{
|
||||
class DeviceSignupScreenState extends ConsumerState<DeviceSignupScreen> {
|
||||
late int currentStep;
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
@@ -34,37 +35,46 @@ class DeviceSignupScreenState extends ConsumerState<DeviceSignupScreen>{
|
||||
return getSteps()[currentStep];
|
||||
}
|
||||
|
||||
List<Widget> getSteps(){
|
||||
List<Widget> getSteps() {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
|
||||
final continueBtn = Container(
|
||||
color: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
child: PrimaryButton(
|
||||
onPressed: ()=>{setState(() {
|
||||
currentStep++;
|
||||
})},
|
||||
onPressed: () => {
|
||||
setState(() {
|
||||
currentStep++;
|
||||
}),
|
||||
},
|
||||
text: "Continuar",
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary)
|
||||
)
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary),
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
return [
|
||||
AddKidScreen(nextStep: ()=>{setState(() {
|
||||
currentStep++;
|
||||
})}),
|
||||
AddKidScreen(
|
||||
nextStep: () => {
|
||||
setState(() {
|
||||
currentStep++;
|
||||
}),
|
||||
},
|
||||
),
|
||||
FormStepLayout(
|
||||
title: "Crea su perfil",
|
||||
subtitle: "Necesitamos estos datos para crear su cuenta y gestionar sus pagos y gastos",
|
||||
subtitle:
|
||||
"Necesitamos estos datos para crear su cuenta y gestionar sus pagos y gastos",
|
||||
currentStep: 1,
|
||||
numSteps: 3,
|
||||
body: [CreateProfileScreen()],
|
||||
footer: [Container(
|
||||
padding: EdgeInsets.all(24),
|
||||
color: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
child: continueBtn
|
||||
)],
|
||||
nextStep: ()=>{},
|
||||
previousStep: ()=>{}
|
||||
footer: [
|
||||
Container(
|
||||
padding: EdgeInsets.all(24),
|
||||
color: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
child: continueBtn,
|
||||
),
|
||||
],
|
||||
nextStep: () => {},
|
||||
previousStep: () => {},
|
||||
),
|
||||
FormStepLayout(
|
||||
title: "Vincula su correa y su reloj",
|
||||
@@ -72,28 +82,28 @@ class DeviceSignupScreenState extends ConsumerState<DeviceSignupScreen>{
|
||||
numSteps: 3,
|
||||
body: [LinkWatchPreviousScreen()],
|
||||
footer: [continueBtn],
|
||||
nextStep: ()=>{},
|
||||
previousStep: ()=>{}
|
||||
nextStep: () => {},
|
||||
previousStep: () => {},
|
||||
),
|
||||
FormStepLayout(
|
||||
title: "Vincula su correa\ny su reloj",
|
||||
currentStep: 2,
|
||||
numSteps: 3,
|
||||
body: [LinkWatchScreen(step:1)],
|
||||
body: [LinkWatchScreen(step: 1)],
|
||||
footer: [continueBtn],
|
||||
nextStep: ()=>{},
|
||||
previousStep: ()=>{}
|
||||
nextStep: () => {},
|
||||
previousStep: () => {},
|
||||
),
|
||||
FormStepLayout(
|
||||
title: "Vincula su correa\ny su reloj",
|
||||
currentStep: 2,
|
||||
numSteps: 3,
|
||||
body: [LinkWatchScreen(step:2)],
|
||||
body: [LinkWatchScreen(step: 2)],
|
||||
footer: [continueBtn],
|
||||
nextStep: ()=>{},
|
||||
previousStep: ()=>{}
|
||||
nextStep: () => {},
|
||||
previousStep: () => {},
|
||||
),
|
||||
AccountCreatedScreen(navigationContract: navigationContract, kidAccount: true)
|
||||
AccountCreatedScreen(navigationContract: navigationContract),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,16 +17,14 @@ class CreateProfileScreen extends ConsumerWidget {
|
||||
Text(
|
||||
"Comienza con un peque; luego podrás agregar más",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500, letterSpacing: 0),
|
||||
),
|
||||
CustomTextField(
|
||||
label: "Nombre",
|
||||
hint: "Nombre",
|
||||
),
|
||||
CustomTextField(
|
||||
label: "Apellidos",
|
||||
hint: "Apellidos",
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
letterSpacing: 0,
|
||||
),
|
||||
),
|
||||
CustomTextField(label: "Nombre", hint: "Nombre"),
|
||||
CustomTextField(label: "Apellidos", hint: "Apellidos"),
|
||||
Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
@@ -42,21 +40,21 @@ class CreateProfileScreen extends ConsumerWidget {
|
||||
children: [
|
||||
Expanded(
|
||||
child: CustomTextField(
|
||||
numeric: true,
|
||||
keyboardType: TextInputType.number,
|
||||
hint: "DD",
|
||||
length: 2,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: CustomTextField(
|
||||
numeric: true,
|
||||
keyboardType: TextInputType.number,
|
||||
hint: "MM",
|
||||
length: 2,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: CustomTextField(
|
||||
numeric: true,
|
||||
keyboardType: TextInputType.number,
|
||||
hint: "AAAA",
|
||||
length: 4,
|
||||
),
|
||||
@@ -77,7 +75,7 @@ class CreateProfileScreen extends ConsumerWidget {
|
||||
size: 18,
|
||||
weight: FontWeight.w500,
|
||||
),
|
||||
)
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
abstract class LinkPhoneUseCase {
|
||||
Future<void> requestCode({required String phone});
|
||||
|
||||
Future<void> verifyCode({required String phone, required String code});
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import 'package:auth/src/core/domain/repositories/auth_repository.dart';
|
||||
import 'package:auth/src/features/link_phone/domain/use_cases/link_phone_use_case.dart';
|
||||
|
||||
class LinkPhoneUseCaseImpl implements LinkPhoneUseCase {
|
||||
LinkPhoneUseCaseImpl(this._repository);
|
||||
|
||||
final AuthRepository _repository;
|
||||
|
||||
@override
|
||||
Future<void> requestCode({required String phone}) async {
|
||||
// return _repository.requestPhoneCode(phone: phone);
|
||||
await Future<void>.delayed(const Duration(milliseconds: 500));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> verifyCode({required String phone, required String code}) async {
|
||||
// return _repository.verifyPhoneCode(phone: phone, code: code);
|
||||
await Future<void>.delayed(const Duration(milliseconds: 500));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import 'package:auth/src/core/providers/auth_repository_provider.dart';
|
||||
import 'package:auth/src/features/link_phone/domain/use_cases/link_phone_use_case.dart';
|
||||
import 'package:auth/src/features/link_phone/domain/use_cases/link_phone_use_case_impl.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
final linkPhoneUseCaseProvider = Provider.autoDispose<LinkPhoneUseCase>((ref) {
|
||||
final authRepository = ref.read(authRepositoryProvider);
|
||||
return LinkPhoneUseCaseImpl(authRepository);
|
||||
});
|
||||
@@ -1,18 +1,18 @@
|
||||
import 'package:auth/src/login/presentation/link_phone_screen.dart';
|
||||
import 'package:auth/src/features/link_phone/presentation/request_phone/request_link_phone_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
|
||||
class LinkPhoneBuilder {
|
||||
const LinkPhoneBuilder();
|
||||
class RequestLinkPhoneBuilder {
|
||||
const RequestLinkPhoneBuilder();
|
||||
|
||||
Page<void> buildPage(BuildContext context, GoRouterState state) {
|
||||
final NavigationContract navigationContract = GetIt.I<NavigationContract>();
|
||||
|
||||
return MaterialPage<void>(
|
||||
key: state.pageKey,
|
||||
child: LinkPhoneScreen(navigationContract: navigationContract),
|
||||
child: RequestLinkPhoneScreen(navigationContract: navigationContract),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
import 'package:auth/src/features/link_phone/presentation/state/link_phone_view_model.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
|
||||
class RequestLinkPhoneScreen extends ConsumerWidget {
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
const RequestLinkPhoneScreen({super.key, required this.navigationContract});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
|
||||
final viewModel = ref.read(linkPhoneViewModelProvider.notifier);
|
||||
final viewState = ref.watch(linkPhoneViewModelProvider);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
context.translate(I18n.linkPhoneTitle),
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
fontSize: 30,
|
||||
fontWeight: FontWeight.w500,
|
||||
letterSpacing: 0,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
Text(
|
||||
context.translate(I18n.linkPhoneSubtitle),
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(fontSize: 16, letterSpacing: 0),
|
||||
),
|
||||
const SizedBox(height: 48),
|
||||
|
||||
Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Align(
|
||||
alignment: Alignment.bottomLeft,
|
||||
child: Text(
|
||||
context.translate(I18n.mobilePhone),
|
||||
style: const TextStyle(fontSize: 14, letterSpacing: 0),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
spacing: 10,
|
||||
children: [
|
||||
CountryPrefixPicker(
|
||||
headerText: context.translate(I18n.selectYourCountry),
|
||||
initialCountryCode: viewState.dialCode,
|
||||
onChanged: (country) {
|
||||
viewModel.updateDialCode(
|
||||
country.dialCode ?? viewState.dialCode,
|
||||
);
|
||||
},
|
||||
),
|
||||
Expanded(
|
||||
child: CustomTextField(
|
||||
controller: viewModel.phoneNumberController,
|
||||
hint: context.translate(I18n.phoneNumber),
|
||||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 16),
|
||||
|
||||
if (viewState.errorMessage.isNotEmpty) ...[
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
viewState.errorMessage,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
color: Color.fromRGBO(239, 17, 17, 1),
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
const SizedBox(height: 24),
|
||||
|
||||
PrimaryButton(
|
||||
onPressed: () async {
|
||||
await viewModel.requestCode();
|
||||
final updatedState = ref.read(linkPhoneViewModelProvider);
|
||||
if (updatedState.errorMessage.isEmpty) {
|
||||
navigationContract.pushTo(AppRoutes.phoneCode);
|
||||
}
|
||||
},
|
||||
text: context.translate(I18n.next),
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
import 'package:auth/src/features/link_phone/presentation/providers/link_phone_provider.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:auth/src/features/link_phone/domain/use_cases/link_phone_use_case.dart';
|
||||
import 'package:auth/src/features/link_phone/presentation/state/link_phone_view_state.dart';
|
||||
|
||||
final linkPhoneViewModelProvider =
|
||||
NotifierProvider.autoDispose<LinkPhoneViewModel, LinkPhoneViewState>(
|
||||
LinkPhoneViewModel.new,
|
||||
);
|
||||
|
||||
class LinkPhoneViewModel extends Notifier<LinkPhoneViewState> {
|
||||
late final LinkPhoneUseCase _linkPhoneUseCase;
|
||||
late final TextEditingController phoneNumberController;
|
||||
late final TextEditingController codeController;
|
||||
|
||||
@override
|
||||
LinkPhoneViewState build() {
|
||||
_linkPhoneUseCase = ref.read(linkPhoneUseCaseProvider);
|
||||
|
||||
phoneNumberController = TextEditingController();
|
||||
phoneNumberController.addListener(_onPhoneNumberChanged);
|
||||
|
||||
codeController = TextEditingController();
|
||||
|
||||
ref.onDispose(disposeControllers);
|
||||
|
||||
return const LinkPhoneViewState();
|
||||
}
|
||||
|
||||
void _onPhoneNumberChanged() {
|
||||
final raw = phoneNumberController.text;
|
||||
state = state.copyWith(
|
||||
phoneNumber: raw,
|
||||
errorMessage: '',
|
||||
codeVerified: false,
|
||||
);
|
||||
}
|
||||
|
||||
void updateDialCode(String dialCode) {
|
||||
state = state.copyWith(
|
||||
dialCode: dialCode,
|
||||
errorMessage: '',
|
||||
codeVerified: false,
|
||||
);
|
||||
}
|
||||
|
||||
void updateCode(String code) {
|
||||
codeController.text = code;
|
||||
state = state.copyWith(errorMessage: '', codeVerified: false);
|
||||
}
|
||||
|
||||
Future<void> requestCode() async {
|
||||
final trimmedNumber = state.phoneNumber.trim();
|
||||
|
||||
if (trimmedNumber.isEmpty) {
|
||||
state = state.copyWith(
|
||||
errorMessage: 'errorMessagePhoneIsEmpty',
|
||||
codeVerified: false,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final fullPhone = '${state.dialCode}$trimmedNumber';
|
||||
|
||||
state = state.copyWith(
|
||||
isLoading: true,
|
||||
errorMessage: '',
|
||||
codeRequested: false,
|
||||
codeVerified: false,
|
||||
);
|
||||
|
||||
try {
|
||||
await _linkPhoneUseCase.requestCode(phone: fullPhone);
|
||||
if (!ref.mounted) return;
|
||||
|
||||
state = state.copyWith(
|
||||
isLoading: false,
|
||||
errorMessage: '',
|
||||
codeRequested: true,
|
||||
);
|
||||
} catch (e) {
|
||||
if (!ref.mounted) return;
|
||||
|
||||
state = state.copyWith(
|
||||
isLoading: false,
|
||||
errorMessage: e.toString(),
|
||||
codeRequested: false,
|
||||
codeVerified: false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> verifyCode() async {
|
||||
final dialCode = state.dialCode;
|
||||
final phoneNumber = state.phoneNumber.trim();
|
||||
final code = codeController.text.trim();
|
||||
final fullPhone = '$dialCode$phoneNumber';
|
||||
|
||||
if (phoneNumber.isEmpty) {
|
||||
state = state.copyWith(
|
||||
errorMessage: 'errorMessagePhoneIsEmpty',
|
||||
codeVerified: false,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (code.isEmpty) {
|
||||
state = state.copyWith(
|
||||
errorMessage: 'errorMessageCodeIsEmpty',
|
||||
codeVerified: false,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
state = state.copyWith(
|
||||
isLoading: true,
|
||||
errorMessage: '',
|
||||
codeVerified: false,
|
||||
);
|
||||
|
||||
try {
|
||||
await _linkPhoneUseCase.verifyCode(phone: fullPhone, code: code);
|
||||
if (!ref.mounted) return;
|
||||
|
||||
state = state.copyWith(
|
||||
isLoading: false,
|
||||
errorMessage: '',
|
||||
codeVerified: true,
|
||||
);
|
||||
} catch (e) {
|
||||
if (!ref.mounted) return;
|
||||
|
||||
state = state.copyWith(
|
||||
isLoading: false,
|
||||
errorMessage: e.toString(),
|
||||
codeVerified: false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void disposeControllers() {
|
||||
phoneNumberController.removeListener(_onPhoneNumberChanged);
|
||||
phoneNumberController.dispose();
|
||||
codeController.dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'link_phone_view_state.freezed.dart';
|
||||
|
||||
@freezed
|
||||
abstract class LinkPhoneViewState with _$LinkPhoneViewState {
|
||||
const factory LinkPhoneViewState({
|
||||
@Default('') String phoneNumber,
|
||||
@Default('+34') String dialCode,
|
||||
@Default('') String errorMessage,
|
||||
@Default(false) bool isLoading,
|
||||
@Default(false) bool codeRequested,
|
||||
@Default(false) bool codeVerified,
|
||||
}) = _LinkPhoneViewState;
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'link_phone_view_state.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$LinkPhoneViewState {
|
||||
|
||||
String get phoneNumber; String get dialCode; String get errorMessage; bool get isLoading; bool get codeRequested; bool get codeVerified;
|
||||
/// Create a copy of LinkPhoneViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$LinkPhoneViewStateCopyWith<LinkPhoneViewState> get copyWith => _$LinkPhoneViewStateCopyWithImpl<LinkPhoneViewState>(this as LinkPhoneViewState, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is LinkPhoneViewState&&(identical(other.phoneNumber, phoneNumber) || other.phoneNumber == phoneNumber)&&(identical(other.dialCode, dialCode) || other.dialCode == dialCode)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.codeRequested, codeRequested) || other.codeRequested == codeRequested)&&(identical(other.codeVerified, codeVerified) || other.codeVerified == codeVerified));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,phoneNumber,dialCode,errorMessage,isLoading,codeRequested,codeVerified);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'LinkPhoneViewState(phoneNumber: $phoneNumber, dialCode: $dialCode, errorMessage: $errorMessage, isLoading: $isLoading, codeRequested: $codeRequested, codeVerified: $codeVerified)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $LinkPhoneViewStateCopyWith<$Res> {
|
||||
factory $LinkPhoneViewStateCopyWith(LinkPhoneViewState value, $Res Function(LinkPhoneViewState) _then) = _$LinkPhoneViewStateCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String phoneNumber, String dialCode, String errorMessage, bool isLoading, bool codeRequested, bool codeVerified
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$LinkPhoneViewStateCopyWithImpl<$Res>
|
||||
implements $LinkPhoneViewStateCopyWith<$Res> {
|
||||
_$LinkPhoneViewStateCopyWithImpl(this._self, this._then);
|
||||
|
||||
final LinkPhoneViewState _self;
|
||||
final $Res Function(LinkPhoneViewState) _then;
|
||||
|
||||
/// Create a copy of LinkPhoneViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? phoneNumber = null,Object? dialCode = null,Object? errorMessage = null,Object? isLoading = null,Object? codeRequested = null,Object? codeVerified = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
phoneNumber: null == phoneNumber ? _self.phoneNumber : phoneNumber // ignore: cast_nullable_to_non_nullable
|
||||
as String,dialCode: null == dialCode ? _self.dialCode : dialCode // ignore: cast_nullable_to_non_nullable
|
||||
as String,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
||||
as String,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,codeRequested: null == codeRequested ? _self.codeRequested : codeRequested // ignore: cast_nullable_to_non_nullable
|
||||
as bool,codeVerified: null == codeVerified ? _self.codeVerified : codeVerified // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [LinkPhoneViewState].
|
||||
extension LinkPhoneViewStatePatterns on LinkPhoneViewState {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _LinkPhoneViewState value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _LinkPhoneViewState() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _LinkPhoneViewState value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _LinkPhoneViewState():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _LinkPhoneViewState value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _LinkPhoneViewState() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String phoneNumber, String dialCode, String errorMessage, bool isLoading, bool codeRequested, bool codeVerified)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _LinkPhoneViewState() when $default != null:
|
||||
return $default(_that.phoneNumber,_that.dialCode,_that.errorMessage,_that.isLoading,_that.codeRequested,_that.codeVerified);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String phoneNumber, String dialCode, String errorMessage, bool isLoading, bool codeRequested, bool codeVerified) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _LinkPhoneViewState():
|
||||
return $default(_that.phoneNumber,_that.dialCode,_that.errorMessage,_that.isLoading,_that.codeRequested,_that.codeVerified);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String phoneNumber, String dialCode, String errorMessage, bool isLoading, bool codeRequested, bool codeVerified)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _LinkPhoneViewState() when $default != null:
|
||||
return $default(_that.phoneNumber,_that.dialCode,_that.errorMessage,_that.isLoading,_that.codeRequested,_that.codeVerified);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _LinkPhoneViewState implements LinkPhoneViewState {
|
||||
const _LinkPhoneViewState({this.phoneNumber = '', this.dialCode = '+34', this.errorMessage = '', this.isLoading = false, this.codeRequested = false, this.codeVerified = false});
|
||||
|
||||
|
||||
@override@JsonKey() final String phoneNumber;
|
||||
@override@JsonKey() final String dialCode;
|
||||
@override@JsonKey() final String errorMessage;
|
||||
@override@JsonKey() final bool isLoading;
|
||||
@override@JsonKey() final bool codeRequested;
|
||||
@override@JsonKey() final bool codeVerified;
|
||||
|
||||
/// Create a copy of LinkPhoneViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$LinkPhoneViewStateCopyWith<_LinkPhoneViewState> get copyWith => __$LinkPhoneViewStateCopyWithImpl<_LinkPhoneViewState>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _LinkPhoneViewState&&(identical(other.phoneNumber, phoneNumber) || other.phoneNumber == phoneNumber)&&(identical(other.dialCode, dialCode) || other.dialCode == dialCode)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.codeRequested, codeRequested) || other.codeRequested == codeRequested)&&(identical(other.codeVerified, codeVerified) || other.codeVerified == codeVerified));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,phoneNumber,dialCode,errorMessage,isLoading,codeRequested,codeVerified);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'LinkPhoneViewState(phoneNumber: $phoneNumber, dialCode: $dialCode, errorMessage: $errorMessage, isLoading: $isLoading, codeRequested: $codeRequested, codeVerified: $codeVerified)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$LinkPhoneViewStateCopyWith<$Res> implements $LinkPhoneViewStateCopyWith<$Res> {
|
||||
factory _$LinkPhoneViewStateCopyWith(_LinkPhoneViewState value, $Res Function(_LinkPhoneViewState) _then) = __$LinkPhoneViewStateCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String phoneNumber, String dialCode, String errorMessage, bool isLoading, bool codeRequested, bool codeVerified
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$LinkPhoneViewStateCopyWithImpl<$Res>
|
||||
implements _$LinkPhoneViewStateCopyWith<$Res> {
|
||||
__$LinkPhoneViewStateCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _LinkPhoneViewState _self;
|
||||
final $Res Function(_LinkPhoneViewState) _then;
|
||||
|
||||
/// Create a copy of LinkPhoneViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? phoneNumber = null,Object? dialCode = null,Object? errorMessage = null,Object? isLoading = null,Object? codeRequested = null,Object? codeVerified = null,}) {
|
||||
return _then(_LinkPhoneViewState(
|
||||
phoneNumber: null == phoneNumber ? _self.phoneNumber : phoneNumber // ignore: cast_nullable_to_non_nullable
|
||||
as String,dialCode: null == dialCode ? _self.dialCode : dialCode // ignore: cast_nullable_to_non_nullable
|
||||
as String,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
||||
as String,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,codeRequested: null == codeRequested ? _self.codeRequested : codeRequested // ignore: cast_nullable_to_non_nullable
|
||||
as bool,codeVerified: null == codeVerified ? _self.codeVerified : codeVerified // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -1,18 +1,18 @@
|
||||
import 'package:auth/src/login/presentation/phone_code_screen.dart';
|
||||
import 'package:auth/src/features/link_phone/presentation/verify_code/verify_link_phone_code_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
|
||||
class PhoneCodeBuilder {
|
||||
const PhoneCodeBuilder();
|
||||
class VerifyLinkPhoneCodeBuilder {
|
||||
const VerifyLinkPhoneCodeBuilder();
|
||||
|
||||
Page<void> buildPage(BuildContext context, GoRouterState state) {
|
||||
final NavigationContract navigationContract = GetIt.I<NavigationContract>();
|
||||
|
||||
return MaterialPage<void>(
|
||||
key: state.pageKey,
|
||||
child: PhoneCodeScreen(navigationContract: navigationContract),
|
||||
child: VerifyLinkPhoneCodeScreen(navigationContract: navigationContract),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
import 'package:auth/src/features/link_phone/presentation/state/link_phone_view_model.dart';
|
||||
import 'package:auth/src/features/link_phone/presentation/widgets/link_phone_code_input.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
|
||||
class VerifyLinkPhoneCodeScreen extends ConsumerWidget {
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
const VerifyLinkPhoneCodeScreen({
|
||||
super.key,
|
||||
required this.navigationContract,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
|
||||
final viewModel = ref.read(linkPhoneViewModelProvider.notifier);
|
||||
final viewState = ref.watch(linkPhoneViewModelProvider);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 48,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
Text(
|
||||
context.translate(I18n.connect),
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
text: context.translate(I18n.verificationCodeSentTo),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: '${viewState.dialCode}${viewState.phoneNumber}',
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 48),
|
||||
Text(
|
||||
context.translate(I18n.enterCodeHere),
|
||||
style: TextStyle(fontSize: 16),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
LinkPhoneCodeInput(
|
||||
length: 6,
|
||||
onCodeChanged: viewModel.updateCode,
|
||||
),
|
||||
|
||||
if (viewState.errorMessage.isNotEmpty) ...[
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
viewState.errorMessage,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
color: Color.fromRGBO(239, 17, 17, 1),
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
PrimaryButton(
|
||||
onPressed: () async {
|
||||
await viewModel.verifyCode();
|
||||
final updatedState = ref.read(linkPhoneViewModelProvider);
|
||||
|
||||
if (updatedState.codeVerified) {
|
||||
navigationContract.pushTo(AppRoutes.login);
|
||||
}
|
||||
},
|
||||
text: context.translate(I18n.enter),
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
Text(
|
||||
context.translate(I18n.didNotReceiveIt),
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
letterSpacing: 0,
|
||||
height: 1.5,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
CustomTextButton(
|
||||
onPressed: () => navigationContract.goBack(),
|
||||
text: context.translate(I18n.tryAgain),
|
||||
size: 18,
|
||||
weight: FontWeight.w500,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class LinkPhoneCodeInput extends StatefulWidget {
|
||||
const LinkPhoneCodeInput({
|
||||
super.key,
|
||||
this.length = 6,
|
||||
required this.onCodeChanged,
|
||||
});
|
||||
|
||||
final int length;
|
||||
final ValueChanged<String> onCodeChanged;
|
||||
|
||||
@override
|
||||
State<LinkPhoneCodeInput> createState() => _LinkPhoneCodeInputState();
|
||||
}
|
||||
|
||||
class _LinkPhoneCodeInputState extends State<LinkPhoneCodeInput> {
|
||||
late final List<TextEditingController> _controllers;
|
||||
late final List<FocusNode> _focusNodes;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controllers = List<TextEditingController>.generate(
|
||||
widget.length,
|
||||
(_) => TextEditingController(),
|
||||
);
|
||||
_focusNodes = List<FocusNode>.generate(widget.length, (_) => FocusNode());
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
for (final controller in _controllers) {
|
||||
controller.dispose();
|
||||
}
|
||||
for (final node in _focusNodes) {
|
||||
node.dispose();
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _onDigitChanged(int index, String value) {
|
||||
if (value.length > 1) {
|
||||
final single = value.characters.last;
|
||||
_controllers[index].text = single;
|
||||
_controllers[index].selection = TextSelection.fromPosition(
|
||||
TextPosition(offset: single.length),
|
||||
);
|
||||
}
|
||||
|
||||
if (value.isNotEmpty && index < widget.length - 1) {
|
||||
_focusNodes[index + 1].requestFocus();
|
||||
} else if (value.isEmpty && index > 0) {
|
||||
_focusNodes[index - 1].requestFocus();
|
||||
}
|
||||
|
||||
final code = _controllers.map((c) => c.text).join();
|
||||
widget.onCodeChanged(code);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
spacing: 8,
|
||||
children: List<Widget>.generate(widget.length, (int i) {
|
||||
return Expanded(
|
||||
child: TextField(
|
||||
controller: _controllers[i],
|
||||
focusNode: _focusNodes[i],
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
||||
textAlign: TextAlign.center,
|
||||
decoration: const InputDecoration(
|
||||
hintText: '0',
|
||||
counterText: '',
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
maxLength: 1,
|
||||
onChanged: (value) => _onDigitChanged(i, value),
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
abstract class LoginUseCase {
|
||||
Future<String> login({required String email, required String password});
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import 'package:auth/src/core/domain/repositories/auth_repository.dart';
|
||||
import 'package:auth/src/features/login/domain/login_use_case.dart';
|
||||
|
||||
class LoginUseCaseImpl implements LoginUseCase {
|
||||
LoginUseCaseImpl(this._repository);
|
||||
|
||||
final AuthRepository _repository;
|
||||
|
||||
@override
|
||||
Future<String> login({required String email, required String password}) {
|
||||
return _repository.login(email: email, password: password);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
abstract class TwoFactorUseCase {
|
||||
Future<void> twoFactor({required String token, required String code});
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import 'package:auth/src/core/domain/repositories/auth_repository.dart';
|
||||
import 'package:auth/src/features/login/domain/two_factor_use_case.dart';
|
||||
|
||||
class TwoFactorUseCaseImpl implements TwoFactorUseCase {
|
||||
TwoFactorUseCaseImpl(this._repository);
|
||||
|
||||
final AuthRepository _repository;
|
||||
|
||||
@override
|
||||
Future<void> twoFactor({required String token, required String code}) {
|
||||
return _repository.twoFactor(token: token, code: code);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:auth/src/login/presentation/login_screen.dart';
|
||||
import 'package:auth/src/features/login/presentation/login_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
@@ -0,0 +1,408 @@
|
||||
import 'package:auth/src/features/login/presentation/loading_google_screen.dart';
|
||||
import 'package:auth/src/features/login/presentation/state/login_view_model.dart';
|
||||
import 'package:auth/src/features/login/presentation/widgets/two_factor_bottom_sheet.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
|
||||
class LoginScreen extends ConsumerWidget {
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
const LoginScreen({super.key, required this.navigationContract});
|
||||
|
||||
Future<void> _onLogIn(BuildContext context, WidgetRef ref) async {
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
|
||||
final vm = ref.read(loginViewModelProvider.notifier);
|
||||
|
||||
final String? token = await vm.login();
|
||||
if (!context.mounted) return;
|
||||
|
||||
if (token == null || token.isEmpty) return;
|
||||
|
||||
vm.prepareTwoFactor();
|
||||
|
||||
final bool? verified = await showModalBottomSheet<bool>(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
useSafeArea: true,
|
||||
isDismissible: false,
|
||||
enableDrag: false,
|
||||
backgroundColor: Colors.transparent,
|
||||
builder: (context) {
|
||||
return Consumer(
|
||||
builder: (context, ref, _) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
final vm = ref.read(loginViewModelProvider.notifier);
|
||||
|
||||
final otpErrorKey = ref.watch(
|
||||
loginViewModelProvider.select((s) => s.otpError),
|
||||
);
|
||||
final isOtpLoading = ref.watch(
|
||||
loginViewModelProvider.select((s) => s.isOtpLoading),
|
||||
);
|
||||
final otpCode = ref.watch(
|
||||
loginViewModelProvider.select((s) => s.otpCode),
|
||||
);
|
||||
|
||||
final otpErrorText = otpErrorKey.isEmpty
|
||||
? ''
|
||||
: context.translate(otpErrorKey);
|
||||
|
||||
Future<void> onVerify() async {
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
|
||||
final ok = await vm.twoFactor(token: token);
|
||||
if (!context.mounted) return;
|
||||
|
||||
if (ok) Navigator.of(context).pop(true);
|
||||
}
|
||||
|
||||
return TwoFactorBottomSheetView(
|
||||
theme: theme,
|
||||
title: context.translate(I18n.twoFactorTitle),
|
||||
subtitle: context.translate(I18n.twoFactorSubtitle),
|
||||
verifyText: context.translate(I18n.twoFactorVerify),
|
||||
closeText: context.translate(I18n.close),
|
||||
isOtpLoading: isOtpLoading,
|
||||
otpCode: otpCode,
|
||||
otpErrorText: otpErrorText,
|
||||
onChanged: vm.setOtpCode,
|
||||
onVerify: onVerify,
|
||||
onClose: () => Navigator.of(context).pop(false),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (!context.mounted) return;
|
||||
|
||||
if (verified == true) {
|
||||
navigationContract.goTo(AppRoutes.dashboardHome);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
final bool isLoading = ref.watch(
|
||||
loginViewModelProvider.select((s) => s.isLoading),
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
body: SafeArea(
|
||||
child: AbsorbPointer(
|
||||
absorbing: isLoading,
|
||||
child: SingleChildScrollView(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
_Header(theme: theme),
|
||||
SizedBox(height: 48),
|
||||
const _EmailSection(),
|
||||
SizedBox(height: 24),
|
||||
_PasswordSection(onSubmitted: () => _onLogIn(context, ref)),
|
||||
SizedBox(height: 16),
|
||||
_ForgotPassword(navigationContract: navigationContract),
|
||||
SizedBox(height: 30),
|
||||
_SignInSection(
|
||||
theme: theme,
|
||||
onSignIn: () => _onLogIn(context, ref),
|
||||
),
|
||||
SizedBox(height: 30),
|
||||
_OrContinueWith(theme: theme),
|
||||
SizedBox(height: 24),
|
||||
_SocialButtons(theme: theme),
|
||||
SizedBox(height: 30),
|
||||
_Footer(navigationContract: navigationContract),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _Header extends StatelessWidget {
|
||||
const _Header({required this.theme});
|
||||
final ThemePort theme;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.check,
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary),
|
||||
size: 54,
|
||||
),
|
||||
Text(
|
||||
context.translate(I18n.welcome),
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _EmailSection extends ConsumerWidget {
|
||||
const _EmailSection();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final vm = ref.read(loginViewModelProvider.notifier);
|
||||
final String emailErrorKey = ref.watch(
|
||||
loginViewModelProvider.select((s) => s.emailError),
|
||||
);
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
CustomTextField(
|
||||
hint: context.translate(I18n.username),
|
||||
label: context.translate(I18n.username),
|
||||
controller: vm.emailController,
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
textInputAction: TextInputAction.next,
|
||||
),
|
||||
_FieldErrorText.fromKey(errorKey: emailErrorKey),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _PasswordSection extends ConsumerWidget {
|
||||
const _PasswordSection({required this.onSubmitted});
|
||||
final Future<void> Function() onSubmitted;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final vm = ref.read(loginViewModelProvider.notifier);
|
||||
|
||||
final bool passwordVisible = ref.watch(
|
||||
loginViewModelProvider.select((s) => s.passwordVisible),
|
||||
);
|
||||
final String passwordErrorKey = ref.watch(
|
||||
loginViewModelProvider.select((s) => s.passwordError),
|
||||
);
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
CustomTextField(
|
||||
showPassword: passwordVisible,
|
||||
label: context.translate(I18n.password),
|
||||
hint: '********',
|
||||
controller: vm.passwordController,
|
||||
textInputAction: TextInputAction.done,
|
||||
onSubmitted: (_) => onSubmitted(),
|
||||
),
|
||||
_FieldErrorText.fromKey(errorKey: passwordErrorKey),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ForgotPassword extends ConsumerWidget {
|
||||
const _ForgotPassword({required this.navigationContract});
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final bool isLoading = ref.watch(
|
||||
loginViewModelProvider.select((s) => s.isLoading),
|
||||
);
|
||||
|
||||
return Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: CustomTextButton(
|
||||
text: context.translate(I18n.forgotPassword),
|
||||
onPressed: isLoading
|
||||
? () {}
|
||||
: () => navigationContract.pushTo(AppRoutes.recoverPassword),
|
||||
size: 16,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _SignInSection extends ConsumerWidget {
|
||||
const _SignInSection({required this.onSignIn, required this.theme});
|
||||
|
||||
final VoidCallback onSignIn;
|
||||
final ThemePort theme;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final bool isLoading = ref.watch(
|
||||
loginViewModelProvider.select((s) => s.isLoading),
|
||||
);
|
||||
final String errorMessage = ref.watch(
|
||||
loginViewModelProvider.select((s) => s.errorMessage),
|
||||
);
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
PrimaryButton(
|
||||
onPressed: isLoading ? () {} : onSignIn,
|
||||
text: context.translate(I18n.signIn),
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary),
|
||||
leading: isLoading
|
||||
? const SizedBox(
|
||||
height: 18,
|
||||
width: 18,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
color: Colors.white,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
if (errorMessage.isNotEmpty)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 12),
|
||||
child: Text(
|
||||
errorMessage,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _OrContinueWith extends StatelessWidget {
|
||||
const _OrContinueWith({required this.theme});
|
||||
final ThemePort theme;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
children: [
|
||||
const Divider(endIndent: 74, indent: 74),
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 14),
|
||||
color: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
child: Text(context.translate(I18n.orContinueWith)),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _SocialButtons extends ConsumerWidget {
|
||||
const _SocialButtons({required this.theme});
|
||||
final ThemePort theme;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final bool isLoading = ref.watch(
|
||||
loginViewModelProvider.select((s) => s.isLoading),
|
||||
);
|
||||
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SecondaryButton(
|
||||
onPressed: isLoading
|
||||
? () {}
|
||||
: () => Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (_) => const LoadingGoogleScreen(),
|
||||
),
|
||||
),
|
||||
radius: 16,
|
||||
padding: 44,
|
||||
text: context.translate(I18n.google),
|
||||
label: 'Google',
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
SecondaryButton(
|
||||
onPressed: isLoading ? () {} : () {},
|
||||
radius: 16,
|
||||
padding: 44,
|
||||
icon: Icons.apple,
|
||||
label: 'Apple',
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _Footer extends ConsumerWidget {
|
||||
const _Footer({required this.navigationContract});
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final bool isLoading = ref.watch(
|
||||
loginViewModelProvider.select((s) => s.isLoading),
|
||||
);
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
context.translate(I18n.dontHaveAccount),
|
||||
style: const TextStyle(fontSize: 18, letterSpacing: 0),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: isLoading
|
||||
? null
|
||||
: () => navigationContract.pushTo(AppRoutes.signup),
|
||||
child: Text(
|
||||
context.translate(I18n.createOneNow),
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w500,
|
||||
letterSpacing: 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _FieldErrorText extends StatelessWidget {
|
||||
const _FieldErrorText._({required this.text});
|
||||
final String text;
|
||||
|
||||
factory _FieldErrorText.fromKey({required String errorKey}) {
|
||||
return _FieldErrorText._(text: errorKey);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (text.isEmpty) return const SizedBox.shrink();
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 8),
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
context.translate(text),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import 'package:auth/src/core/providers/auth_repository_provider.dart';
|
||||
import 'package:auth/src/features/login/domain/login_use_case.dart';
|
||||
import 'package:auth/src/features/login/domain/login_use_case_impl.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
final loginUseCaseProvider = Provider.autoDispose<LoginUseCase>((ref) {
|
||||
final authRepository = ref.read(authRepositoryProvider);
|
||||
return LoginUseCaseImpl(authRepository);
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
import 'package:auth/src/core/providers/auth_repository_provider.dart';
|
||||
import 'package:auth/src/features/login/domain/two_factor_use_case.dart';
|
||||
import 'package:auth/src/features/login/domain/two_factor_use_case_impl.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
final twoFactorUseCaseProvider = Provider.autoDispose<TwoFactorUseCase>((ref) {
|
||||
final authRepository = ref.read(authRepositoryProvider);
|
||||
return TwoFactorUseCaseImpl(authRepository);
|
||||
});
|
||||
@@ -0,0 +1,202 @@
|
||||
import 'package:auth/src/features/login/domain/login_use_case.dart';
|
||||
import 'package:auth/src/features/login/domain/two_factor_use_case.dart';
|
||||
import 'package:auth/src/features/login/presentation/providers/login_provider.dart';
|
||||
import 'package:auth/src/features/login/presentation/providers/two_factor_provider.dart';
|
||||
import 'package:auth/src/features/login/presentation/state/login_view_state.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
|
||||
final loginViewModelProvider =
|
||||
NotifierProvider.autoDispose<LoginViewModel, LoginViewState>(
|
||||
LoginViewModel.new,
|
||||
);
|
||||
|
||||
class LoginViewModel extends Notifier<LoginViewState> {
|
||||
late final LoginUseCase _loginUseCase;
|
||||
late final TwoFactorUseCase _twoFactorUseCase;
|
||||
|
||||
late final TextEditingController emailController;
|
||||
late final TextEditingController passwordController;
|
||||
|
||||
late final TextEditingController otpController;
|
||||
|
||||
static final RegExp _emailRegex = RegExp(
|
||||
r'^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$',
|
||||
caseSensitive: false,
|
||||
);
|
||||
|
||||
@override
|
||||
LoginViewState build() {
|
||||
_loginUseCase = ref.read(loginUseCaseProvider);
|
||||
_twoFactorUseCase = ref.read(twoFactorUseCaseProvider);
|
||||
|
||||
emailController = TextEditingController();
|
||||
passwordController = TextEditingController();
|
||||
otpController = TextEditingController();
|
||||
|
||||
emailController.addListener(_onEmailChanged);
|
||||
passwordController.addListener(_onPasswordChanged);
|
||||
otpController.addListener(_onOtpChanged);
|
||||
|
||||
ref.onDispose(disposeControllers);
|
||||
|
||||
return const LoginViewState();
|
||||
}
|
||||
|
||||
void _onEmailChanged() {
|
||||
final text = emailController.text;
|
||||
if (text == state.email) return;
|
||||
|
||||
state = state.copyWith(email: text, errorMessage: '');
|
||||
|
||||
if (state.showErrors) {
|
||||
state = state.copyWith(emailError: _emailErrorFor(text));
|
||||
}
|
||||
}
|
||||
|
||||
void _onPasswordChanged() {
|
||||
final text = passwordController.text;
|
||||
if (text == state.password) return;
|
||||
|
||||
state = state.copyWith(password: text, errorMessage: '');
|
||||
|
||||
if (state.showErrors) {
|
||||
state = state.copyWith(passwordError: _passwordErrorFor(text));
|
||||
}
|
||||
}
|
||||
|
||||
void togglePasswordVisible() {
|
||||
state = state.copyWith(passwordVisible: !state.passwordVisible);
|
||||
}
|
||||
|
||||
bool _isValidEmail(String email) => _emailRegex.hasMatch(email);
|
||||
|
||||
String _emailErrorFor(String value) {
|
||||
final email = value.trim();
|
||||
if (email.isEmpty) return I18n.errorEmailRequired;
|
||||
if (!_isValidEmail(email)) return I18n.errorEmailInvalid;
|
||||
return '';
|
||||
}
|
||||
|
||||
String _passwordErrorFor(String value) {
|
||||
final password = value.trim();
|
||||
if (password.isEmpty) return I18n.errorPasswordRequired;
|
||||
if (password.length < 6) return I18n.errorPasswordMinLength;
|
||||
return '';
|
||||
}
|
||||
|
||||
bool _validateForm() {
|
||||
final emailError = _emailErrorFor(state.email);
|
||||
final passwordError = _passwordErrorFor(state.password);
|
||||
|
||||
state = state.copyWith(
|
||||
showErrors: true,
|
||||
emailError: emailError,
|
||||
passwordError: passwordError,
|
||||
errorMessage: '',
|
||||
);
|
||||
|
||||
return emailError.isEmpty && passwordError.isEmpty;
|
||||
}
|
||||
|
||||
Future<String?> login() async {
|
||||
if (!_validateForm()) return null;
|
||||
|
||||
final email = state.email.trim();
|
||||
final password = state.password.trim();
|
||||
|
||||
state = state.copyWith(isLoading: true, errorMessage: '');
|
||||
|
||||
try {
|
||||
final String token = await _loginUseCase.login(
|
||||
email: email,
|
||||
password: password,
|
||||
);
|
||||
|
||||
if (!ref.mounted) return null;
|
||||
|
||||
state = state.copyWith(isLoading: false);
|
||||
return token;
|
||||
} catch (e) {
|
||||
if (!ref.mounted) return null;
|
||||
|
||||
state = state.copyWith(isLoading: false, errorMessage: e.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
void prepareTwoFactor() {
|
||||
otpController.text = '';
|
||||
state = state.copyWith(otpCode: '', otpError: '', isOtpLoading: false);
|
||||
}
|
||||
|
||||
void _onOtpChanged() {
|
||||
final raw = otpController.text;
|
||||
if (raw == state.otpCode) return;
|
||||
|
||||
state = state.copyWith(otpCode: raw, otpError: '');
|
||||
|
||||
if (state.showErrors) {
|
||||
state = state.copyWith(otpError: _otpErrorFor(raw));
|
||||
}
|
||||
}
|
||||
|
||||
void setOtpCode(String code) {
|
||||
state = state.copyWith(otpCode: code, otpError: '');
|
||||
}
|
||||
|
||||
String _otpErrorFor(String value) {
|
||||
final code = value.trim();
|
||||
if (code.isEmpty) return I18n.errorTwoFactorCodeRequired;
|
||||
if (code.length != 6) return I18n.errorTwoFactorCodeInvalidLength;
|
||||
return '';
|
||||
}
|
||||
|
||||
bool _validateOtp() {
|
||||
final otpError = _otpErrorFor(state.otpCode);
|
||||
|
||||
state = state.copyWith(
|
||||
showErrors: true,
|
||||
otpError: otpError,
|
||||
errorMessage: '',
|
||||
);
|
||||
|
||||
return otpError.isEmpty;
|
||||
}
|
||||
|
||||
Future<bool> twoFactor({required String token}) async {
|
||||
if (!_validateOtp()) return false;
|
||||
|
||||
final code = state.otpCode.trim();
|
||||
|
||||
state = state.copyWith(isOtpLoading: true, otpError: '', errorMessage: '');
|
||||
|
||||
try {
|
||||
await _twoFactorUseCase.twoFactor(token: token, code: code);
|
||||
|
||||
if (!ref.mounted) return false;
|
||||
|
||||
state = state.copyWith(isOtpLoading: false);
|
||||
return true;
|
||||
} catch (e) {
|
||||
if (!ref.mounted) return false;
|
||||
|
||||
state = state.copyWith(
|
||||
isOtpLoading: false,
|
||||
otpError: I18n.errorTwoFactorCodeInvalid,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void disposeControllers() {
|
||||
emailController.removeListener(_onEmailChanged);
|
||||
passwordController.removeListener(_onPasswordChanged);
|
||||
otpController.removeListener(_onOtpChanged);
|
||||
|
||||
emailController.dispose();
|
||||
passwordController.dispose();
|
||||
otpController.dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'login_view_state.freezed.dart';
|
||||
|
||||
@freezed
|
||||
abstract class LoginViewState with _$LoginViewState {
|
||||
const factory LoginViewState({
|
||||
@Default('') String email,
|
||||
@Default('') String password,
|
||||
@Default(false) bool passwordVisible,
|
||||
@Default('') String emailError,
|
||||
@Default('') String passwordError,
|
||||
@Default('') String errorMessage,
|
||||
@Default(false) bool showErrors,
|
||||
@Default(false) bool isLoading,
|
||||
@Default('') String token,
|
||||
@Default('') String otpCode,
|
||||
@Default('') String otpError,
|
||||
@Default(false) bool isOtpLoading,
|
||||
}) = _LoginViewState;
|
||||
}
|
||||
@@ -0,0 +1,304 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'login_view_state.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$LoginViewState {
|
||||
|
||||
String get email; String get password; bool get passwordVisible; String get emailError; String get passwordError; String get errorMessage; bool get showErrors; bool get isLoading; String get token; String get otpCode; String get otpError; bool get isOtpLoading;
|
||||
/// Create a copy of LoginViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$LoginViewStateCopyWith<LoginViewState> get copyWith => _$LoginViewStateCopyWithImpl<LoginViewState>(this as LoginViewState, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is LoginViewState&&(identical(other.email, email) || other.email == email)&&(identical(other.password, password) || other.password == password)&&(identical(other.passwordVisible, passwordVisible) || other.passwordVisible == passwordVisible)&&(identical(other.emailError, emailError) || other.emailError == emailError)&&(identical(other.passwordError, passwordError) || other.passwordError == passwordError)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.showErrors, showErrors) || other.showErrors == showErrors)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.token, token) || other.token == token)&&(identical(other.otpCode, otpCode) || other.otpCode == otpCode)&&(identical(other.otpError, otpError) || other.otpError == otpError)&&(identical(other.isOtpLoading, isOtpLoading) || other.isOtpLoading == isOtpLoading));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,email,password,passwordVisible,emailError,passwordError,errorMessage,showErrors,isLoading,token,otpCode,otpError,isOtpLoading);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'LoginViewState(email: $email, password: $password, passwordVisible: $passwordVisible, emailError: $emailError, passwordError: $passwordError, errorMessage: $errorMessage, showErrors: $showErrors, isLoading: $isLoading, token: $token, otpCode: $otpCode, otpError: $otpError, isOtpLoading: $isOtpLoading)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $LoginViewStateCopyWith<$Res> {
|
||||
factory $LoginViewStateCopyWith(LoginViewState value, $Res Function(LoginViewState) _then) = _$LoginViewStateCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String email, String password, bool passwordVisible, String emailError, String passwordError, String errorMessage, bool showErrors, bool isLoading, String token, String otpCode, String otpError, bool isOtpLoading
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$LoginViewStateCopyWithImpl<$Res>
|
||||
implements $LoginViewStateCopyWith<$Res> {
|
||||
_$LoginViewStateCopyWithImpl(this._self, this._then);
|
||||
|
||||
final LoginViewState _self;
|
||||
final $Res Function(LoginViewState) _then;
|
||||
|
||||
/// Create a copy of LoginViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? email = null,Object? password = null,Object? passwordVisible = null,Object? emailError = null,Object? passwordError = null,Object? errorMessage = null,Object? showErrors = null,Object? isLoading = null,Object? token = null,Object? otpCode = null,Object? otpError = null,Object? isOtpLoading = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
email: null == email ? _self.email : email // ignore: cast_nullable_to_non_nullable
|
||||
as String,password: null == password ? _self.password : password // ignore: cast_nullable_to_non_nullable
|
||||
as String,passwordVisible: null == passwordVisible ? _self.passwordVisible : passwordVisible // ignore: cast_nullable_to_non_nullable
|
||||
as bool,emailError: null == emailError ? _self.emailError : emailError // ignore: cast_nullable_to_non_nullable
|
||||
as String,passwordError: null == passwordError ? _self.passwordError : passwordError // ignore: cast_nullable_to_non_nullable
|
||||
as String,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
||||
as String,showErrors: null == showErrors ? _self.showErrors : showErrors // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,token: null == token ? _self.token : token // ignore: cast_nullable_to_non_nullable
|
||||
as String,otpCode: null == otpCode ? _self.otpCode : otpCode // ignore: cast_nullable_to_non_nullable
|
||||
as String,otpError: null == otpError ? _self.otpError : otpError // ignore: cast_nullable_to_non_nullable
|
||||
as String,isOtpLoading: null == isOtpLoading ? _self.isOtpLoading : isOtpLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [LoginViewState].
|
||||
extension LoginViewStatePatterns on LoginViewState {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _LoginViewState value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _LoginViewState() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _LoginViewState value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _LoginViewState():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _LoginViewState value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _LoginViewState() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String email, String password, bool passwordVisible, String emailError, String passwordError, String errorMessage, bool showErrors, bool isLoading, String token, String otpCode, String otpError, bool isOtpLoading)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _LoginViewState() when $default != null:
|
||||
return $default(_that.email,_that.password,_that.passwordVisible,_that.emailError,_that.passwordError,_that.errorMessage,_that.showErrors,_that.isLoading,_that.token,_that.otpCode,_that.otpError,_that.isOtpLoading);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String email, String password, bool passwordVisible, String emailError, String passwordError, String errorMessage, bool showErrors, bool isLoading, String token, String otpCode, String otpError, bool isOtpLoading) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _LoginViewState():
|
||||
return $default(_that.email,_that.password,_that.passwordVisible,_that.emailError,_that.passwordError,_that.errorMessage,_that.showErrors,_that.isLoading,_that.token,_that.otpCode,_that.otpError,_that.isOtpLoading);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String email, String password, bool passwordVisible, String emailError, String passwordError, String errorMessage, bool showErrors, bool isLoading, String token, String otpCode, String otpError, bool isOtpLoading)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _LoginViewState() when $default != null:
|
||||
return $default(_that.email,_that.password,_that.passwordVisible,_that.emailError,_that.passwordError,_that.errorMessage,_that.showErrors,_that.isLoading,_that.token,_that.otpCode,_that.otpError,_that.isOtpLoading);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _LoginViewState implements LoginViewState {
|
||||
const _LoginViewState({this.email = '', this.password = '', this.passwordVisible = false, this.emailError = '', this.passwordError = '', this.errorMessage = '', this.showErrors = false, this.isLoading = false, this.token = '', this.otpCode = '', this.otpError = '', this.isOtpLoading = false});
|
||||
|
||||
|
||||
@override@JsonKey() final String email;
|
||||
@override@JsonKey() final String password;
|
||||
@override@JsonKey() final bool passwordVisible;
|
||||
@override@JsonKey() final String emailError;
|
||||
@override@JsonKey() final String passwordError;
|
||||
@override@JsonKey() final String errorMessage;
|
||||
@override@JsonKey() final bool showErrors;
|
||||
@override@JsonKey() final bool isLoading;
|
||||
@override@JsonKey() final String token;
|
||||
@override@JsonKey() final String otpCode;
|
||||
@override@JsonKey() final String otpError;
|
||||
@override@JsonKey() final bool isOtpLoading;
|
||||
|
||||
/// Create a copy of LoginViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$LoginViewStateCopyWith<_LoginViewState> get copyWith => __$LoginViewStateCopyWithImpl<_LoginViewState>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _LoginViewState&&(identical(other.email, email) || other.email == email)&&(identical(other.password, password) || other.password == password)&&(identical(other.passwordVisible, passwordVisible) || other.passwordVisible == passwordVisible)&&(identical(other.emailError, emailError) || other.emailError == emailError)&&(identical(other.passwordError, passwordError) || other.passwordError == passwordError)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.showErrors, showErrors) || other.showErrors == showErrors)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.token, token) || other.token == token)&&(identical(other.otpCode, otpCode) || other.otpCode == otpCode)&&(identical(other.otpError, otpError) || other.otpError == otpError)&&(identical(other.isOtpLoading, isOtpLoading) || other.isOtpLoading == isOtpLoading));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,email,password,passwordVisible,emailError,passwordError,errorMessage,showErrors,isLoading,token,otpCode,otpError,isOtpLoading);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'LoginViewState(email: $email, password: $password, passwordVisible: $passwordVisible, emailError: $emailError, passwordError: $passwordError, errorMessage: $errorMessage, showErrors: $showErrors, isLoading: $isLoading, token: $token, otpCode: $otpCode, otpError: $otpError, isOtpLoading: $isOtpLoading)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$LoginViewStateCopyWith<$Res> implements $LoginViewStateCopyWith<$Res> {
|
||||
factory _$LoginViewStateCopyWith(_LoginViewState value, $Res Function(_LoginViewState) _then) = __$LoginViewStateCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String email, String password, bool passwordVisible, String emailError, String passwordError, String errorMessage, bool showErrors, bool isLoading, String token, String otpCode, String otpError, bool isOtpLoading
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$LoginViewStateCopyWithImpl<$Res>
|
||||
implements _$LoginViewStateCopyWith<$Res> {
|
||||
__$LoginViewStateCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _LoginViewState _self;
|
||||
final $Res Function(_LoginViewState) _then;
|
||||
|
||||
/// Create a copy of LoginViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? email = null,Object? password = null,Object? passwordVisible = null,Object? emailError = null,Object? passwordError = null,Object? errorMessage = null,Object? showErrors = null,Object? isLoading = null,Object? token = null,Object? otpCode = null,Object? otpError = null,Object? isOtpLoading = null,}) {
|
||||
return _then(_LoginViewState(
|
||||
email: null == email ? _self.email : email // ignore: cast_nullable_to_non_nullable
|
||||
as String,password: null == password ? _self.password : password // ignore: cast_nullable_to_non_nullable
|
||||
as String,passwordVisible: null == passwordVisible ? _self.passwordVisible : passwordVisible // ignore: cast_nullable_to_non_nullable
|
||||
as bool,emailError: null == emailError ? _self.emailError : emailError // ignore: cast_nullable_to_non_nullable
|
||||
as String,passwordError: null == passwordError ? _self.passwordError : passwordError // ignore: cast_nullable_to_non_nullable
|
||||
as String,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
||||
as String,showErrors: null == showErrors ? _self.showErrors : showErrors // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,token: null == token ? _self.token : token // ignore: cast_nullable_to_non_nullable
|
||||
as String,otpCode: null == otpCode ? _self.otpCode : otpCode // ignore: cast_nullable_to_non_nullable
|
||||
as String,otpError: null == otpError ? _self.otpError : otpError // ignore: cast_nullable_to_non_nullable
|
||||
as String,isOtpLoading: null == isOtpLoading ? _self.isOtpLoading : isOtpLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,211 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class OtpCodeFields extends StatefulWidget {
|
||||
const OtpCodeFields({
|
||||
super.key,
|
||||
this.length = 6,
|
||||
this.autofocus = true,
|
||||
this.enabled = true,
|
||||
this.errorText,
|
||||
this.onChanged,
|
||||
this.onCompleted,
|
||||
this.boxSize = 48,
|
||||
this.gap = 10,
|
||||
});
|
||||
|
||||
final int length;
|
||||
final bool autofocus;
|
||||
final bool enabled;
|
||||
final String? errorText;
|
||||
final ValueChanged<String>? onChanged;
|
||||
final ValueChanged<String>? onCompleted;
|
||||
final double boxSize;
|
||||
final double gap;
|
||||
|
||||
@override
|
||||
State<OtpCodeFields> createState() => _OtpCodeFieldsState();
|
||||
}
|
||||
|
||||
class _OtpCodeFieldsState extends State<OtpCodeFields> {
|
||||
late final List<TextEditingController> _controllers;
|
||||
late final List<FocusNode> _focusNodes;
|
||||
|
||||
String get _code => _controllers.map((c) => c.text.trim()).join();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controllers = List.generate(widget.length, (_) => TextEditingController());
|
||||
_focusNodes = List.generate(widget.length, (_) => FocusNode());
|
||||
|
||||
if (widget.autofocus) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (!mounted) return;
|
||||
_focusNodes.first.requestFocus();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
for (final c in _controllers) {
|
||||
c.dispose();
|
||||
}
|
||||
for (final f in _focusNodes) {
|
||||
f.dispose();
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _emit() {
|
||||
final code = _code;
|
||||
widget.onChanged?.call(code);
|
||||
if (code.length == widget.length &&
|
||||
!_controllers.any((c) => c.text.isEmpty)) {
|
||||
widget.onCompleted?.call(code);
|
||||
}
|
||||
}
|
||||
|
||||
void _setFromPaste(String value) {
|
||||
final digits = value.replaceAll(RegExp(r'\D'), '');
|
||||
if (digits.isEmpty) return;
|
||||
|
||||
final clipped = digits.length > widget.length
|
||||
? digits.substring(0, widget.length)
|
||||
: digits;
|
||||
|
||||
for (var i = 0; i < widget.length; i++) {
|
||||
_controllers[i].text = i < clipped.length ? clipped[i] : '';
|
||||
}
|
||||
|
||||
final nextIndex = clipped.length >= widget.length
|
||||
? widget.length - 1
|
||||
: clipped.length;
|
||||
|
||||
_focusNodes[nextIndex].requestFocus();
|
||||
_emit();
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
void _onChanged(int index, String value) {
|
||||
if (!mounted) return;
|
||||
|
||||
if (value.length > 1) {
|
||||
_setFromPaste(value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.isNotEmpty && index < widget.length - 1) {
|
||||
_focusNodes[index + 1].requestFocus();
|
||||
}
|
||||
|
||||
_emit();
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
KeyEventResult _onKey(int index, KeyEvent event) {
|
||||
if (event is! KeyDownEvent) return KeyEventResult.ignored;
|
||||
|
||||
if (event.logicalKey == LogicalKeyboardKey.backspace) {
|
||||
final current = _controllers[index].text;
|
||||
|
||||
if (current.isEmpty && index > 0) {
|
||||
_controllers[index - 1].text = '';
|
||||
_focusNodes[index - 1].requestFocus();
|
||||
_emit();
|
||||
setState(() {});
|
||||
return KeyEventResult.handled;
|
||||
}
|
||||
}
|
||||
|
||||
return KeyEventResult.ignored;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final borderColor = widget.errorText == null || widget.errorText!.isEmpty
|
||||
? Theme.of(context).dividerColor
|
||||
: Theme.of(context).colorScheme.error;
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Wrap(
|
||||
alignment: WrapAlignment.center,
|
||||
spacing: widget.gap,
|
||||
children: List.generate(widget.length, (i) {
|
||||
return SizedBox(
|
||||
width: widget.boxSize,
|
||||
height: widget.boxSize,
|
||||
child: Focus(
|
||||
onKeyEvent: (_, event) => _onKey(i, event),
|
||||
child: TextField(
|
||||
enabled: widget.enabled,
|
||||
controller: _controllers[i],
|
||||
focusNode: _focusNodes[i],
|
||||
keyboardType: TextInputType.number,
|
||||
textInputAction: i == widget.length - 1
|
||||
? TextInputAction.done
|
||||
: TextInputAction.next,
|
||||
textAlign: TextAlign.center,
|
||||
maxLength: 1,
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
LengthLimitingTextInputFormatter(1),
|
||||
],
|
||||
decoration: InputDecoration(
|
||||
counterText: '',
|
||||
contentPadding: EdgeInsets.zero,
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
borderSide: BorderSide(color: borderColor),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
borderSide: BorderSide(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
width: 1.6,
|
||||
),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
borderSide: BorderSide(
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
width: 1.2,
|
||||
),
|
||||
),
|
||||
focusedErrorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
borderSide: BorderSide(
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
width: 1.6,
|
||||
),
|
||||
),
|
||||
),
|
||||
onChanged: (v) => _onChanged(i, v),
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
if (widget.errorText != null && widget.errorText!.isNotEmpty)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: Text(
|
||||
widget.errorText!,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auth/src/features/login/presentation/widgets/otp_code_fields.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class TwoFactorBottomSheetView extends StatelessWidget {
|
||||
const TwoFactorBottomSheetView({
|
||||
super.key,
|
||||
required this.theme,
|
||||
required this.title,
|
||||
required this.subtitle,
|
||||
required this.verifyText,
|
||||
required this.closeText,
|
||||
required this.isOtpLoading,
|
||||
required this.otpCode,
|
||||
required this.otpErrorText,
|
||||
required this.onChanged,
|
||||
required this.onVerify,
|
||||
required this.onClose,
|
||||
});
|
||||
|
||||
final ThemePort theme;
|
||||
|
||||
final String title;
|
||||
final String subtitle;
|
||||
final String verifyText;
|
||||
final String closeText;
|
||||
|
||||
final bool isOtpLoading;
|
||||
final String otpCode;
|
||||
final String otpErrorText;
|
||||
|
||||
final ValueChanged<String> onChanged;
|
||||
final Future<void> Function() onVerify;
|
||||
final VoidCallback onClose;
|
||||
|
||||
bool get _isValidOtp => otpCode.trim().length == 6;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final bottomInset = MediaQuery.of(context).viewInsets.bottom;
|
||||
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
borderRadius: const BorderRadius.vertical(top: Radius.circular(24)),
|
||||
),
|
||||
padding: EdgeInsets.fromLTRB(24, 12, 24, 24 + bottomInset),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
height: 4,
|
||||
width: 48,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.withValues(alpha: 0.35),
|
||||
borderRadius: BorderRadius.circular(999),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
Text(
|
||||
title,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w700),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
subtitle,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(fontSize: 14),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
OtpCodeFields(
|
||||
length: 6,
|
||||
enabled: !isOtpLoading,
|
||||
errorText: otpErrorText.isEmpty ? null : otpErrorText,
|
||||
onChanged: onChanged,
|
||||
onCompleted: (_) {
|
||||
if (isOtpLoading || !_isValidOtp) return;
|
||||
unawaited(onVerify());
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
PrimaryButton(
|
||||
onPressed: (isOtpLoading || !_isValidOtp)
|
||||
? () {}
|
||||
: () => unawaited(onVerify()),
|
||||
text: verifyText,
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary),
|
||||
leading: isOtpLoading
|
||||
? const SizedBox(
|
||||
height: 18,
|
||||
width: 18,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
color: Colors.white,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
|
||||
const SizedBox(height: 12),
|
||||
|
||||
TextButton(
|
||||
onPressed: isOtpLoading ? null : onClose,
|
||||
child: Text(closeText),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:auth/src/onboarding/presentation/onboarding_screen.dart';
|
||||
import 'package:auth/src/features/onboarding/presentation/onboarding_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
@@ -0,0 +1,126 @@
|
||||
import 'package:auth/src/features/onboarding/domain/onboarding_page.dart';
|
||||
import 'package:auth/src/features/onboarding/presentation/onboarding_view_model.dart';
|
||||
import 'package:auth/src/features/onboarding/presentation/widgets/onboarding_content.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
|
||||
final onboardingPageControllerProvider = Provider.autoDispose<PageController>((
|
||||
ref,
|
||||
) {
|
||||
final controller = PageController();
|
||||
ref.onDispose(controller.dispose);
|
||||
return controller;
|
||||
});
|
||||
|
||||
class OnboardingScreen extends ConsumerWidget {
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
const OnboardingScreen({super.key, required this.navigationContract});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final state = ref.watch(onBoardingViewModelProvider);
|
||||
final viewModel = ref.read(onBoardingViewModelProvider.notifier);
|
||||
final pageController = ref.watch(onboardingPageControllerProvider);
|
||||
|
||||
final isLast = state.cardIndex >= onboardingPages.length - 1;
|
||||
|
||||
void goToNext() {
|
||||
if (isLast) {
|
||||
navigationContract.goTo(AppRoutes.linkPhone);
|
||||
} else {
|
||||
pageController.nextPage(
|
||||
duration: const Duration(milliseconds: 400),
|
||||
curve: Curves.easeOut,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: PageView.builder(
|
||||
controller: pageController,
|
||||
itemCount: onboardingPages.length,
|
||||
onPageChanged: viewModel.onPageChanged,
|
||||
itemBuilder: (context, index) {
|
||||
final page = onboardingPages[index];
|
||||
return OnboardingContent(
|
||||
image: page.image,
|
||||
title: page.title,
|
||||
subtitle: page.subtitle,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
StepIndicator(
|
||||
current: state.cardIndex + 1,
|
||||
total: onboardingPages.length,
|
||||
color: const Color(0xFF4A4A4A),
|
||||
),
|
||||
const SizedBox(height: 38),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
width: double.infinity,
|
||||
child: TextButton(
|
||||
onPressed: goToNext,
|
||||
style: TextButton.styleFrom(
|
||||
backgroundColor: isLast
|
||||
? const Color(0xFF329E95)
|
||||
: const Color(0xFF333333),
|
||||
foregroundColor: Colors.white,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
horizontal: 24,
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
isLast
|
||||
? context.translate(I18n.start)
|
||||
: context.translate(I18n.next),
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
SizedBox(
|
||||
height: 48,
|
||||
child: Center(
|
||||
child: isLast
|
||||
? const SizedBox.shrink()
|
||||
: TextButton(
|
||||
onPressed: () =>
|
||||
navigationContract.goTo(AppRoutes.linkPhone),
|
||||
child: Text(
|
||||
context.translate(I18n.skip),
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
decoration: TextDecoration.underline,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 48),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:auth/src/onboarding/presentation/onboarding_view_state.dart';
|
||||
import 'package:auth/src/features/onboarding/presentation/onboarding_view_state.dart';
|
||||
|
||||
final onBoardingViewModelProvider =
|
||||
NotifierProvider.autoDispose<OnBoardingViewModel, OnboardingViewState>(
|
||||
@@ -57,7 +57,11 @@ class NewPasswordScreenState extends ConsumerState<NewPasswordScreen> {
|
||||
const Text(
|
||||
"Recuperar contraseña",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 30, letterSpacing: 0),
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 30,
|
||||
letterSpacing: 0,
|
||||
),
|
||||
),
|
||||
Column(
|
||||
spacing: 16,
|
||||
@@ -91,11 +95,16 @@ class NewPasswordScreenState extends ConsumerState<NewPasswordScreen> {
|
||||
children: [
|
||||
Icon(
|
||||
Icons.check,
|
||||
color: theme.getColorFor(securityChecks["min"]!
|
||||
? ThemeCode.buttonPrimary
|
||||
: ThemeCode.buttonSecondary),
|
||||
color: theme.getColorFor(
|
||||
securityChecks["min"]!
|
||||
? ThemeCode.buttonPrimary
|
||||
: ThemeCode.buttonSecondary,
|
||||
),
|
||||
),
|
||||
const Text(
|
||||
"Al menos 8 caracteres",
|
||||
style: TextStyle(fontSize: 14),
|
||||
),
|
||||
const Text("Al menos 8 caracteres", style: TextStyle(fontSize: 14)),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
@@ -103,11 +112,16 @@ class NewPasswordScreenState extends ConsumerState<NewPasswordScreen> {
|
||||
children: [
|
||||
Icon(
|
||||
Icons.check,
|
||||
color: theme.getColorFor(securityChecks["capital"]!
|
||||
? ThemeCode.buttonPrimary
|
||||
: ThemeCode.buttonSecondary),
|
||||
color: theme.getColorFor(
|
||||
securityChecks["capital"]!
|
||||
? ThemeCode.buttonPrimary
|
||||
: ThemeCode.buttonSecondary,
|
||||
),
|
||||
),
|
||||
const Text(
|
||||
"Una mayúscula",
|
||||
style: TextStyle(fontSize: 14),
|
||||
),
|
||||
const Text("Una mayúscula", style: TextStyle(fontSize: 14)),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
@@ -115,11 +129,16 @@ class NewPasswordScreenState extends ConsumerState<NewPasswordScreen> {
|
||||
children: [
|
||||
Icon(
|
||||
Icons.check,
|
||||
color: theme.getColorFor(securityChecks["number"]!
|
||||
? ThemeCode.buttonPrimary
|
||||
: ThemeCode.buttonSecondary),
|
||||
color: theme.getColorFor(
|
||||
securityChecks["number"]!
|
||||
? ThemeCode.buttonPrimary
|
||||
: ThemeCode.buttonSecondary,
|
||||
),
|
||||
),
|
||||
const Text(
|
||||
"Un número",
|
||||
style: TextStyle(fontSize: 14),
|
||||
),
|
||||
const Text("Un número", style: TextStyle(fontSize: 14)),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
@@ -127,15 +146,20 @@ class NewPasswordScreenState extends ConsumerState<NewPasswordScreen> {
|
||||
children: [
|
||||
Icon(
|
||||
Icons.check,
|
||||
color: theme.getColorFor(securityChecks["special"]!
|
||||
? ThemeCode.buttonPrimary
|
||||
: ThemeCode.buttonSecondary),
|
||||
color: theme.getColorFor(
|
||||
securityChecks["special"]!
|
||||
? ThemeCode.buttonPrimary
|
||||
: ThemeCode.buttonSecondary,
|
||||
),
|
||||
),
|
||||
const Text(
|
||||
"Un carácter especial",
|
||||
style: TextStyle(fontSize: 14),
|
||||
),
|
||||
const Text("Un carácter especial", style: TextStyle(fontSize: 14)),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
@@ -146,32 +170,39 @@ class NewPasswordScreenState extends ConsumerState<NewPasswordScreen> {
|
||||
child: const Text(
|
||||
"Teléfono móvil",
|
||||
style: TextStyle(fontSize: 14, letterSpacing: 0),
|
||||
)
|
||||
),
|
||||
),
|
||||
Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
CustomDropdown(
|
||||
value: 0,
|
||||
items: [Icon(Icons.outlined_flag), Icon(Icons.outlined_flag), Icon(Icons.outlined_flag)],
|
||||
onChanged: (value)=> {},
|
||||
items: [
|
||||
Icon(Icons.outlined_flag),
|
||||
Icon(Icons.outlined_flag),
|
||||
Icon(Icons.outlined_flag),
|
||||
],
|
||||
onChanged: (value) => {},
|
||||
width: 80,
|
||||
),
|
||||
Expanded(child: CustomTextField(
|
||||
hint: "Teléfono",
|
||||
numeric: true
|
||||
))
|
||||
]
|
||||
Expanded(
|
||||
child: CustomTextField(
|
||||
hint: "Teléfono",
|
||||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
),
|
||||
],
|
||||
),
|
||||
PrimaryButton(
|
||||
onPressed: ()=>{navigationContract.goTo(AppRoutes.dashboardHome)},
|
||||
onPressed: () => {
|
||||
navigationContract.goTo(AppRoutes.dashboardHome),
|
||||
},
|
||||
text: "Aceptar",
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary)
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary),
|
||||
),
|
||||
const Spacer(),
|
||||
],
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:auth/src/recover_password/presentation/sent_screen.dart';
|
||||
import 'package:auth/src/features/recover_password/presentation/sent_screen.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
@@ -47,26 +47,30 @@ class RestorePasswordScreen extends ConsumerWidget {
|
||||
spacing: 8,
|
||||
children: [
|
||||
Align(
|
||||
alignment: Alignment.bottomLeft,
|
||||
child: Text(
|
||||
"Teléfono móvil",
|
||||
style: TextStyle(fontSize: 14, letterSpacing: 0),
|
||||
)
|
||||
alignment: Alignment.bottomLeft,
|
||||
child: Text(
|
||||
"Teléfono móvil",
|
||||
style: TextStyle(fontSize: 14, letterSpacing: 0),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
spacing: 10,
|
||||
children: [
|
||||
CustomDropdown(
|
||||
value: 0,
|
||||
items: [Icon(Icons.outlined_flag), Icon(Icons.outlined_flag), Icon(Icons.outlined_flag)],
|
||||
onChanged: (value)=> {},
|
||||
items: [
|
||||
Icon(Icons.outlined_flag),
|
||||
Icon(Icons.outlined_flag),
|
||||
Icon(Icons.outlined_flag),
|
||||
],
|
||||
onChanged: (value) => {},
|
||||
width: 80,
|
||||
),
|
||||
Expanded(
|
||||
child: CustomTextField(
|
||||
hint: "Teléfono",
|
||||
numeric: true
|
||||
)
|
||||
child: CustomTextField(
|
||||
hint: "Teléfono",
|
||||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -75,11 +79,14 @@ class RestorePasswordScreen extends ConsumerWidget {
|
||||
Row(
|
||||
spacing: 20,
|
||||
children: [
|
||||
Expanded( child: SecondaryButton(
|
||||
Expanded(
|
||||
child: SecondaryButton(
|
||||
onPressed: () => {Navigator.pop(context)},
|
||||
text: "Volver"
|
||||
)),
|
||||
Expanded( child: PrimaryButton(
|
||||
text: "Volver",
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: PrimaryButton(
|
||||
onPressed: () => {
|
||||
Navigator.push(
|
||||
context,
|
||||
@@ -90,8 +97,9 @@ class RestorePasswordScreen extends ConsumerWidget {
|
||||
},
|
||||
text: "Enviar",
|
||||
size: 16,
|
||||
color: theme.getColorFor(ThemeCode.buttonSecondary)
|
||||
)),
|
||||
color: theme.getColorFor(ThemeCode.buttonSecondary),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:auth/src/recover_password/presentation/new_password_screen.dart';
|
||||
import 'package:auth/src/features/recover_password/presentation/new_password_screen.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
@@ -6,10 +6,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
class SentScreen extends ConsumerWidget {
|
||||
final String format;
|
||||
|
||||
const SentScreen({
|
||||
super.key,
|
||||
required this.format
|
||||
});
|
||||
const SentScreen({super.key, required this.format});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
@@ -27,7 +24,11 @@ class SentScreen extends ConsumerWidget {
|
||||
Text(
|
||||
"Recuperar contraseña",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 30, letterSpacing: 0),
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 30,
|
||||
letterSpacing: 0,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
spacing: 10,
|
||||
@@ -38,9 +39,9 @@ class SentScreen extends ConsumerWidget {
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary),
|
||||
),
|
||||
Text(
|
||||
format=="email"
|
||||
?"Correo enviado correctamente"
|
||||
:"SMS enviado correctamente",
|
||||
format == "email"
|
||||
? "Correo enviado correctamente"
|
||||
: "SMS enviado correctamente",
|
||||
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
||||
),
|
||||
Spacer(),
|
||||
@@ -50,16 +51,16 @@ class SentScreen extends ConsumerWidget {
|
||||
spacing: 16,
|
||||
children: [
|
||||
Text(
|
||||
format=="email"
|
||||
?"Revisa tu email y haz clic en el enlace para crear una nueva contraseña."
|
||||
:"Revisa tu móvil y sigue las instrucciones para crear una nueva contraseña.",
|
||||
format == "email"
|
||||
? "Revisa tu email y haz clic en el enlace para crear una nueva contraseña."
|
||||
: "Revisa tu móvil y sigue las instrucciones para crear una nueva contraseña.",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(fontSize: 18, letterSpacing: 0),
|
||||
),
|
||||
Text(
|
||||
format=="email"
|
||||
?"Si no recibes el correo en unos minutos, revisa tu carpeta de spam o pulsa \"Reenviar correo\"."
|
||||
:"Si no recibes el SMS en unos minutos, asegúrate de tener cobertura o pulsa \"Reenviar SMS \".",
|
||||
format == "email"
|
||||
? "Si no recibes el correo en unos minutos, revisa tu carpeta de spam o pulsa \"Reenviar correo\"."
|
||||
: "Si no recibes el SMS en unos minutos, asegúrate de tener cobertura o pulsa \"Reenviar SMS \".",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(fontSize: 14, letterSpacing: 0),
|
||||
),
|
||||
@@ -68,22 +69,22 @@ class SentScreen extends ConsumerWidget {
|
||||
Row(
|
||||
spacing: 10,
|
||||
children: [
|
||||
Expanded( child: SecondaryButton(
|
||||
onPressed: () => {},
|
||||
text: format=="email"
|
||||
?"Reenviar correo"
|
||||
:"Reenviar SMS"
|
||||
)),
|
||||
Expanded(
|
||||
child: SecondaryButton(
|
||||
onPressed: () => {},
|
||||
text: format == "email"
|
||||
? "Reenviar correo"
|
||||
: "Reenviar SMS",
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: PrimaryButton(
|
||||
onPressed: ()=>Navigator.push(
|
||||
onPressed: () => Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (_) => NewPasswordScreen(),
|
||||
),
|
||||
MaterialPageRoute(builder: (_) => NewPasswordScreen()),
|
||||
),
|
||||
text: "Continuar",
|
||||
color: theme.getColorFor(ThemeCode.buttonSecondary)
|
||||
color: theme.getColorFor(ThemeCode.buttonSecondary),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:auth/src/recover_password/presentation/restore_password_screen.dart';
|
||||
import 'package:auth/src/features/recover_password/presentation/restore_password_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
@@ -0,0 +1,15 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'address_entity.freezed.dart';
|
||||
|
||||
@freezed
|
||||
abstract class AddressEntity with _$AddressEntity {
|
||||
const factory AddressEntity({
|
||||
required String street,
|
||||
required String city,
|
||||
required String province,
|
||||
required String state,
|
||||
required String country,
|
||||
required int postCode,
|
||||
}) = _AddressEntity;
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'address_entity.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$AddressEntity {
|
||||
|
||||
String get street; String get city; String get province; String get state; String get country; int get postCode;
|
||||
/// Create a copy of AddressEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$AddressEntityCopyWith<AddressEntity> get copyWith => _$AddressEntityCopyWithImpl<AddressEntity>(this as AddressEntity, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is AddressEntity&&(identical(other.street, street) || other.street == street)&&(identical(other.city, city) || other.city == city)&&(identical(other.province, province) || other.province == province)&&(identical(other.state, state) || other.state == state)&&(identical(other.country, country) || other.country == country)&&(identical(other.postCode, postCode) || other.postCode == postCode));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,street,city,province,state,country,postCode);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AddressEntity(street: $street, city: $city, province: $province, state: $state, country: $country, postCode: $postCode)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $AddressEntityCopyWith<$Res> {
|
||||
factory $AddressEntityCopyWith(AddressEntity value, $Res Function(AddressEntity) _then) = _$AddressEntityCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String street, String city, String province, String state, String country, int postCode
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$AddressEntityCopyWithImpl<$Res>
|
||||
implements $AddressEntityCopyWith<$Res> {
|
||||
_$AddressEntityCopyWithImpl(this._self, this._then);
|
||||
|
||||
final AddressEntity _self;
|
||||
final $Res Function(AddressEntity) _then;
|
||||
|
||||
/// Create a copy of AddressEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? street = null,Object? city = null,Object? province = null,Object? state = null,Object? country = null,Object? postCode = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
street: null == street ? _self.street : street // ignore: cast_nullable_to_non_nullable
|
||||
as String,city: null == city ? _self.city : city // ignore: cast_nullable_to_non_nullable
|
||||
as String,province: null == province ? _self.province : province // ignore: cast_nullable_to_non_nullable
|
||||
as String,state: null == state ? _self.state : state // ignore: cast_nullable_to_non_nullable
|
||||
as String,country: null == country ? _self.country : country // ignore: cast_nullable_to_non_nullable
|
||||
as String,postCode: null == postCode ? _self.postCode : postCode // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [AddressEntity].
|
||||
extension AddressEntityPatterns on AddressEntity {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _AddressEntity value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _AddressEntity() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _AddressEntity value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _AddressEntity():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _AddressEntity value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _AddressEntity() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String street, String city, String province, String state, String country, int postCode)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AddressEntity() when $default != null:
|
||||
return $default(_that.street,_that.city,_that.province,_that.state,_that.country,_that.postCode);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String street, String city, String province, String state, String country, int postCode) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AddressEntity():
|
||||
return $default(_that.street,_that.city,_that.province,_that.state,_that.country,_that.postCode);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String street, String city, String province, String state, String country, int postCode)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AddressEntity() when $default != null:
|
||||
return $default(_that.street,_that.city,_that.province,_that.state,_that.country,_that.postCode);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _AddressEntity implements AddressEntity {
|
||||
const _AddressEntity({required this.street, required this.city, required this.province, required this.state, required this.country, required this.postCode});
|
||||
|
||||
|
||||
@override final String street;
|
||||
@override final String city;
|
||||
@override final String province;
|
||||
@override final String state;
|
||||
@override final String country;
|
||||
@override final int postCode;
|
||||
|
||||
/// Create a copy of AddressEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$AddressEntityCopyWith<_AddressEntity> get copyWith => __$AddressEntityCopyWithImpl<_AddressEntity>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AddressEntity&&(identical(other.street, street) || other.street == street)&&(identical(other.city, city) || other.city == city)&&(identical(other.province, province) || other.province == province)&&(identical(other.state, state) || other.state == state)&&(identical(other.country, country) || other.country == country)&&(identical(other.postCode, postCode) || other.postCode == postCode));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,street,city,province,state,country,postCode);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AddressEntity(street: $street, city: $city, province: $province, state: $state, country: $country, postCode: $postCode)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$AddressEntityCopyWith<$Res> implements $AddressEntityCopyWith<$Res> {
|
||||
factory _$AddressEntityCopyWith(_AddressEntity value, $Res Function(_AddressEntity) _then) = __$AddressEntityCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String street, String city, String province, String state, String country, int postCode
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$AddressEntityCopyWithImpl<$Res>
|
||||
implements _$AddressEntityCopyWith<$Res> {
|
||||
__$AddressEntityCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _AddressEntity _self;
|
||||
final $Res Function(_AddressEntity) _then;
|
||||
|
||||
/// Create a copy of AddressEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? street = null,Object? city = null,Object? province = null,Object? state = null,Object? country = null,Object? postCode = null,}) {
|
||||
return _then(_AddressEntity(
|
||||
street: null == street ? _self.street : street // ignore: cast_nullable_to_non_nullable
|
||||
as String,city: null == city ? _self.city : city // ignore: cast_nullable_to_non_nullable
|
||||
as String,province: null == province ? _self.province : province // ignore: cast_nullable_to_non_nullable
|
||||
as String,state: null == state ? _self.state : state // ignore: cast_nullable_to_non_nullable
|
||||
as String,country: null == country ? _self.country : country // ignore: cast_nullable_to_non_nullable
|
||||
as String,postCode: null == postCode ? _self.postCode : postCode // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,25 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'address_entity.dart';
|
||||
|
||||
part 'sign_up_request_entity.freezed.dart';
|
||||
|
||||
@freezed
|
||||
abstract class SignUpRequestEntity with _$SignUpRequestEntity {
|
||||
const factory SignUpRequestEntity({
|
||||
required String documentType,
|
||||
required String documentNumber,
|
||||
required String relationship,
|
||||
required String firstName,
|
||||
required String lastName,
|
||||
required String email,
|
||||
required String phone,
|
||||
required String language,
|
||||
required String password,
|
||||
required List<AddressEntity> taxResidences,
|
||||
required List<AddressEntity> addresses,
|
||||
required int bornAt,
|
||||
required String userId, // UUID
|
||||
required String placeOfBirth,
|
||||
required String birthCountry,
|
||||
}) = _SignUpRequestEntity;
|
||||
}
|
||||
@@ -0,0 +1,327 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'sign_up_request_entity.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$SignUpRequestEntity {
|
||||
|
||||
String get documentType; String get documentNumber; String get relationship; String get firstName; String get lastName; String get email; String get phone; String get language; String get password; List<AddressEntity> get taxResidences; List<AddressEntity> get addresses; int get bornAt; String get userId;// UUID
|
||||
String get placeOfBirth; String get birthCountry;
|
||||
/// Create a copy of SignUpRequestEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$SignUpRequestEntityCopyWith<SignUpRequestEntity> get copyWith => _$SignUpRequestEntityCopyWithImpl<SignUpRequestEntity>(this as SignUpRequestEntity, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SignUpRequestEntity&&(identical(other.documentType, documentType) || other.documentType == documentType)&&(identical(other.documentNumber, documentNumber) || other.documentNumber == documentNumber)&&(identical(other.relationship, relationship) || other.relationship == relationship)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.email, email) || other.email == email)&&(identical(other.phone, phone) || other.phone == phone)&&(identical(other.language, language) || other.language == language)&&(identical(other.password, password) || other.password == password)&&const DeepCollectionEquality().equals(other.taxResidences, taxResidences)&&const DeepCollectionEquality().equals(other.addresses, addresses)&&(identical(other.bornAt, bornAt) || other.bornAt == bornAt)&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.placeOfBirth, placeOfBirth) || other.placeOfBirth == placeOfBirth)&&(identical(other.birthCountry, birthCountry) || other.birthCountry == birthCountry));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,documentType,documentNumber,relationship,firstName,lastName,email,phone,language,password,const DeepCollectionEquality().hash(taxResidences),const DeepCollectionEquality().hash(addresses),bornAt,userId,placeOfBirth,birthCountry);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SignUpRequestEntity(documentType: $documentType, documentNumber: $documentNumber, relationship: $relationship, firstName: $firstName, lastName: $lastName, email: $email, phone: $phone, language: $language, password: $password, taxResidences: $taxResidences, addresses: $addresses, bornAt: $bornAt, userId: $userId, placeOfBirth: $placeOfBirth, birthCountry: $birthCountry)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $SignUpRequestEntityCopyWith<$Res> {
|
||||
factory $SignUpRequestEntityCopyWith(SignUpRequestEntity value, $Res Function(SignUpRequestEntity) _then) = _$SignUpRequestEntityCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String documentType, String documentNumber, String relationship, String firstName, String lastName, String email, String phone, String language, String password, List<AddressEntity> taxResidences, List<AddressEntity> addresses, int bornAt, String userId, String placeOfBirth, String birthCountry
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$SignUpRequestEntityCopyWithImpl<$Res>
|
||||
implements $SignUpRequestEntityCopyWith<$Res> {
|
||||
_$SignUpRequestEntityCopyWithImpl(this._self, this._then);
|
||||
|
||||
final SignUpRequestEntity _self;
|
||||
final $Res Function(SignUpRequestEntity) _then;
|
||||
|
||||
/// Create a copy of SignUpRequestEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? documentType = null,Object? documentNumber = null,Object? relationship = null,Object? firstName = null,Object? lastName = null,Object? email = null,Object? phone = null,Object? language = null,Object? password = null,Object? taxResidences = null,Object? addresses = null,Object? bornAt = null,Object? userId = null,Object? placeOfBirth = null,Object? birthCountry = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
documentType: null == documentType ? _self.documentType : documentType // ignore: cast_nullable_to_non_nullable
|
||||
as String,documentNumber: null == documentNumber ? _self.documentNumber : documentNumber // ignore: cast_nullable_to_non_nullable
|
||||
as String,relationship: null == relationship ? _self.relationship : relationship // ignore: cast_nullable_to_non_nullable
|
||||
as String,firstName: null == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable
|
||||
as String,lastName: null == lastName ? _self.lastName : lastName // ignore: cast_nullable_to_non_nullable
|
||||
as String,email: null == email ? _self.email : email // ignore: cast_nullable_to_non_nullable
|
||||
as String,phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable
|
||||
as String,language: null == language ? _self.language : language // ignore: cast_nullable_to_non_nullable
|
||||
as String,password: null == password ? _self.password : password // ignore: cast_nullable_to_non_nullable
|
||||
as String,taxResidences: null == taxResidences ? _self.taxResidences : taxResidences // ignore: cast_nullable_to_non_nullable
|
||||
as List<AddressEntity>,addresses: null == addresses ? _self.addresses : addresses // ignore: cast_nullable_to_non_nullable
|
||||
as List<AddressEntity>,bornAt: null == bornAt ? _self.bornAt : bornAt // ignore: cast_nullable_to_non_nullable
|
||||
as int,userId: null == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable
|
||||
as String,placeOfBirth: null == placeOfBirth ? _self.placeOfBirth : placeOfBirth // ignore: cast_nullable_to_non_nullable
|
||||
as String,birthCountry: null == birthCountry ? _self.birthCountry : birthCountry // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [SignUpRequestEntity].
|
||||
extension SignUpRequestEntityPatterns on SignUpRequestEntity {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _SignUpRequestEntity value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpRequestEntity() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _SignUpRequestEntity value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpRequestEntity():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _SignUpRequestEntity value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpRequestEntity() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String documentType, String documentNumber, String relationship, String firstName, String lastName, String email, String phone, String language, String password, List<AddressEntity> taxResidences, List<AddressEntity> addresses, int bornAt, String userId, String placeOfBirth, String birthCountry)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpRequestEntity() when $default != null:
|
||||
return $default(_that.documentType,_that.documentNumber,_that.relationship,_that.firstName,_that.lastName,_that.email,_that.phone,_that.language,_that.password,_that.taxResidences,_that.addresses,_that.bornAt,_that.userId,_that.placeOfBirth,_that.birthCountry);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String documentType, String documentNumber, String relationship, String firstName, String lastName, String email, String phone, String language, String password, List<AddressEntity> taxResidences, List<AddressEntity> addresses, int bornAt, String userId, String placeOfBirth, String birthCountry) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpRequestEntity():
|
||||
return $default(_that.documentType,_that.documentNumber,_that.relationship,_that.firstName,_that.lastName,_that.email,_that.phone,_that.language,_that.password,_that.taxResidences,_that.addresses,_that.bornAt,_that.userId,_that.placeOfBirth,_that.birthCountry);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String documentType, String documentNumber, String relationship, String firstName, String lastName, String email, String phone, String language, String password, List<AddressEntity> taxResidences, List<AddressEntity> addresses, int bornAt, String userId, String placeOfBirth, String birthCountry)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _SignUpRequestEntity() when $default != null:
|
||||
return $default(_that.documentType,_that.documentNumber,_that.relationship,_that.firstName,_that.lastName,_that.email,_that.phone,_that.language,_that.password,_that.taxResidences,_that.addresses,_that.bornAt,_that.userId,_that.placeOfBirth,_that.birthCountry);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _SignUpRequestEntity implements SignUpRequestEntity {
|
||||
const _SignUpRequestEntity({required this.documentType, required this.documentNumber, required this.relationship, required this.firstName, required this.lastName, required this.email, required this.phone, required this.language, required this.password, required final List<AddressEntity> taxResidences, required final List<AddressEntity> addresses, required this.bornAt, required this.userId, required this.placeOfBirth, required this.birthCountry}): _taxResidences = taxResidences,_addresses = addresses;
|
||||
|
||||
|
||||
@override final String documentType;
|
||||
@override final String documentNumber;
|
||||
@override final String relationship;
|
||||
@override final String firstName;
|
||||
@override final String lastName;
|
||||
@override final String email;
|
||||
@override final String phone;
|
||||
@override final String language;
|
||||
@override final String password;
|
||||
final List<AddressEntity> _taxResidences;
|
||||
@override List<AddressEntity> get taxResidences {
|
||||
if (_taxResidences is EqualUnmodifiableListView) return _taxResidences;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_taxResidences);
|
||||
}
|
||||
|
||||
final List<AddressEntity> _addresses;
|
||||
@override List<AddressEntity> get addresses {
|
||||
if (_addresses is EqualUnmodifiableListView) return _addresses;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_addresses);
|
||||
}
|
||||
|
||||
@override final int bornAt;
|
||||
@override final String userId;
|
||||
// UUID
|
||||
@override final String placeOfBirth;
|
||||
@override final String birthCountry;
|
||||
|
||||
/// Create a copy of SignUpRequestEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$SignUpRequestEntityCopyWith<_SignUpRequestEntity> get copyWith => __$SignUpRequestEntityCopyWithImpl<_SignUpRequestEntity>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SignUpRequestEntity&&(identical(other.documentType, documentType) || other.documentType == documentType)&&(identical(other.documentNumber, documentNumber) || other.documentNumber == documentNumber)&&(identical(other.relationship, relationship) || other.relationship == relationship)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.email, email) || other.email == email)&&(identical(other.phone, phone) || other.phone == phone)&&(identical(other.language, language) || other.language == language)&&(identical(other.password, password) || other.password == password)&&const DeepCollectionEquality().equals(other._taxResidences, _taxResidences)&&const DeepCollectionEquality().equals(other._addresses, _addresses)&&(identical(other.bornAt, bornAt) || other.bornAt == bornAt)&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.placeOfBirth, placeOfBirth) || other.placeOfBirth == placeOfBirth)&&(identical(other.birthCountry, birthCountry) || other.birthCountry == birthCountry));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,documentType,documentNumber,relationship,firstName,lastName,email,phone,language,password,const DeepCollectionEquality().hash(_taxResidences),const DeepCollectionEquality().hash(_addresses),bornAt,userId,placeOfBirth,birthCountry);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SignUpRequestEntity(documentType: $documentType, documentNumber: $documentNumber, relationship: $relationship, firstName: $firstName, lastName: $lastName, email: $email, phone: $phone, language: $language, password: $password, taxResidences: $taxResidences, addresses: $addresses, bornAt: $bornAt, userId: $userId, placeOfBirth: $placeOfBirth, birthCountry: $birthCountry)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$SignUpRequestEntityCopyWith<$Res> implements $SignUpRequestEntityCopyWith<$Res> {
|
||||
factory _$SignUpRequestEntityCopyWith(_SignUpRequestEntity value, $Res Function(_SignUpRequestEntity) _then) = __$SignUpRequestEntityCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String documentType, String documentNumber, String relationship, String firstName, String lastName, String email, String phone, String language, String password, List<AddressEntity> taxResidences, List<AddressEntity> addresses, int bornAt, String userId, String placeOfBirth, String birthCountry
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$SignUpRequestEntityCopyWithImpl<$Res>
|
||||
implements _$SignUpRequestEntityCopyWith<$Res> {
|
||||
__$SignUpRequestEntityCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _SignUpRequestEntity _self;
|
||||
final $Res Function(_SignUpRequestEntity) _then;
|
||||
|
||||
/// Create a copy of SignUpRequestEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? documentType = null,Object? documentNumber = null,Object? relationship = null,Object? firstName = null,Object? lastName = null,Object? email = null,Object? phone = null,Object? language = null,Object? password = null,Object? taxResidences = null,Object? addresses = null,Object? bornAt = null,Object? userId = null,Object? placeOfBirth = null,Object? birthCountry = null,}) {
|
||||
return _then(_SignUpRequestEntity(
|
||||
documentType: null == documentType ? _self.documentType : documentType // ignore: cast_nullable_to_non_nullable
|
||||
as String,documentNumber: null == documentNumber ? _self.documentNumber : documentNumber // ignore: cast_nullable_to_non_nullable
|
||||
as String,relationship: null == relationship ? _self.relationship : relationship // ignore: cast_nullable_to_non_nullable
|
||||
as String,firstName: null == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable
|
||||
as String,lastName: null == lastName ? _self.lastName : lastName // ignore: cast_nullable_to_non_nullable
|
||||
as String,email: null == email ? _self.email : email // ignore: cast_nullable_to_non_nullable
|
||||
as String,phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable
|
||||
as String,language: null == language ? _self.language : language // ignore: cast_nullable_to_non_nullable
|
||||
as String,password: null == password ? _self.password : password // ignore: cast_nullable_to_non_nullable
|
||||
as String,taxResidences: null == taxResidences ? _self._taxResidences : taxResidences // ignore: cast_nullable_to_non_nullable
|
||||
as List<AddressEntity>,addresses: null == addresses ? _self._addresses : addresses // ignore: cast_nullable_to_non_nullable
|
||||
as List<AddressEntity>,bornAt: null == bornAt ? _self.bornAt : bornAt // ignore: cast_nullable_to_non_nullable
|
||||
as int,userId: null == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable
|
||||
as String,placeOfBirth: null == placeOfBirth ? _self.placeOfBirth : placeOfBirth // ignore: cast_nullable_to_non_nullable
|
||||
as String,birthCountry: null == birthCountry ? _self.birthCountry : birthCountry // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,19 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'two_fa_secret_entity.freezed.dart';
|
||||
|
||||
@freezed
|
||||
abstract class TwoFASecretEntity with _$TwoFASecretEntity {
|
||||
const factory TwoFASecretEntity({
|
||||
required bool isCreated,
|
||||
required TwoFASecretItemEntity item,
|
||||
}) = _TwoFASecretEntity;
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class TwoFASecretItemEntity with _$TwoFASecretItemEntity {
|
||||
const factory TwoFASecretItemEntity({
|
||||
required String secret,
|
||||
required String qr,
|
||||
}) = _TwoFASecretItemEntity;
|
||||
}
|
||||
@@ -0,0 +1,552 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'two_fa_secret_entity.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$TwoFASecretEntity {
|
||||
|
||||
bool get isCreated; TwoFASecretItemEntity get item;
|
||||
/// Create a copy of TwoFASecretEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$TwoFASecretEntityCopyWith<TwoFASecretEntity> get copyWith => _$TwoFASecretEntityCopyWithImpl<TwoFASecretEntity>(this as TwoFASecretEntity, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is TwoFASecretEntity&&(identical(other.isCreated, isCreated) || other.isCreated == isCreated)&&(identical(other.item, item) || other.item == item));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,isCreated,item);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'TwoFASecretEntity(isCreated: $isCreated, item: $item)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $TwoFASecretEntityCopyWith<$Res> {
|
||||
factory $TwoFASecretEntityCopyWith(TwoFASecretEntity value, $Res Function(TwoFASecretEntity) _then) = _$TwoFASecretEntityCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
bool isCreated, TwoFASecretItemEntity item
|
||||
});
|
||||
|
||||
|
||||
$TwoFASecretItemEntityCopyWith<$Res> get item;
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$TwoFASecretEntityCopyWithImpl<$Res>
|
||||
implements $TwoFASecretEntityCopyWith<$Res> {
|
||||
_$TwoFASecretEntityCopyWithImpl(this._self, this._then);
|
||||
|
||||
final TwoFASecretEntity _self;
|
||||
final $Res Function(TwoFASecretEntity) _then;
|
||||
|
||||
/// Create a copy of TwoFASecretEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? isCreated = null,Object? item = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
isCreated: null == isCreated ? _self.isCreated : isCreated // ignore: cast_nullable_to_non_nullable
|
||||
as bool,item: null == item ? _self.item : item // ignore: cast_nullable_to_non_nullable
|
||||
as TwoFASecretItemEntity,
|
||||
));
|
||||
}
|
||||
/// Create a copy of TwoFASecretEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$TwoFASecretItemEntityCopyWith<$Res> get item {
|
||||
|
||||
return $TwoFASecretItemEntityCopyWith<$Res>(_self.item, (value) {
|
||||
return _then(_self.copyWith(item: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [TwoFASecretEntity].
|
||||
extension TwoFASecretEntityPatterns on TwoFASecretEntity {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _TwoFASecretEntity value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretEntity() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _TwoFASecretEntity value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretEntity():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _TwoFASecretEntity value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretEntity() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool isCreated, TwoFASecretItemEntity item)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretEntity() when $default != null:
|
||||
return $default(_that.isCreated,_that.item);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool isCreated, TwoFASecretItemEntity item) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretEntity():
|
||||
return $default(_that.isCreated,_that.item);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool isCreated, TwoFASecretItemEntity item)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretEntity() when $default != null:
|
||||
return $default(_that.isCreated,_that.item);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _TwoFASecretEntity implements TwoFASecretEntity {
|
||||
const _TwoFASecretEntity({required this.isCreated, required this.item});
|
||||
|
||||
|
||||
@override final bool isCreated;
|
||||
@override final TwoFASecretItemEntity item;
|
||||
|
||||
/// Create a copy of TwoFASecretEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$TwoFASecretEntityCopyWith<_TwoFASecretEntity> get copyWith => __$TwoFASecretEntityCopyWithImpl<_TwoFASecretEntity>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _TwoFASecretEntity&&(identical(other.isCreated, isCreated) || other.isCreated == isCreated)&&(identical(other.item, item) || other.item == item));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,isCreated,item);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'TwoFASecretEntity(isCreated: $isCreated, item: $item)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$TwoFASecretEntityCopyWith<$Res> implements $TwoFASecretEntityCopyWith<$Res> {
|
||||
factory _$TwoFASecretEntityCopyWith(_TwoFASecretEntity value, $Res Function(_TwoFASecretEntity) _then) = __$TwoFASecretEntityCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
bool isCreated, TwoFASecretItemEntity item
|
||||
});
|
||||
|
||||
|
||||
@override $TwoFASecretItemEntityCopyWith<$Res> get item;
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$TwoFASecretEntityCopyWithImpl<$Res>
|
||||
implements _$TwoFASecretEntityCopyWith<$Res> {
|
||||
__$TwoFASecretEntityCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _TwoFASecretEntity _self;
|
||||
final $Res Function(_TwoFASecretEntity) _then;
|
||||
|
||||
/// Create a copy of TwoFASecretEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? isCreated = null,Object? item = null,}) {
|
||||
return _then(_TwoFASecretEntity(
|
||||
isCreated: null == isCreated ? _self.isCreated : isCreated // ignore: cast_nullable_to_non_nullable
|
||||
as bool,item: null == item ? _self.item : item // ignore: cast_nullable_to_non_nullable
|
||||
as TwoFASecretItemEntity,
|
||||
));
|
||||
}
|
||||
|
||||
/// Create a copy of TwoFASecretEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$TwoFASecretItemEntityCopyWith<$Res> get item {
|
||||
|
||||
return $TwoFASecretItemEntityCopyWith<$Res>(_self.item, (value) {
|
||||
return _then(_self.copyWith(item: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$TwoFASecretItemEntity {
|
||||
|
||||
String get secret; String get qr;
|
||||
/// Create a copy of TwoFASecretItemEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$TwoFASecretItemEntityCopyWith<TwoFASecretItemEntity> get copyWith => _$TwoFASecretItemEntityCopyWithImpl<TwoFASecretItemEntity>(this as TwoFASecretItemEntity, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is TwoFASecretItemEntity&&(identical(other.secret, secret) || other.secret == secret)&&(identical(other.qr, qr) || other.qr == qr));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,secret,qr);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'TwoFASecretItemEntity(secret: $secret, qr: $qr)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $TwoFASecretItemEntityCopyWith<$Res> {
|
||||
factory $TwoFASecretItemEntityCopyWith(TwoFASecretItemEntity value, $Res Function(TwoFASecretItemEntity) _then) = _$TwoFASecretItemEntityCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String secret, String qr
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$TwoFASecretItemEntityCopyWithImpl<$Res>
|
||||
implements $TwoFASecretItemEntityCopyWith<$Res> {
|
||||
_$TwoFASecretItemEntityCopyWithImpl(this._self, this._then);
|
||||
|
||||
final TwoFASecretItemEntity _self;
|
||||
final $Res Function(TwoFASecretItemEntity) _then;
|
||||
|
||||
/// Create a copy of TwoFASecretItemEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? secret = null,Object? qr = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
secret: null == secret ? _self.secret : secret // ignore: cast_nullable_to_non_nullable
|
||||
as String,qr: null == qr ? _self.qr : qr // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [TwoFASecretItemEntity].
|
||||
extension TwoFASecretItemEntityPatterns on TwoFASecretItemEntity {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _TwoFASecretItemEntity value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretItemEntity() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _TwoFASecretItemEntity value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretItemEntity():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _TwoFASecretItemEntity value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretItemEntity() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String secret, String qr)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretItemEntity() when $default != null:
|
||||
return $default(_that.secret,_that.qr);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String secret, String qr) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretItemEntity():
|
||||
return $default(_that.secret,_that.qr);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String secret, String qr)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _TwoFASecretItemEntity() when $default != null:
|
||||
return $default(_that.secret,_that.qr);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _TwoFASecretItemEntity implements TwoFASecretItemEntity {
|
||||
const _TwoFASecretItemEntity({required this.secret, required this.qr});
|
||||
|
||||
|
||||
@override final String secret;
|
||||
@override final String qr;
|
||||
|
||||
/// Create a copy of TwoFASecretItemEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$TwoFASecretItemEntityCopyWith<_TwoFASecretItemEntity> get copyWith => __$TwoFASecretItemEntityCopyWithImpl<_TwoFASecretItemEntity>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _TwoFASecretItemEntity&&(identical(other.secret, secret) || other.secret == secret)&&(identical(other.qr, qr) || other.qr == qr));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,secret,qr);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'TwoFASecretItemEntity(secret: $secret, qr: $qr)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$TwoFASecretItemEntityCopyWith<$Res> implements $TwoFASecretItemEntityCopyWith<$Res> {
|
||||
factory _$TwoFASecretItemEntityCopyWith(_TwoFASecretItemEntity value, $Res Function(_TwoFASecretItemEntity) _then) = __$TwoFASecretItemEntityCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String secret, String qr
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$TwoFASecretItemEntityCopyWithImpl<$Res>
|
||||
implements _$TwoFASecretItemEntityCopyWith<$Res> {
|
||||
__$TwoFASecretItemEntityCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _TwoFASecretItemEntity _self;
|
||||
final $Res Function(_TwoFASecretItemEntity) _then;
|
||||
|
||||
/// Create a copy of TwoFASecretItemEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? secret = null,Object? qr = null,}) {
|
||||
return _then(_TwoFASecretItemEntity(
|
||||
secret: null == secret ? _self.secret : secret // ignore: cast_nullable_to_non_nullable
|
||||
as String,qr: null == qr ? _self.qr : qr // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,5 @@
|
||||
import 'package:auth/src/features/sign_up/domain/entities/two_fa_secret_entity.dart';
|
||||
|
||||
abstract class GenerateTwoFASignUpUseCase {
|
||||
Future<TwoFASecretEntity> generateTwoFASignUp({required String token});
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import 'package:auth/src/core/domain/repositories/auth_repository.dart';
|
||||
import 'package:auth/src/features/sign_up/domain/entities/two_fa_secret_entity.dart';
|
||||
import 'package:auth/src/features/sign_up/domain/generate_two_fa_sign_up_use_case.dart';
|
||||
|
||||
class GenerateTwoFASignUpUseCaseImpl implements GenerateTwoFASignUpUseCase {
|
||||
GenerateTwoFASignUpUseCaseImpl(this._repository);
|
||||
|
||||
final AuthRepository _repository;
|
||||
@override
|
||||
Future<TwoFASecretEntity> generateTwoFASignUp({required String token}) {
|
||||
return _repository.generateTwoFASignUp(token: token);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import 'package:auth/src/features/sign_up/domain/entities/sign_up_request_entity.dart';
|
||||
|
||||
abstract class SignUpUseCase {
|
||||
Future<String> signUp({required SignUpRequestEntity request});
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import 'package:auth/src/core/domain/repositories/auth_repository.dart';
|
||||
import 'package:auth/src/features/sign_up/domain/entities/sign_up_request_entity.dart';
|
||||
import 'package:auth/src/features/sign_up/domain/sign_up_use_case.dart';
|
||||
|
||||
class SignUpUseCaseImpl implements SignUpUseCase {
|
||||
SignUpUseCaseImpl(this._repository);
|
||||
|
||||
final AuthRepository _repository;
|
||||
|
||||
@override
|
||||
Future<String> signUp({required SignUpRequestEntity request}) {
|
||||
return _repository.signUp(request: request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
abstract class VerifyTwoFACodeSignUpUseCase {
|
||||
Future<void> verifyTwoFACodeSignUp({
|
||||
required String token,
|
||||
required String code,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import 'package:auth/src/core/domain/repositories/auth_repository.dart';
|
||||
import 'package:auth/src/features/sign_up/domain/verify_two_fa_code_sign_up_use_case.dart';
|
||||
|
||||
class VerifyTwoFaCodeSignUpUseCaseImpl implements VerifyTwoFACodeSignUpUseCase {
|
||||
VerifyTwoFaCodeSignUpUseCaseImpl(this._repository);
|
||||
|
||||
final AuthRepository _repository;
|
||||
@override
|
||||
Future<void> verifyTwoFACodeSignUp({
|
||||
required String token,
|
||||
required String code,
|
||||
}) {
|
||||
return _repository.verifyTwoFACodeSignUp(token: token, code: code);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
typedef SignUpBodyBuilder =
|
||||
Widget Function(BuildContext context, WidgetRef ref);
|
||||
|
||||
class SignUpStepConfig {
|
||||
final String supertitle;
|
||||
final String title;
|
||||
final String? subtitle;
|
||||
final SignUpBodyBuilder bodyBuilder;
|
||||
|
||||
const SignUpStepConfig({
|
||||
required this.supertitle,
|
||||
required this.title,
|
||||
this.subtitle,
|
||||
required this.bodyBuilder,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import 'package:auth/src/features/sign_up/domain/entities/address_entity.dart';
|
||||
import 'package:auth/src/features/sign_up/presentation/state/address_view_state.dart';
|
||||
|
||||
extension AddressViewStateMapper on AddressViewState {
|
||||
bool get isValid =>
|
||||
street.trim().isNotEmpty &&
|
||||
city.trim().isNotEmpty &&
|
||||
province.trim().isNotEmpty &&
|
||||
state.trim().isNotEmpty &&
|
||||
country.trim().isNotEmpty &&
|
||||
(postCode != null);
|
||||
|
||||
AddressEntity toEntity() {
|
||||
return AddressEntity(
|
||||
street: street.trim(),
|
||||
city: city.trim(),
|
||||
province: province.trim(),
|
||||
state: state.trim(),
|
||||
country: country.trim(),
|
||||
postCode: postCode ?? 0,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import 'package:auth/src/features/sign_up/domain/entities/address_entity.dart';
|
||||
import 'package:auth/src/features/sign_up/domain/entities/sign_up_request_entity.dart';
|
||||
import 'package:auth/src/features/sign_up/presentation/mappers/address_view_state_mapper.dart';
|
||||
import 'package:auth/src/features/sign_up/presentation/state/sign_up_view_state.dart';
|
||||
|
||||
extension SignUpViewStateMapper on SignUpViewState {
|
||||
bool get canSubmit =>
|
||||
documentNumber.trim().isNotEmpty &&
|
||||
documentType.trim().isNotEmpty &&
|
||||
relationship.trim().isNotEmpty &&
|
||||
firstName.trim().isNotEmpty &&
|
||||
lastName.trim().isNotEmpty &&
|
||||
email.trim().isNotEmpty &&
|
||||
phone.trim().isNotEmpty &&
|
||||
password.isNotEmpty &&
|
||||
bornAt != null &&
|
||||
userId.trim().isNotEmpty &&
|
||||
placeOfBirth.trim().isNotEmpty &&
|
||||
birthCountry.trim().isNotEmpty &&
|
||||
address.isValid;
|
||||
|
||||
SignUpRequestEntity toRequestEntity() {
|
||||
final birth = bornAt;
|
||||
if (birth == null) {
|
||||
throw Exception('bornAt is required');
|
||||
}
|
||||
|
||||
return SignUpRequestEntity(
|
||||
documentNumber: documentNumber.trim(),
|
||||
documentType: documentType.trim(),
|
||||
relationship: relationship.trim(),
|
||||
firstName: firstName.trim(),
|
||||
lastName: lastName.trim(),
|
||||
email: email.trim(),
|
||||
phone: phone.trim(),
|
||||
language: language.trim(),
|
||||
password: password,
|
||||
bornAt: birth.millisecondsSinceEpoch,
|
||||
userId: userId.trim(),
|
||||
placeOfBirth: placeOfBirth.trim(),
|
||||
birthCountry: birthCountry.trim(),
|
||||
addresses: <AddressEntity>[address.toEntity()],
|
||||
taxResidences: <AddressEntity>[address.toEntity()],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import 'package:auth/src/core/providers/auth_repository_provider.dart';
|
||||
import 'package:auth/src/features/sign_up/domain/generate_two_fa_sign_up_use_case.dart';
|
||||
import 'package:auth/src/features/sign_up/domain/generate_two_fa_sign_up_use_case_impl.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
final generateTwoFASignUpUseCaseProvider =
|
||||
Provider.autoDispose<GenerateTwoFASignUpUseCase>((ref) {
|
||||
final authRepository = ref.read(authRepositoryProvider);
|
||||
return GenerateTwoFASignUpUseCaseImpl(authRepository);
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
import 'package:auth/src/core/providers/auth_repository_provider.dart';
|
||||
import 'package:auth/src/features/sign_up/domain/sign_up_use_case.dart';
|
||||
import 'package:auth/src/features/sign_up/domain/sign_up_use_case_impl.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
final signUpUseCaseProvider = Provider.autoDispose<SignUpUseCase>((ref) {
|
||||
final authRepository = ref.read(authRepositoryProvider);
|
||||
return SignUpUseCaseImpl(authRepository);
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
import 'package:auth/src/core/providers/auth_repository_provider.dart';
|
||||
import 'package:auth/src/features/sign_up/domain/verify_two_fa_code_sign_up_use_case.dart';
|
||||
import 'package:auth/src/features/sign_up/domain/verify_two_fa_code_sign_up_use_case_impl.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
final verifyTwoFACodeSignUpUseCaseProvider =
|
||||
Provider.autoDispose<VerifyTwoFACodeSignUpUseCase>((ref) {
|
||||
final authRepository = ref.read(authRepositoryProvider);
|
||||
return VerifyTwoFaCodeSignUpUseCaseImpl(authRepository);
|
||||
});
|
||||
@@ -1,86 +1,88 @@
|
||||
import 'package:auth/src/features/sign_up/presentation/state/sign_up_view_model.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
|
||||
class AccountCreatedScreen extends ConsumerWidget {
|
||||
final bool kidAccount;
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
const AccountCreatedScreen({
|
||||
super.key,
|
||||
required this.kidAccount,
|
||||
required this.navigationContract,
|
||||
});
|
||||
const AccountCreatedScreen({super.key, required this.navigationContract});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
|
||||
final email = "usuario@example.com";
|
||||
final fullName = "Carlos Pérez Cruz";
|
||||
final model = "SaveWatch Plus 2";
|
||||
final id = "1106652524";
|
||||
final state = ref.watch(signUpViewModelProvider);
|
||||
|
||||
final String email = state.email;
|
||||
final String fullName = '${state.firstName} ${state.lastName}'.trim();
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
body: Container(
|
||||
margin: EdgeInsets.all(30),
|
||||
margin: const EdgeInsets.all(30),
|
||||
child: Center(
|
||||
child: Column(
|
||||
spacing: 20,
|
||||
children: [
|
||||
Spacer(flex: 10),
|
||||
const Spacer(flex: 10),
|
||||
Icon(
|
||||
Icons.check,
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary),
|
||||
size: 50,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Text(
|
||||
"Cuenta creada",
|
||||
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
|
||||
context.translate(I18n.accountCreatedTitle),
|
||||
style: const TextStyle(
|
||||
fontSize: 30,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
Text.rich(
|
||||
textAlign: TextAlign.center,
|
||||
TextSpan(
|
||||
text: "Has creado la cuenta para:\n",
|
||||
text: '${context.translate(I18n.accountCreatedForLabel)}\n',
|
||||
children: [
|
||||
TextSpan(
|
||||
text: fullName,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (!kidAccount) Text.rich(
|
||||
|
||||
const SizedBox(height: 16),
|
||||
Text.rich(
|
||||
textAlign: TextAlign.center,
|
||||
TextSpan(
|
||||
text: "Hemos enviado un email de verificación a:\n",
|
||||
text:
|
||||
'${context.translate(I18n.accountCreatedEmailVerificationSentLabel)}\n',
|
||||
children: [
|
||||
TextSpan(
|
||||
text: email,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (kidAccount) Text("Reloj: $model\nID del reloj: $id"),
|
||||
|
||||
const SizedBox(height: 20),
|
||||
Text(
|
||||
"Crea la cuenta de tu peque e ingresa su \nprimera paga para utilizarla con su reloj",
|
||||
context.translate(I18n.accountCreatedChildSetupHint),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
|
||||
const SizedBox(height: 20),
|
||||
PrimaryButton(
|
||||
onPressed: () => {
|
||||
if (kidAccount){
|
||||
navigationContract.goTo(AppRoutes.dashboardHome)
|
||||
} else {
|
||||
navigationContract.pushTo(AppRoutes.deviceSignup)
|
||||
}
|
||||
},
|
||||
text: "Continuar",
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary)
|
||||
onPressed: () => navigationContract.goTo(AppRoutes.login),
|
||||
text: context.translate(I18n.accountCreatedContinue),
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary),
|
||||
),
|
||||
Spacer(flex: 8),
|
||||
const Spacer(flex: 8),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -0,0 +1,281 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:auth/src/features/login/presentation/widgets/two_factor_bottom_sheet.dart';
|
||||
import 'package:auth/src/features/sign_up/presentation/state/sign_up_view_model.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
|
||||
class SecretCodeScreen extends ConsumerWidget {
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
const SecretCodeScreen({super.key, required this.navigationContract});
|
||||
|
||||
Uint8List? _qrBytes(String? dataUri) {
|
||||
final value = (dataUri ?? '').trim();
|
||||
if (value.isEmpty) return null;
|
||||
|
||||
final idx = value.indexOf('base64,');
|
||||
final b64 = idx == -1 ? value : value.substring(idx + 7);
|
||||
|
||||
try {
|
||||
return base64Decode(b64);
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool?> _openTwoFactorSignUpBottomSheet(
|
||||
BuildContext context,
|
||||
WidgetRef ref,
|
||||
) async {
|
||||
final token = ref.read(signUpViewModelProvider).token;
|
||||
if (token.trim().isEmpty) return false;
|
||||
|
||||
return showModalBottomSheet<bool>(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
useSafeArea: true,
|
||||
isDismissible: false,
|
||||
enableDrag: false,
|
||||
backgroundColor: Colors.transparent,
|
||||
builder: (context) {
|
||||
return Consumer(
|
||||
builder: (context, ref, _) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
final vm = ref.read(signUpViewModelProvider.notifier);
|
||||
|
||||
final otpErrorKey = ref.watch(
|
||||
signUpViewModelProvider.select((s) => s.otpError),
|
||||
);
|
||||
final isOtpLoading = ref.watch(
|
||||
signUpViewModelProvider.select((s) => s.isOtpLoading),
|
||||
);
|
||||
final otpCode = ref.watch(
|
||||
signUpViewModelProvider.select((s) => s.otpCode),
|
||||
);
|
||||
|
||||
final otpErrorText = otpErrorKey.isEmpty
|
||||
? ''
|
||||
: context.translate(otpErrorKey);
|
||||
|
||||
Future<void> onVerify() async {
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
|
||||
final ok = await vm.verifyTwoFACodeSignUp(token: token);
|
||||
if (!context.mounted) return;
|
||||
|
||||
if (ok) Navigator.of(context).pop(true);
|
||||
}
|
||||
|
||||
return TwoFactorBottomSheetView(
|
||||
theme: theme,
|
||||
title: context.translate(I18n.twoFactorTitle),
|
||||
subtitle: context.translate(I18n.twoFactorSubtitle),
|
||||
verifyText: context.translate(I18n.twoFactorVerify),
|
||||
closeText: context.translate(I18n.close),
|
||||
isOtpLoading: isOtpLoading,
|
||||
otpCode: otpCode,
|
||||
otpErrorText: otpErrorText,
|
||||
onChanged: vm.setOtpCode,
|
||||
onVerify: onVerify,
|
||||
onClose: () => Navigator.of(context).pop(false),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
final vm = ref.read(signUpViewModelProvider.notifier);
|
||||
final state = ref.watch(signUpViewModelProvider);
|
||||
|
||||
final secret = state.twoFASecret?.item.secret.trim() ?? '';
|
||||
final qrDataUri = state.twoFASecret?.item.qr;
|
||||
final qrBytes = _qrBytes(qrDataUri);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
body: SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.fromLTRB(24, 8, 24, 24),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
context.translate(I18n.secretCodeTitle),
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: theme.getColorFor(ThemeCode.textPrimary),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
_StepBlock(
|
||||
theme: theme,
|
||||
number: '1.',
|
||||
title: context.translate(I18n.secretCodeStep1Title),
|
||||
body: context.translate(I18n.secretCodeStep1Body),
|
||||
),
|
||||
const SizedBox(height: 14),
|
||||
|
||||
_StepBlock(
|
||||
theme: theme,
|
||||
number: '2.',
|
||||
title: context.translate(I18n.secretCodeStep2Title),
|
||||
body: context.translate(I18n.secretCodeStep2Body),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
Center(
|
||||
child: Container(
|
||||
width: 150,
|
||||
height: 150,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(width: 1, color: Colors.black),
|
||||
color: theme.getColorFor(ThemeCode.backgroundSecondary),
|
||||
),
|
||||
child: qrBytes == null
|
||||
? const Center(child: Icon(Icons.qr_code_2, size: 60))
|
||||
: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: Image.memory(qrBytes, fit: BoxFit.cover),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
Center(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 14,
|
||||
vertical: 10,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: theme.getColorFor(ThemeCode.backgroundSecondary),
|
||||
border: Border.all(width: 1, color: Colors.black),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
secret,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w700,
|
||||
letterSpacing: 1.1,
|
||||
color: theme.getColorFor(ThemeCode.textPrimary),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
IconButton(
|
||||
visualDensity: VisualDensity.compact,
|
||||
padding: EdgeInsets.zero,
|
||||
constraints: const BoxConstraints(),
|
||||
icon: const Icon(Icons.copy, size: 18),
|
||||
onPressed: secret.isEmpty
|
||||
? null
|
||||
: () async {
|
||||
await Clipboard.setData(
|
||||
ClipboardData(text: secret),
|
||||
);
|
||||
if (!context.mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
context.translate(
|
||||
I18n.secretCodeKeyCopied,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 18),
|
||||
_StepBlock(
|
||||
theme: theme,
|
||||
number: '3.',
|
||||
title: context.translate(I18n.secretCodeStep3Title),
|
||||
body: context.translate(I18n.secretCodeStep3Body),
|
||||
),
|
||||
|
||||
const SizedBox(height: 26),
|
||||
PrimaryButton(
|
||||
onPressed: () async {
|
||||
final verified = await _openTwoFactorSignUpBottomSheet(
|
||||
context,
|
||||
ref,
|
||||
);
|
||||
if (!context.mounted) return;
|
||||
|
||||
if (verified == true) {
|
||||
vm.showAccountCreated();
|
||||
}
|
||||
},
|
||||
text: context.translate(I18n.secretCodeConfigure),
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _StepBlock extends StatelessWidget {
|
||||
final ThemePort theme;
|
||||
final String number;
|
||||
final String title;
|
||||
final String body;
|
||||
|
||||
const _StepBlock({
|
||||
required this.theme,
|
||||
required this.number,
|
||||
required this.title,
|
||||
required this.body,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RichText(
|
||||
text: TextSpan(
|
||||
style: TextStyle(
|
||||
height: 1.35,
|
||||
fontSize: 14,
|
||||
color: theme.getColorFor(ThemeCode.textPrimary),
|
||||
),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: '$number ',
|
||||
style: const TextStyle(fontWeight: FontWeight.w700),
|
||||
),
|
||||
TextSpan(
|
||||
text: '$title\n',
|
||||
style: const TextStyle(fontWeight: FontWeight.w700),
|
||||
),
|
||||
TextSpan(
|
||||
text: body,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w400,
|
||||
color: theme.getColorFor(ThemeCode.textSecondary),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
import 'package:country_code_picker/country_code_picker.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
|
||||
class SignupAddressScreen extends StatelessWidget {
|
||||
const SignupAddressScreen({
|
||||
super.key,
|
||||
|
||||
required this.bornAtController,
|
||||
required this.onPickBornAt,
|
||||
required this.relationshipSelected,
|
||||
required this.onRelationshipChanged,
|
||||
required this.relationshipOptions,
|
||||
required this.relationshipHint,
|
||||
required this.relationshipLabel,
|
||||
|
||||
required this.placeOfBirthController,
|
||||
required this.birthCountryController,
|
||||
|
||||
required this.streetController,
|
||||
required this.cityController,
|
||||
required this.provinceController,
|
||||
required this.stateController,
|
||||
|
||||
required this.addressCountrySelected,
|
||||
required this.onAddressCountryChanged,
|
||||
required this.addressCountryController,
|
||||
required this.addressCountryLabel,
|
||||
|
||||
required this.postCodeController,
|
||||
|
||||
required this.birthDateLabel,
|
||||
required this.birthDateHint,
|
||||
|
||||
required this.placeOfBirthLabel,
|
||||
required this.placeOfBirthHint,
|
||||
|
||||
required this.birthCountryLabel,
|
||||
required this.birthCountryHint,
|
||||
required this.onBirthCountryChanged,
|
||||
|
||||
required this.streetLabel,
|
||||
required this.streetHint,
|
||||
|
||||
required this.cityLabel,
|
||||
required this.cityHint,
|
||||
|
||||
required this.provinceLabel,
|
||||
required this.provinceHint,
|
||||
|
||||
required this.stateLabel,
|
||||
required this.stateHint,
|
||||
|
||||
required this.postCodeLabel,
|
||||
required this.postCodeHint,
|
||||
});
|
||||
|
||||
final TextEditingController bornAtController;
|
||||
final VoidCallback onPickBornAt;
|
||||
|
||||
final String? relationshipSelected;
|
||||
final ValueChanged<String?> onRelationshipChanged;
|
||||
final List<String> relationshipOptions;
|
||||
final String relationshipHint;
|
||||
final String relationshipLabel;
|
||||
|
||||
final TextEditingController placeOfBirthController;
|
||||
final TextEditingController birthCountryController;
|
||||
|
||||
final TextEditingController streetController;
|
||||
final TextEditingController cityController;
|
||||
final TextEditingController provinceController;
|
||||
final TextEditingController stateController;
|
||||
|
||||
final String? addressCountrySelected;
|
||||
final ValueChanged<CountryCode> onAddressCountryChanged;
|
||||
final String addressCountryLabel;
|
||||
final TextEditingController addressCountryController;
|
||||
|
||||
final TextEditingController postCodeController;
|
||||
|
||||
final String birthDateLabel;
|
||||
final String birthDateHint;
|
||||
|
||||
final String placeOfBirthLabel;
|
||||
final String placeOfBirthHint;
|
||||
final ValueChanged<CountryCode> onBirthCountryChanged;
|
||||
|
||||
final String birthCountryLabel;
|
||||
final String birthCountryHint;
|
||||
|
||||
final String streetLabel;
|
||||
final String streetHint;
|
||||
|
||||
final String cityLabel;
|
||||
final String cityHint;
|
||||
|
||||
final String provinceLabel;
|
||||
final String provinceHint;
|
||||
|
||||
final String stateLabel;
|
||||
final String stateHint;
|
||||
|
||||
final String postCodeLabel;
|
||||
final String postCodeHint;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: onPickBornAt,
|
||||
child: AbsorbPointer(
|
||||
child: CustomTextField(
|
||||
label: birthDateLabel,
|
||||
hint: birthDateHint,
|
||||
controller: bornAtController,
|
||||
readOnly: true,
|
||||
keyboardType: TextInputType.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 8),
|
||||
|
||||
Align(
|
||||
alignment: Alignment.bottomLeft,
|
||||
child: Text(relationshipLabel, style: const TextStyle(fontSize: 14)),
|
||||
),
|
||||
CustomDropdown(
|
||||
items: relationshipOptions.map(Text.new).toList(growable: false),
|
||||
values: relationshipOptions,
|
||||
value: relationshipSelected,
|
||||
hint: relationshipHint,
|
||||
onChanged: (v) => onRelationshipChanged(v as String?),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
CustomTextField(
|
||||
label: placeOfBirthLabel,
|
||||
hint: placeOfBirthHint,
|
||||
controller: placeOfBirthController,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Align(
|
||||
alignment: Alignment.bottomLeft,
|
||||
child: Text(birthCountryLabel, style: const TextStyle(fontSize: 14)),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
spacing: 10,
|
||||
children: [
|
||||
CountryPrefixPicker(
|
||||
headerText: context.translate(I18n.selectYourCountry),
|
||||
onChanged: onBirthCountryChanged,
|
||||
),
|
||||
Expanded(
|
||||
child: CustomTextField(
|
||||
readOnly: true,
|
||||
controller: birthCountryController,
|
||||
hint: context.translate(I18n.birthCountryLabel),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
CustomTextField(
|
||||
label: streetLabel,
|
||||
hint: streetHint,
|
||||
controller: streetController,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
CustomTextField(
|
||||
label: cityLabel,
|
||||
hint: cityHint,
|
||||
controller: cityController,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
CustomTextField(
|
||||
label: provinceLabel,
|
||||
hint: provinceHint,
|
||||
controller: provinceController,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
CustomTextField(
|
||||
label: stateLabel,
|
||||
hint: stateHint,
|
||||
controller: stateController,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
Align(
|
||||
alignment: Alignment.bottomLeft,
|
||||
child: Text(
|
||||
addressCountryLabel,
|
||||
style: const TextStyle(fontSize: 14, letterSpacing: 0),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
spacing: 10,
|
||||
children: [
|
||||
CountryPrefixPicker(
|
||||
headerText: context.translate(I18n.selectYourCountry),
|
||||
onChanged: onAddressCountryChanged,
|
||||
),
|
||||
Expanded(
|
||||
child: CustomTextField(
|
||||
readOnly: true,
|
||||
controller: addressCountryController,
|
||||
hint: context.translate(I18n.addressCountryHint),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
CustomTextField(
|
||||
label: postCodeLabel,
|
||||
hint: postCodeHint,
|
||||
keyboardType: TextInputType.number,
|
||||
controller: postCodeController,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SignUpPasswordScreen extends StatelessWidget {
|
||||
final bool isPasswordVisible;
|
||||
final TextEditingController passwordTextFieldController;
|
||||
final TextEditingController repeatPasswordTextFieldController;
|
||||
const SignUpPasswordScreen({
|
||||
super.key,
|
||||
required this.isPasswordVisible,
|
||||
required this.passwordTextFieldController,
|
||||
required this.repeatPasswordTextFieldController,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
spacing: 24,
|
||||
children: [
|
||||
CustomTextField(
|
||||
showPassword: isPasswordVisible,
|
||||
label: "Contraseña",
|
||||
hint: "********",
|
||||
controller: passwordTextFieldController,
|
||||
),
|
||||
CustomTextField(
|
||||
showPassword: isPasswordVisible,
|
||||
label: "Repetir contraseña",
|
||||
hint: "*******",
|
||||
controller: repeatPasswordTextFieldController,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
import 'package:country_code_picker/country_code_picker.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
|
||||
class SignupPersonalScreen extends StatelessWidget {
|
||||
final TextEditingController firstNameTextFieldController;
|
||||
final TextEditingController lastNameTextFieldController;
|
||||
final TextEditingController documentNumberTextFieldController;
|
||||
final TextEditingController phoneTextFieldController;
|
||||
final TextEditingController emailTextFieldController;
|
||||
|
||||
final String? documentTypeSelected;
|
||||
final ValueChanged<String?> onDocumentTypeChanged;
|
||||
|
||||
final String firstNameLabel;
|
||||
final String firstNameHint;
|
||||
|
||||
final String lastNameLabel;
|
||||
final String lastNameHint;
|
||||
|
||||
final List<String> documentTypeOptions;
|
||||
final String documentTypeHint;
|
||||
|
||||
final String documentNumberLabel;
|
||||
final String documentNumberHint;
|
||||
|
||||
final String phoneLabel;
|
||||
final String phoneHint;
|
||||
final ValueChanged<CountryCode> onDialCodeChanged;
|
||||
|
||||
final String emailLabel;
|
||||
final String emailHint;
|
||||
|
||||
final bool acceptTerms;
|
||||
final ValueChanged<bool?>? onAcceptTermsPressed;
|
||||
final String termsText;
|
||||
final ThemePort theme;
|
||||
|
||||
const SignupPersonalScreen({
|
||||
super.key,
|
||||
required this.firstNameTextFieldController,
|
||||
required this.lastNameTextFieldController,
|
||||
required this.documentNumberTextFieldController,
|
||||
required this.phoneTextFieldController,
|
||||
required this.emailTextFieldController,
|
||||
required this.documentTypeSelected,
|
||||
required this.onDocumentTypeChanged,
|
||||
required this.firstNameLabel,
|
||||
required this.firstNameHint,
|
||||
required this.lastNameLabel,
|
||||
required this.lastNameHint,
|
||||
required this.documentTypeOptions,
|
||||
required this.documentTypeHint,
|
||||
required this.documentNumberLabel,
|
||||
required this.documentNumberHint,
|
||||
required this.phoneLabel,
|
||||
required this.phoneHint,
|
||||
required this.onDialCodeChanged,
|
||||
required this.emailLabel,
|
||||
required this.emailHint,
|
||||
required this.acceptTerms,
|
||||
required this.onAcceptTermsPressed,
|
||||
required this.termsText,
|
||||
required this.theme,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
CustomTextField(
|
||||
label: firstNameLabel,
|
||||
hint: firstNameHint,
|
||||
controller: firstNameTextFieldController,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
CustomTextField(
|
||||
label: lastNameLabel,
|
||||
hint: lastNameHint,
|
||||
controller: lastNameTextFieldController,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CustomDropdown(
|
||||
items: documentTypeOptions
|
||||
.map(Text.new)
|
||||
.toList(growable: false),
|
||||
values: documentTypeOptions,
|
||||
value: documentTypeSelected,
|
||||
hint: documentTypeHint,
|
||||
onChanged: (v) => onDocumentTypeChanged(v as String?),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: CustomTextField(
|
||||
label: documentNumberLabel,
|
||||
hint: documentNumberHint,
|
||||
controller: documentNumberTextFieldController,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Align(
|
||||
alignment: Alignment.bottomLeft,
|
||||
child: Text(phoneLabel, style: const TextStyle(fontSize: 14)),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
spacing: 10,
|
||||
children: [
|
||||
CountryPrefixPicker(
|
||||
headerText: context.translate(I18n.selectYourCountry),
|
||||
onChanged: onDialCodeChanged,
|
||||
),
|
||||
Expanded(
|
||||
child: CustomTextField(
|
||||
controller: phoneTextFieldController,
|
||||
hint: context.translate(I18n.phoneNumber),
|
||||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
CustomTextField(
|
||||
label: emailLabel,
|
||||
hint: emailHint,
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
controller: emailTextFieldController,
|
||||
),
|
||||
|
||||
CheckboxListTile(
|
||||
value: acceptTerms,
|
||||
onChanged: onAcceptTermsPressed,
|
||||
title: Text(
|
||||
termsText,
|
||||
style: TextStyle(fontSize: 16, letterSpacing: 0),
|
||||
),
|
||||
checkboxScaleFactor: 1.5,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
activeColor: theme.getColorFor(ThemeCode.buttonPrimary),
|
||||
controlAffinity: ListTileControlAffinity.leading,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user