diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json new file mode 100644 index 00000000..3b00a9d9 --- /dev/null +++ b/.dart_tool/package_config.json @@ -0,0 +1,364 @@ +{ + "configVersion": 2, + "packages": [ + { + "name": "ansi_styles", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/ansi_styles-0.3.2+1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "args", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/args-2.7.0", + "packageUri": "lib/", + "languageVersion": "3.3" + }, + { + "name": "async", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/async-2.13.0", + "packageUri": "lib/", + "languageVersion": "3.4" + }, + { + "name": "characters", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/characters-1.4.0", + "packageUri": "lib/", + "languageVersion": "3.4" + }, + { + "name": "charcode", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/charcode-1.4.0", + "packageUri": "lib/", + "languageVersion": "3.0" + }, + { + "name": "checked_yaml", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/checked_yaml-2.0.4", + "packageUri": "lib/", + "languageVersion": "3.8" + }, + { + "name": "cli_launcher", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/cli_launcher-0.3.2+1", + "packageUri": "lib/", + "languageVersion": "3.8" + }, + { + "name": "cli_util", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/cli_util-0.4.2", + "packageUri": "lib/", + "languageVersion": "3.4" + }, + { + "name": "collection", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/collection-1.19.1", + "packageUri": "lib/", + "languageVersion": "3.4" + }, + { + "name": "conventional_commit", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/conventional_commit-0.6.1+1", + "packageUri": "lib/", + "languageVersion": "3.8" + }, + { + "name": "ffi", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/ffi-2.1.4", + "packageUri": "lib/", + "languageVersion": "3.7" + }, + { + "name": "file", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/file-7.0.1", + "packageUri": "lib/", + "languageVersion": "3.0" + }, + { + "name": "flutter", + "rootUri": "file:///Users/juliandalcalaf/Development/flutter/packages/flutter", + "packageUri": "lib/", + "languageVersion": "3.8" + }, + { + "name": "flutter_secure_storage", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage-9.2.4", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "flutter_secure_storage_linux", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage_linux-1.2.3", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "flutter_secure_storage_macos", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage_macos-3.1.3", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "flutter_secure_storage_platform_interface", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage_platform_interface-1.1.2", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "flutter_secure_storage_web", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage_web-1.2.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "flutter_secure_storage_windows", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage_windows-3.1.2", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "flutter_web_plugins", + "rootUri": "file:///Users/juliandalcalaf/Development/flutter/packages/flutter_web_plugins", + "packageUri": "lib/", + "languageVersion": "3.8" + }, + { + "name": "glob", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/glob-2.1.3", + "packageUri": "lib/", + "languageVersion": "3.3" + }, + { + "name": "graphs", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/graphs-2.3.2", + "packageUri": "lib/", + "languageVersion": "3.4" + }, + { + "name": "http", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/http-1.5.0", + "packageUri": "lib/", + "languageVersion": "3.4" + }, + { + "name": "http_parser", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/http_parser-4.1.2", + "packageUri": "lib/", + "languageVersion": "3.4" + }, + { + "name": "io", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/io-1.0.5", + "packageUri": "lib/", + "languageVersion": "3.4" + }, + { + "name": "js", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/js-0.6.7", + "packageUri": "lib/", + "languageVersion": "2.19" + }, + { + "name": "json_annotation", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/json_annotation-4.9.0", + "packageUri": "lib/", + "languageVersion": "3.0" + }, + { + "name": "material_color_utilities", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/material_color_utilities-0.11.1", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "melos", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/melos-6.3.3", + "packageUri": "lib/", + "languageVersion": "3.8" + }, + { + "name": "meta", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/meta-1.16.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "mustache_template", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/mustache_template-2.0.2", + "packageUri": "lib/", + "languageVersion": "3.7" + }, + { + "name": "path", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path-1.9.1", + "packageUri": "lib/", + "languageVersion": "3.4" + }, + { + "name": "path_provider", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider-2.1.5", + "packageUri": "lib/", + "languageVersion": "3.4" + }, + { + "name": "path_provider_android", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_android-2.2.20", + "packageUri": "lib/", + "languageVersion": "3.9" + }, + { + "name": "path_provider_foundation", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.3", + "packageUri": "lib/", + "languageVersion": "3.9" + }, + { + "name": "path_provider_linux", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1", + "packageUri": "lib/", + "languageVersion": "2.19" + }, + { + "name": "path_provider_platform_interface", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_platform_interface-2.1.2", + "packageUri": "lib/", + "languageVersion": "3.0" + }, + { + "name": "path_provider_windows", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0", + "packageUri": "lib/", + "languageVersion": "3.2" + }, + { + "name": "platform", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/platform-3.1.6", + "packageUri": "lib/", + "languageVersion": "3.2" + }, + { + "name": "plugin_platform_interface", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/plugin_platform_interface-2.1.8", + "packageUri": "lib/", + "languageVersion": "3.0" + }, + { + "name": "pool", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/pool-1.5.2", + "packageUri": "lib/", + "languageVersion": "3.4" + }, + { + "name": "process", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/process-5.0.5", + "packageUri": "lib/", + "languageVersion": "3.5" + }, + { + "name": "prompts", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/prompts-2.0.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "pub_semver", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/pub_semver-2.2.0", + "packageUri": "lib/", + "languageVersion": "3.4" + }, + { + "name": "pub_updater", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/pub_updater-0.5.0", + "packageUri": "lib/", + "languageVersion": "3.5" + }, + { + "name": "pubspec_parse", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/pubspec_parse-1.5.0", + "packageUri": "lib/", + "languageVersion": "3.6" + }, + { + "name": "sky_engine", + "rootUri": "file:///Users/juliandalcalaf/Development/flutter/bin/cache/pkg/sky_engine", + "packageUri": "lib/", + "languageVersion": "3.8" + }, + { + "name": "source_span", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/source_span-1.10.1", + "packageUri": "lib/", + "languageVersion": "3.1" + }, + { + "name": "stack_trace", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/stack_trace-1.12.1", + "packageUri": "lib/", + "languageVersion": "3.4" + }, + { + "name": "string_scanner", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/string_scanner-1.4.1", + "packageUri": "lib/", + "languageVersion": "3.1" + }, + { + "name": "term_glyph", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/term_glyph-1.2.2", + "packageUri": "lib/", + "languageVersion": "3.1" + }, + { + "name": "typed_data", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/typed_data-1.4.0", + "packageUri": "lib/", + "languageVersion": "3.5" + }, + { + "name": "vector_math", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/vector_math-2.2.0", + "packageUri": "lib/", + "languageVersion": "3.1" + }, + { + "name": "web", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/web-1.1.1", + "packageUri": "lib/", + "languageVersion": "3.4" + }, + { + "name": "win32", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/win32-5.15.0", + "packageUri": "lib/", + "languageVersion": "3.8" + }, + { + "name": "xdg_directories", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/xdg_directories-1.1.0", + "packageUri": "lib/", + "languageVersion": "3.3" + }, + { + "name": "yaml", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/yaml-3.1.3", + "packageUri": "lib/", + "languageVersion": "3.4" + }, + { + "name": "yaml_edit", + "rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/yaml_edit-2.2.2", + "packageUri": "lib/", + "languageVersion": "3.1" + }, + { + "name": "sf_app_platform_mono_repo", + "rootUri": "../", + "packageUri": "lib/", + "languageVersion": "3.0" + } + ], + "generator": "pub", + "generatorVersion": "3.9.2", + "flutterRoot": "file:///Users/juliandalcalaf/Development/flutter", + "flutterVersion": "3.35.7", + "pubCache": "file:///Users/juliandalcalaf/.pub-cache" +} diff --git a/.dart_tool/package_graph.json b/.dart_tool/package_graph.json new file mode 100644 index 00000000..c8198228 --- /dev/null +++ b/.dart_tool/package_graph.json @@ -0,0 +1,491 @@ +{ + "roots": [ + "sf_app_platform_mono_repo" + ], + "packages": [ + { + "name": "sf_app_platform_mono_repo", + "version": "0.0.0", + "dependencies": [ + "flutter_secure_storage" + ], + "devDependencies": [ + "melos" + ] + }, + { + "name": "flutter_secure_storage", + "version": "9.2.4", + "dependencies": [ + "flutter", + "flutter_secure_storage_linux", + "flutter_secure_storage_macos", + "flutter_secure_storage_platform_interface", + "flutter_secure_storage_web", + "flutter_secure_storage_windows", + "meta" + ] + }, + { + "name": "melos", + "version": "6.3.3", + "dependencies": [ + "ansi_styles", + "args", + "async", + "cli_launcher", + "cli_util", + "collection", + "conventional_commit", + "file", + "glob", + "graphs", + "http", + "meta", + "mustache_template", + "path", + "platform", + "pool", + "prompts", + "pub_semver", + "pub_updater", + "pubspec_parse", + "string_scanner", + "yaml", + "yaml_edit" + ] + }, + { + "name": "meta", + "version": "1.16.0", + "dependencies": [] + }, + { + "name": "flutter_secure_storage_windows", + "version": "3.1.2", + "dependencies": [ + "ffi", + "flutter", + "flutter_secure_storage_platform_interface", + "path", + "path_provider", + "win32" + ] + }, + { + "name": "flutter_secure_storage_web", + "version": "1.2.1", + "dependencies": [ + "flutter", + "flutter_secure_storage_platform_interface", + "flutter_web_plugins", + "js" + ] + }, + { + "name": "flutter_secure_storage_platform_interface", + "version": "1.1.2", + "dependencies": [ + "flutter", + "plugin_platform_interface" + ] + }, + { + "name": "flutter_secure_storage_macos", + "version": "3.1.3", + "dependencies": [ + "flutter", + "flutter_secure_storage_platform_interface" + ] + }, + { + "name": "flutter_secure_storage_linux", + "version": "1.2.3", + "dependencies": [ + "flutter", + "flutter_secure_storage_platform_interface" + ] + }, + { + "name": "flutter", + "version": "0.0.0", + "dependencies": [ + "characters", + "collection", + "material_color_utilities", + "meta", + "sky_engine", + "vector_math" + ] + }, + { + "name": "yaml_edit", + "version": "2.2.2", + "dependencies": [ + "collection", + "meta", + "source_span", + "yaml" + ] + }, + { + "name": "yaml", + "version": "3.1.3", + "dependencies": [ + "collection", + "source_span", + "string_scanner" + ] + }, + { + "name": "string_scanner", + "version": "1.4.1", + "dependencies": [ + "source_span" + ] + }, + { + "name": "pubspec_parse", + "version": "1.5.0", + "dependencies": [ + "checked_yaml", + "collection", + "json_annotation", + "pub_semver", + "yaml" + ] + }, + { + "name": "pub_updater", + "version": "0.5.0", + "dependencies": [ + "http", + "json_annotation", + "process", + "pub_semver" + ] + }, + { + "name": "pub_semver", + "version": "2.2.0", + "dependencies": [ + "collection" + ] + }, + { + "name": "prompts", + "version": "2.0.0", + "dependencies": [ + "charcode", + "io" + ] + }, + { + "name": "pool", + "version": "1.5.2", + "dependencies": [ + "async", + "stack_trace" + ] + }, + { + "name": "platform", + "version": "3.1.6", + "dependencies": [] + }, + { + "name": "path", + "version": "1.9.1", + "dependencies": [] + }, + { + "name": "mustache_template", + "version": "2.0.2", + "dependencies": [] + }, + { + "name": "http", + "version": "1.5.0", + "dependencies": [ + "async", + "http_parser", + "meta", + "web" + ] + }, + { + "name": "graphs", + "version": "2.3.2", + "dependencies": [ + "collection" + ] + }, + { + "name": "glob", + "version": "2.1.3", + "dependencies": [ + "async", + "collection", + "file", + "path", + "string_scanner" + ] + }, + { + "name": "file", + "version": "7.0.1", + "dependencies": [ + "meta", + "path" + ] + }, + { + "name": "conventional_commit", + "version": "0.6.1+1", + "dependencies": [] + }, + { + "name": "collection", + "version": "1.19.1", + "dependencies": [] + }, + { + "name": "cli_util", + "version": "0.4.2", + "dependencies": [ + "meta", + "path" + ] + }, + { + "name": "cli_launcher", + "version": "0.3.2+1", + "dependencies": [ + "path", + "yaml" + ] + }, + { + "name": "async", + "version": "2.13.0", + "dependencies": [ + "collection", + "meta" + ] + }, + { + "name": "args", + "version": "2.7.0", + "dependencies": [] + }, + { + "name": "ansi_styles", + "version": "0.3.2+1", + "dependencies": [] + }, + { + "name": "win32", + "version": "5.15.0", + "dependencies": [ + "ffi" + ] + }, + { + "name": "path_provider", + "version": "2.1.5", + "dependencies": [ + "flutter", + "path_provider_android", + "path_provider_foundation", + "path_provider_linux", + "path_provider_platform_interface", + "path_provider_windows" + ] + }, + { + "name": "ffi", + "version": "2.1.4", + "dependencies": [] + }, + { + "name": "js", + "version": "0.6.7", + "dependencies": [ + "meta" + ] + }, + { + "name": "flutter_web_plugins", + "version": "0.0.0", + "dependencies": [ + "flutter" + ] + }, + { + "name": "plugin_platform_interface", + "version": "2.1.8", + "dependencies": [ + "meta" + ] + }, + { + "name": "sky_engine", + "version": "0.0.0", + "dependencies": [] + }, + { + "name": "vector_math", + "version": "2.2.0", + "dependencies": [] + }, + { + "name": "material_color_utilities", + "version": "0.11.1", + "dependencies": [ + "collection" + ] + }, + { + "name": "characters", + "version": "1.4.0", + "dependencies": [] + }, + { + "name": "source_span", + "version": "1.10.1", + "dependencies": [ + "collection", + "path", + "term_glyph" + ] + }, + { + "name": "json_annotation", + "version": "4.9.0", + "dependencies": [ + "meta" + ] + }, + { + "name": "checked_yaml", + "version": "2.0.4", + "dependencies": [ + "json_annotation", + "source_span", + "yaml" + ] + }, + { + "name": "process", + "version": "5.0.5", + "dependencies": [ + "file", + "path", + "platform" + ] + }, + { + "name": "io", + "version": "1.0.5", + "dependencies": [ + "meta", + "path", + "string_scanner" + ] + }, + { + "name": "charcode", + "version": "1.4.0", + "dependencies": [] + }, + { + "name": "stack_trace", + "version": "1.12.1", + "dependencies": [ + "path" + ] + }, + { + "name": "web", + "version": "1.1.1", + "dependencies": [] + }, + { + "name": "http_parser", + "version": "4.1.2", + "dependencies": [ + "collection", + "source_span", + "string_scanner", + "typed_data" + ] + }, + { + "name": "path_provider_windows", + "version": "2.3.0", + "dependencies": [ + "ffi", + "flutter", + "path", + "path_provider_platform_interface" + ] + }, + { + "name": "path_provider_platform_interface", + "version": "2.1.2", + "dependencies": [ + "flutter", + "platform", + "plugin_platform_interface" + ] + }, + { + "name": "path_provider_linux", + "version": "2.2.1", + "dependencies": [ + "ffi", + "flutter", + "path", + "path_provider_platform_interface", + "xdg_directories" + ] + }, + { + "name": "path_provider_foundation", + "version": "2.4.3", + "dependencies": [ + "flutter", + "path_provider_platform_interface" + ] + }, + { + "name": "path_provider_android", + "version": "2.2.20", + "dependencies": [ + "flutter", + "path_provider_platform_interface" + ] + }, + { + "name": "term_glyph", + "version": "1.2.2", + "dependencies": [] + }, + { + "name": "typed_data", + "version": "1.4.0", + "dependencies": [ + "collection" + ] + }, + { + "name": "xdg_directories", + "version": "1.1.0", + "dependencies": [ + "meta", + "path" + ] + } + ], + "configVersion": 1 +} \ No newline at end of file diff --git a/.dart_tool/pub/bin/melos/melos.dart-3.9.2.snapshot b/.dart_tool/pub/bin/melos/melos.dart-3.9.2.snapshot new file mode 100644 index 00000000..4d144da8 Binary files /dev/null and b/.dart_tool/pub/bin/melos/melos.dart-3.9.2.snapshot differ diff --git a/.dart_tool/version b/.dart_tool/version new file mode 100644 index 00000000..e119acda --- /dev/null +++ b/.dart_tool/version @@ -0,0 +1 @@ +3.35.7 \ No newline at end of file diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies new file mode 100644 index 00000000..44e20093 --- /dev/null +++ b/.flutter-plugins-dependencies @@ -0,0 +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-12-04 12:33:12.174628","version":"3.35.7","swift_package_manager_enabled":{"ios":false,"macos":false}} \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml index 8b896c94..2c5bd550 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -11,6 +11,7 @@ + diff --git a/.idea/runConfigurations/melos_flutter_test_sf_infrastructure.xml b/.idea/runConfigurations/melos_flutter_test_sf_infrastructure.xml new file mode 100644 index 00000000..ad91e09b --- /dev/null +++ b/.idea/runConfigurations/melos_flutter_test_sf_infrastructure.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/apps/mobile_app/.env b/apps/mobile_app/.env new file mode 100644 index 00000000..f8131abf --- /dev/null +++ b/apps/mobile_app/.env @@ -0,0 +1 @@ +API_BASE_URL=https://api-neki-b2b.neki.es/gateway/api/ diff --git a/apps/mobile_app/lib/config/env/env.dart b/apps/mobile_app/lib/config/env/env.dart new file mode 100644 index 00000000..adaf9578 --- /dev/null +++ b/apps/mobile_app/lib/config/env/env.dart @@ -0,0 +1,7 @@ +import 'package:flutter_dotenv/flutter_dotenv.dart'; + +class Env { + static String get apiBaseUrl => dotenv.env['API_BASE_URL'] ?? ''; + + // static String get apiKey => dotenv.env['API_KEY'] ?? ''; +} diff --git a/apps/mobile_app/lib/config/env/questia_env_config.dart b/apps/mobile_app/lib/config/env/questia_env_config.dart new file mode 100644 index 00000000..fee4026c --- /dev/null +++ b/apps/mobile_app/lib/config/env/questia_env_config.dart @@ -0,0 +1,10 @@ +import 'package:sf_infrastructure/sf_infrastructure.dart'; +import 'env.dart'; + +class QuestiaEnvConfig implements EnvConfig { + @override + String get apiBaseUrl => Env.apiBaseUrl; + + // @override + // String get apiKey => Env.apiKey; +} diff --git a/apps/mobile_app/lib/main.dart b/apps/mobile_app/lib/main.dart index d609c0e7..8d3ebb5d 100644 --- a/apps/mobile_app/lib/main.dart +++ b/apps/mobile_app/lib/main.dart @@ -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 main() async { @@ -11,7 +15,9 @@ Future main() async { navigationModule(); configureAppRouter(); themePackages(); + await dotenv.load(fileName: '.env'); + await configureDependencies(QuestiaEnvConfig(), log: kDebugMode); runApp(const ProviderScope(child: PlatformApp())); } @@ -48,4 +54,4 @@ class PlatformApp extends ConsumerWidget { }, ); } -} \ No newline at end of file +} diff --git a/apps/mobile_app/lib/navigation/app_router.dart b/apps/mobile_app/lib/navigation/app_router.dart index 78155c03..237198d5 100644 --- a/apps/mobile_app/lib/navigation/app_router.dart +++ b/apps/mobile_app/lib/navigation/app_router.dart @@ -15,7 +15,7 @@ late final GoRouter appRouter; void configureAppRouter() { appRouter = GoRouter( navigatorKey: rootNavigatorKey, - initialLocation: AppRoutes.onboarding, + initialLocation: AppRoutes.linkPhone, debugLogDiagnostics: true, routes: [ GoRoute( diff --git a/apps/mobile_app/pubspec.lock b/apps/mobile_app/pubspec.lock index 5238aa8d..20e6e08c 100644 --- a/apps/mobile_app/pubspec.lock +++ b/apps/mobile_app/pubspec.lock @@ -214,6 +214,22 @@ packages: relative: true source: path version: "0.0.1" + 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 +275,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: @@ -597,6 +621,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: diff --git a/apps/mobile_app/pubspec.yaml b/apps/mobile_app/pubspec.yaml index 1960a01a..09555ae8 100644 --- a/apps/mobile_app/pubspec.yaml +++ b/apps/mobile_app/pubspec.yaml @@ -57,12 +57,15 @@ 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 dev_dependencies: flutter_test: @@ -89,7 +92,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 diff --git a/apps/mobile_app/pubspec_overrides.yaml b/apps/mobile_app/pubspec_overrides.yaml index 377c31a3..41f777ad 100644 --- a/apps/mobile_app/pubspec_overrides.yaml +++ b/apps/mobile_app/pubspec_overrides.yaml @@ -1,4 +1,4 @@ -# melos_managed_dependency_overrides: auth,dashboard_shell,design_system,home,navigation,notifications,profile,sf_shared,utils,sf_localizations,fonts +# 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 @@ -16,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: diff --git a/modules/auth/lib/auth.dart b/modules/auth/lib/auth.dart index 8f61929c..e425af89 100644 --- a/modules/auth/lib/auth.dart +++ b/modules/auth/lib/auth.dart @@ -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'; \ No newline at end of file +export 'src/features/device_sign_up/link_watch/create_profile_screen.dart'; +export 'src/features/onboarding/onboarding_builder.dart'; +export 'src/features/link_phone/link_phone_builder.dart'; +export 'src/features/login/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/signup_builder.dart'; diff --git a/modules/auth/lib/src/core/data/datasource/auth_remote_datasource.dart b/modules/auth/lib/src/core/data/datasource/auth_remote_datasource.dart new file mode 100644 index 00000000..573fcef8 --- /dev/null +++ b/modules/auth/lib/src/core/data/datasource/auth_remote_datasource.dart @@ -0,0 +1,5 @@ +abstract class AuthRemoteDatasource { + Future requestPhoneCode({required String phone}); + + Future verifyPhoneCode({required String phone, required String code}); +} diff --git a/modules/auth/lib/src/core/data/datasource/auth_remote_datasource_impl.dart b/modules/auth/lib/src/core/data/datasource/auth_remote_datasource_impl.dart new file mode 100644 index 00000000..80b14c6d --- /dev/null +++ b/modules/auth/lib/src/core/data/datasource/auth_remote_datasource_impl.dart @@ -0,0 +1,53 @@ +import 'package:dio/dio.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 requestPhoneCode({required String phone}) async { + try { + await _repository.post( + '/auth/link-phone/request-code', + body: {'phone': phone}, + ); + } on DioException catch (error) { + throw _mapDioError(error, defaultMessage: 'Error al solicitar el código'); + } + } + + @override + Future verifyPhoneCode({ + required String phone, + required String code, + }) async { + try { + await _repository.post( + '/auth/link-phone/verify-code', + body: {'phone': phone, 'code': code}, + ); + } on DioException catch (error) { + throw _mapDioError(error, defaultMessage: 'Error al verificar el código'); + } + } + + Exception _mapDioError(DioException error, {required String defaultMessage}) { + final responseData = error.response?.data; + String message = defaultMessage; + + if (responseData is Map) { + final serverMessage = responseData['message']; + if (serverMessage is String && serverMessage.isNotEmpty) { + message = serverMessage; + } + } else if (error.message != null && error.message!.isNotEmpty) { + message = error.message!; + } + + return Exception(message); + } +} diff --git a/modules/auth/lib/src/core/data/repositories/auth_repository_impl.dart b/modules/auth/lib/src/core/data/repositories/auth_repository_impl.dart new file mode 100644 index 00000000..127c6070 --- /dev/null +++ b/modules/auth/lib/src/core/data/repositories/auth_repository_impl.dart @@ -0,0 +1,18 @@ +import 'package:auth/src/core/data/datasource/auth_remote_datasource.dart'; +import 'package:auth/src/core/domain/repositories/auth_repository.dart'; + +class AuthRepositoryImpl implements AuthRepository { + const AuthRepositoryImpl(this._remote); + + final AuthRemoteDatasource _remote; + + @override + Future requestPhoneCode({required String phone}) { + return _remote.requestPhoneCode(phone: phone); + } + + @override + Future verifyPhoneCode({required String phone, required String code}) { + return _remote.verifyPhoneCode(phone: phone, code: code); + } +} diff --git a/modules/auth/lib/src/core/domain/repositories/auth_repository.dart b/modules/auth/lib/src/core/domain/repositories/auth_repository.dart new file mode 100644 index 00000000..4584b9db --- /dev/null +++ b/modules/auth/lib/src/core/domain/repositories/auth_repository.dart @@ -0,0 +1,5 @@ +abstract class AuthRepository { + Future requestPhoneCode({required String phone}); + + Future verifyPhoneCode({required String phone, required String code}); +} diff --git a/modules/auth/lib/src/core/providers/auth_remote_datasource_provider.dart b/modules/auth/lib/src/core/providers/auth_remote_datasource_provider.dart new file mode 100644 index 00000000..e4404b71 --- /dev/null +++ b/modules/auth/lib/src/core/providers/auth_remote_datasource_provider.dart @@ -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((ref) { + final questiaRepository = getIt(); + return AuthRemoteDatasourceImpl(questiaRepository); +}); diff --git a/modules/auth/lib/src/core/providers/auth_repository_provider.dart b/modules/auth/lib/src/core/providers/auth_repository_provider.dart new file mode 100644 index 00000000..c373a93a --- /dev/null +++ b/modules/auth/lib/src/core/providers/auth_repository_provider.dart @@ -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((ref) { + final remote = ref.read(authRemoteDatasourceProvider); + return AuthRepositoryImpl(remote); +}); diff --git a/modules/auth/lib/src/device_sign_up/add_kid_screen.dart b/modules/auth/lib/src/features/device_sign_up/add_kid_screen.dart similarity index 100% rename from modules/auth/lib/src/device_sign_up/add_kid_screen.dart rename to modules/auth/lib/src/features/device_sign_up/add_kid_screen.dart diff --git a/modules/auth/lib/src/device_sign_up/contact_screen.dart b/modules/auth/lib/src/features/device_sign_up/contact_screen.dart similarity index 100% rename from modules/auth/lib/src/device_sign_up/contact_screen.dart rename to modules/auth/lib/src/features/device_sign_up/contact_screen.dart diff --git a/modules/auth/lib/src/device_sign_up/device_signup_builder.dart b/modules/auth/lib/src/features/device_sign_up/device_signup_builder.dart similarity index 87% rename from modules/auth/lib/src/device_sign_up/device_signup_builder.dart rename to modules/auth/lib/src/features/device_sign_up/device_signup_builder.dart index f9ed93c6..d2f648ff 100644 --- a/modules/auth/lib/src/device_sign_up/device_signup_builder.dart +++ b/modules/auth/lib/src/features/device_sign_up/device_signup_builder.dart @@ -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'; diff --git a/modules/auth/lib/src/device_sign_up/device_signup_screen.dart b/modules/auth/lib/src/features/device_sign_up/device_signup_screen.dart similarity index 51% rename from modules/auth/lib/src/device_sign_up/device_signup_screen.dart rename to modules/auth/lib/src/features/device_sign_up/device_signup_screen.dart index 65a8fdd8..2db8e906 100644 --- a/modules/auth/lib/src/device_sign_up/device_signup_screen.dart +++ b/modules/auth/lib/src/features/device_sign_up/device_signup_screen.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/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 createState() => DeviceSignupScreenState(navigationContract); + ConsumerState createState() => + DeviceSignupScreenState(navigationContract); } -class DeviceSignupScreenState extends ConsumerState{ +class DeviceSignupScreenState extends ConsumerState { late int currentStep; final NavigationContract navigationContract; @@ -34,37 +35,46 @@ class DeviceSignupScreenState extends ConsumerState{ return getSteps()[currentStep]; } - List getSteps(){ + List 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,31 @@ class DeviceSignupScreenState extends ConsumerState{ 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, kidAccount: true) ]; } -} \ No newline at end of file +} diff --git a/modules/auth/lib/src/device_sign_up/link_watch/create_profile_screen.dart b/modules/auth/lib/src/features/device_sign_up/link_watch/create_profile_screen.dart similarity index 100% rename from modules/auth/lib/src/device_sign_up/link_watch/create_profile_screen.dart rename to modules/auth/lib/src/features/device_sign_up/link_watch/create_profile_screen.dart diff --git a/modules/auth/lib/src/device_sign_up/link_watch/link_watch_previous_screen.dart b/modules/auth/lib/src/features/device_sign_up/link_watch/link_watch_previous_screen.dart similarity index 100% rename from modules/auth/lib/src/device_sign_up/link_watch/link_watch_previous_screen.dart rename to modules/auth/lib/src/features/device_sign_up/link_watch/link_watch_previous_screen.dart diff --git a/modules/auth/lib/src/device_sign_up/link_watch/link_watch_screen.dart b/modules/auth/lib/src/features/device_sign_up/link_watch/link_watch_screen.dart similarity index 100% rename from modules/auth/lib/src/device_sign_up/link_watch/link_watch_screen.dart rename to modules/auth/lib/src/features/device_sign_up/link_watch/link_watch_screen.dart diff --git a/modules/auth/lib/src/features/link_phone/domain/use_cases/link_phone_use_case.dart b/modules/auth/lib/src/features/link_phone/domain/use_cases/link_phone_use_case.dart new file mode 100644 index 00000000..fd7fce0e --- /dev/null +++ b/modules/auth/lib/src/features/link_phone/domain/use_cases/link_phone_use_case.dart @@ -0,0 +1,5 @@ +abstract class LinkPhoneUseCase { + Future requestCode({required String phone}); + + Future verifyCode({required String phone, required String code}); +} diff --git a/modules/auth/lib/src/features/link_phone/domain/use_cases/link_phone_use_case_impl.dart b/modules/auth/lib/src/features/link_phone/domain/use_cases/link_phone_use_case_impl.dart new file mode 100644 index 00000000..18e3c34e --- /dev/null +++ b/modules/auth/lib/src/features/link_phone/domain/use_cases/link_phone_use_case_impl.dart @@ -0,0 +1,18 @@ +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 requestCode({required String phone}) { + return _repository.requestPhoneCode(phone: phone); + } + + @override + Future verifyCode({required String phone, required String code}) { + return _repository.verifyPhoneCode(phone: phone, code: code); + } +} diff --git a/modules/auth/lib/src/login/link_phone_builder.dart b/modules/auth/lib/src/features/link_phone/link_phone_builder.dart similarity index 86% rename from modules/auth/lib/src/login/link_phone_builder.dart rename to modules/auth/lib/src/features/link_phone/link_phone_builder.dart index ee261810..543f46e5 100644 --- a/modules/auth/lib/src/login/link_phone_builder.dart +++ b/modules/auth/lib/src/features/link_phone/link_phone_builder.dart @@ -1,4 +1,4 @@ -import 'package:auth/src/login/presentation/link_phone_screen.dart'; +import 'package:auth/src/features/link_phone/presentation/link_phone_screen.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:get_it/get_it.dart'; diff --git a/modules/auth/lib/src/features/link_phone/presentation/link_phone_screen.dart b/modules/auth/lib/src/features/link_phone/presentation/link_phone_screen.dart new file mode 100644 index 00000000..938d7a71 --- /dev/null +++ b/modules/auth/lib/src/features/link_phone/presentation/link_phone_screen.dart @@ -0,0 +1,114 @@ +import 'package:auth/src/features/link_phone/presentation/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 LinkPhoneScreen extends ConsumerWidget { + final NavigationContract navigationContract; + + const LinkPhoneScreen({super.key, required this.navigationContract}); + + void _onCountryChanged(int? value) {} + + @override + Widget build(BuildContext context, WidgetRef ref) { + final theme = ref.watch(themePortProvider); + + final viewModel = ref.watch(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: [ + CustomDropdown( + value: 0, + items: const [ + Icon(Icons.outlined_flag), + Icon(Icons.outlined_flag), + Icon(Icons.outlined_flag), + ], + onChanged: _onCountryChanged, + width: 80, + ), + Expanded( + child: CustomTextField( + // controller: viewModel.phoneNumberController, + hint: context.translate(I18n.phoneNumber), + numeric: true, + ), + ), + ], + ), + ], + ), + + const SizedBox(height: 16), + + if (viewState.errorMessage?.isNotEmpty ?? false) ...[ + const SizedBox(height: 4), + Text( + // context.translate(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), + ), + ], + ), + ), + ); + } +} diff --git a/modules/auth/lib/src/features/link_phone/presentation/link_phone_view_model.dart b/modules/auth/lib/src/features/link_phone/presentation/link_phone_view_model.dart new file mode 100644 index 00000000..c921380f --- /dev/null +++ b/modules/auth/lib/src/features/link_phone/presentation/link_phone_view_model.dart @@ -0,0 +1,61 @@ +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/link_phone_view_state.dart'; + +final linkPhoneViewModelProvider = + NotifierProvider.autoDispose( + LinkPhoneViewModel.new, + ); + +class LinkPhoneViewModel extends Notifier { + late final LinkPhoneUseCase _linkPhoneUseCase; + late final TextEditingController phoneNumberController; + + @override + LinkPhoneViewState build() { + _linkPhoneUseCase = ref.read(linkPhoneUseCaseProvider); + phoneNumberController = TextEditingController(); + phoneNumberController.addListener(_onPhoneNumberChanged); + ref.onDispose(disposeControllers); + return const LinkPhoneViewState(); + } + + void _onPhoneNumberChanged() { + final raw = phoneNumberController.text; + + state = state.copyWith(phoneNumber: raw, errorMessage: ''); + } + + Future requestCode() async { + final phone = phoneNumberController.text.trim(); + + if (phone.isEmpty) { + state = state.copyWith(errorMessage: 'El teléfono no puede estar vacío'); + return; + } + + state = state.copyWith(isLoading: true, errorMessage: ''); + + try { + await _linkPhoneUseCase.requestCode(phone: phone); + 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()); + } + } + + void disposeControllers() { + phoneNumberController.removeListener(_onPhoneNumberChanged); + phoneNumberController.dispose(); + } +} diff --git a/modules/auth/lib/src/features/link_phone/presentation/link_phone_view_state.dart b/modules/auth/lib/src/features/link_phone/presentation/link_phone_view_state.dart new file mode 100644 index 00000000..3d194348 --- /dev/null +++ b/modules/auth/lib/src/features/link_phone/presentation/link_phone_view_state.dart @@ -0,0 +1,13 @@ +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, + String? errorMessage, + @Default(false) bool isLoading, + @Default(false) bool codeRequested, + }) = _LinkPhoneViewState; +} diff --git a/modules/auth/lib/src/features/link_phone/presentation/link_phone_view_state.freezed.dart b/modules/auth/lib/src/features/link_phone/presentation/link_phone_view_state.freezed.dart new file mode 100644 index 00000000..1159a82f --- /dev/null +++ b/modules/auth/lib/src/features/link_phone/presentation/link_phone_view_state.freezed.dart @@ -0,0 +1,280 @@ +// 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 value) => value; +/// @nodoc +mixin _$LinkPhoneViewState { + + String get phoneNumber; String? get errorMessage; bool get isLoading; bool get codeRequested; +/// 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 get copyWith => _$LinkPhoneViewStateCopyWithImpl(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.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.codeRequested, codeRequested) || other.codeRequested == codeRequested)); +} + + +@override +int get hashCode => Object.hash(runtimeType,phoneNumber,errorMessage,isLoading,codeRequested); + +@override +String toString() { + return 'LinkPhoneViewState(phoneNumber: $phoneNumber, errorMessage: $errorMessage, isLoading: $isLoading, codeRequested: $codeRequested)'; +} + + +} + +/// @nodoc +abstract mixin class $LinkPhoneViewStateCopyWith<$Res> { + factory $LinkPhoneViewStateCopyWith(LinkPhoneViewState value, $Res Function(LinkPhoneViewState) _then) = _$LinkPhoneViewStateCopyWithImpl; +@useResult +$Res call({ + String phoneNumber, String? errorMessage, bool isLoading, bool codeRequested +}); + + + + +} +/// @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? errorMessage = freezed,Object? isLoading = null,Object? codeRequested = null,}) { + return _then(_self.copyWith( +phoneNumber: null == phoneNumber ? _self.phoneNumber : phoneNumber // ignore: cast_nullable_to_non_nullable +as String,errorMessage: freezed == 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, + )); +} + +} + + +/// 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 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 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? 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 Function( String phoneNumber, String? errorMessage, bool isLoading, bool codeRequested)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _LinkPhoneViewState() when $default != null: +return $default(_that.phoneNumber,_that.errorMessage,_that.isLoading,_that.codeRequested);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 Function( String phoneNumber, String? errorMessage, bool isLoading, bool codeRequested) $default,) {final _that = this; +switch (_that) { +case _LinkPhoneViewState(): +return $default(_that.phoneNumber,_that.errorMessage,_that.isLoading,_that.codeRequested);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? Function( String phoneNumber, String? errorMessage, bool isLoading, bool codeRequested)? $default,) {final _that = this; +switch (_that) { +case _LinkPhoneViewState() when $default != null: +return $default(_that.phoneNumber,_that.errorMessage,_that.isLoading,_that.codeRequested);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _LinkPhoneViewState implements LinkPhoneViewState { + const _LinkPhoneViewState({this.phoneNumber = '', this.errorMessage, this.isLoading = false, this.codeRequested = false}); + + +@override@JsonKey() final String phoneNumber; +@override final String? errorMessage; +@override@JsonKey() final bool isLoading; +@override@JsonKey() final bool codeRequested; + +/// 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.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.codeRequested, codeRequested) || other.codeRequested == codeRequested)); +} + + +@override +int get hashCode => Object.hash(runtimeType,phoneNumber,errorMessage,isLoading,codeRequested); + +@override +String toString() { + return 'LinkPhoneViewState(phoneNumber: $phoneNumber, errorMessage: $errorMessage, isLoading: $isLoading, codeRequested: $codeRequested)'; +} + + +} + +/// @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? errorMessage, bool isLoading, bool codeRequested +}); + + + + +} +/// @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? errorMessage = freezed,Object? isLoading = null,Object? codeRequested = null,}) { + return _then(_LinkPhoneViewState( +phoneNumber: null == phoneNumber ? _self.phoneNumber : phoneNumber // ignore: cast_nullable_to_non_nullable +as String,errorMessage: freezed == 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, + )); +} + + +} + +// dart format on diff --git a/modules/auth/lib/src/features/link_phone/presentation/providers/link_phone_provider.dart b/modules/auth/lib/src/features/link_phone/presentation/providers/link_phone_provider.dart new file mode 100644 index 00000000..e0ceebc3 --- /dev/null +++ b/modules/auth/lib/src/features/link_phone/presentation/providers/link_phone_provider.dart @@ -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((ref) { + final authRepository = ref.read(authRepositoryProvider); + return LinkPhoneUseCaseImpl(authRepository); +}); diff --git a/modules/auth/lib/src/login/login_builder.dart b/modules/auth/lib/src/features/login/login_builder.dart similarity index 87% rename from modules/auth/lib/src/login/login_builder.dart rename to modules/auth/lib/src/features/login/login_builder.dart index c72a184e..3d6b349d 100644 --- a/modules/auth/lib/src/login/login_builder.dart +++ b/modules/auth/lib/src/features/login/login_builder.dart @@ -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'; diff --git a/modules/auth/lib/src/login/phone_code_builder.dart b/modules/auth/lib/src/features/login/phone_code_builder.dart similarity index 86% rename from modules/auth/lib/src/login/phone_code_builder.dart rename to modules/auth/lib/src/features/login/phone_code_builder.dart index 47a63946..e8a31e24 100644 --- a/modules/auth/lib/src/login/phone_code_builder.dart +++ b/modules/auth/lib/src/features/login/phone_code_builder.dart @@ -1,4 +1,4 @@ -import 'package:auth/src/login/presentation/phone_code_screen.dart'; +import 'package:auth/src/features/login/presentation/phone_code_screen.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:get_it/get_it.dart'; diff --git a/modules/auth/lib/src/login/presentation/loading_google_screen.dart b/modules/auth/lib/src/features/login/presentation/loading_google_screen.dart similarity index 100% rename from modules/auth/lib/src/login/presentation/loading_google_screen.dart rename to modules/auth/lib/src/features/login/presentation/loading_google_screen.dart diff --git a/modules/auth/lib/src/login/presentation/loading_screen.dart b/modules/auth/lib/src/features/login/presentation/loading_screen.dart similarity index 100% rename from modules/auth/lib/src/login/presentation/loading_screen.dart rename to modules/auth/lib/src/features/login/presentation/loading_screen.dart diff --git a/modules/auth/lib/src/login/presentation/login_screen.dart b/modules/auth/lib/src/features/login/presentation/login_screen.dart similarity index 70% rename from modules/auth/lib/src/login/presentation/login_screen.dart rename to modules/auth/lib/src/features/login/presentation/login_screen.dart index 3cf9cdfe..9758e619 100644 --- a/modules/auth/lib/src/login/presentation/login_screen.dart +++ b/modules/auth/lib/src/features/login/presentation/login_screen.dart @@ -1,5 +1,5 @@ -import 'package:auth/src/login/presentation/loading_google_screen.dart'; -import 'package:auth/src/sign_up/signup_screen.dart'; +import 'package:auth/src/features/login/presentation/loading_google_screen.dart'; +import 'package:auth/src/features/sign_up/signup_screen.dart'; import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; @@ -15,7 +15,7 @@ class LoginScreen extends ConsumerStatefulWidget { ConsumerState createState() => _LoginScreenState(); } -class _LoginScreenState extends ConsumerState{ +class _LoginScreenState extends ConsumerState { bool passwordVisible = false; @override @@ -28,7 +28,11 @@ class _LoginScreenState extends ConsumerState{ Column( spacing: 8, children: [ - Icon(Icons.check, color: theme.getColorFor(ThemeCode.buttonPrimary), size: 50), + Icon( + Icons.check, + color: theme.getColorFor(ThemeCode.buttonPrimary), + size: 50, + ), Text( // context.translate(I18n.example) "¡Te damos la bienvenida!", @@ -51,43 +55,48 @@ class _LoginScreenState extends ConsumerState{ spacing: 12, children: [ CustomTextField( - showPassword: passwordVisible, - label: "Contraseña", - hint: "********" + showPassword: passwordVisible, + label: "Contraseña", + hint: "********", ), Align( alignment: Alignment.topLeft, child: CustomTextButton( text: "¿Has olvidado la contraseña?", - onPressed: () => - widget.navigationContract.pushTo(AppRoutes.recoverPassword), + onPressed: () => widget.navigationContract.pushTo( + AppRoutes.recoverPassword, + ), size: 16, - )), + ), + ), ], - ) + ), ], ), PrimaryButton( - onPressed: () => widget.navigationContract.goTo(AppRoutes.dashboardHome), - text: "Iniciar sesión", - color: theme.getColorFor(ThemeCode.buttonPrimary) + onPressed: () => + widget.navigationContract.goTo(AppRoutes.dashboardHome), + text: "Iniciar sesión", + color: theme.getColorFor(ThemeCode.buttonPrimary), ), Container( padding: EdgeInsets.only(top: 24), child: Column( spacing: 24, children: [ - Stack(children: [ - Divider(endIndent: 74, indent: 74), - Align( + Stack( + children: [ + Divider(endIndent: 74, indent: 74), + Align( alignment: Alignment.center, child: Container( padding: const EdgeInsets.symmetric(horizontal: 14), color: theme.getColorFor(ThemeCode.backgroundPrimary), child: Text("o continúa con"), - ) - ) - ]), + ), + ), + ], + ), Row( spacing: 20, children: [ @@ -105,7 +114,7 @@ class _LoginScreenState extends ConsumerState{ label: "Google", ), SecondaryButton( - onPressed: ()=>{}, + onPressed: () => {}, radius: 16, padding: 44, icon: Icons.apple, @@ -121,18 +130,23 @@ class _LoginScreenState extends ConsumerState{ spacing: 8, children: [ Text( - "¿No tienes cuenta?", - style: TextStyle(fontSize: 18, letterSpacing: 0) + "¿No tienes cuenta?", + style: TextStyle(fontSize: 18, letterSpacing: 0), ), TextButton( - onPressed: () => widget.navigationContract.goTo(AppRoutes.signup), + onPressed: () => + widget.navigationContract.goTo(AppRoutes.signup), child: Text( "Crear una ahora", - style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500, letterSpacing: 0) - ) + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w500, + letterSpacing: 0, + ), + ), ), ], - ) + ), ], ), ]; @@ -153,8 +167,8 @@ class _LoginScreenState extends ConsumerState{ itemCount: content.length, ), ), - ) - ) + ), + ), ); } } diff --git a/modules/auth/lib/src/login/presentation/phone_code_screen.dart b/modules/auth/lib/src/features/login/presentation/phone_code_screen.dart similarity index 84% rename from modules/auth/lib/src/login/presentation/phone_code_screen.dart rename to modules/auth/lib/src/features/login/presentation/phone_code_screen.dart index 9ee6c3e1..5a8f4b71 100644 --- a/modules/auth/lib/src/login/presentation/phone_code_screen.dart +++ b/modules/auth/lib/src/features/login/presentation/phone_code_screen.dart @@ -5,12 +5,10 @@ import 'package:navigation/navigation.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; class PhoneCodeScreen extends ConsumerWidget { - // final String phone; final NavigationContract navigationContract; PhoneCodeScreen({super.key, required this.navigationContract}); - // class PhoneCodeScreenState extends State { final focusNodes = List.generate(6, (int i) { return FocusNode(); }); @@ -34,7 +32,10 @@ class PhoneCodeScreen extends ConsumerWidget { children: [ Text( "Conéctate", - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30), + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 30, + ), ), Text.rich( TextSpan( @@ -55,7 +56,9 @@ class PhoneCodeScreen extends ConsumerWidget { child: TextField( focusNode: focusNodes[i], keyboardType: TextInputType.number, - inputFormatters: [FilteringTextInputFormatter.digitsOnly], + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + ], textAlign: TextAlign.center, decoration: InputDecoration( hintText: "0", @@ -78,7 +81,9 @@ class PhoneCodeScreen extends ConsumerWidget { spacing: 24, children: [ PrimaryButton( - onPressed: () => {navigationContract.pushTo(AppRoutes.login)}, + onPressed: () => { + navigationContract.pushTo(AppRoutes.login), + }, text: "Entrar", color: theme.getColorFor(ThemeCode.buttonPrimary), ), @@ -87,7 +92,11 @@ class PhoneCodeScreen extends ConsumerWidget { children: [ Text( "¿No lo has recibido?", - style: TextStyle(fontSize: 18, letterSpacing: 0, height: 1.5), + style: TextStyle( + fontSize: 18, + letterSpacing: 0, + height: 1.5, + ), ), CustomTextButton( onPressed: () => {}, @@ -96,7 +105,7 @@ class PhoneCodeScreen extends ConsumerWidget { weight: FontWeight.w500, ), ], - ) + ), ], ), Spacer(flex: 10), diff --git a/modules/auth/lib/src/onboarding/domain/onboarding_page.dart b/modules/auth/lib/src/features/onboarding/domain/onboarding_page.dart similarity index 100% rename from modules/auth/lib/src/onboarding/domain/onboarding_page.dart rename to modules/auth/lib/src/features/onboarding/domain/onboarding_page.dart diff --git a/modules/auth/lib/src/onboarding/onboarding_builder.dart b/modules/auth/lib/src/features/onboarding/onboarding_builder.dart similarity index 86% rename from modules/auth/lib/src/onboarding/onboarding_builder.dart rename to modules/auth/lib/src/features/onboarding/onboarding_builder.dart index 45c469ec..b313931e 100644 --- a/modules/auth/lib/src/onboarding/onboarding_builder.dart +++ b/modules/auth/lib/src/features/onboarding/onboarding_builder.dart @@ -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'; diff --git a/modules/auth/lib/src/features/onboarding/presentation/onboarding_screen.dart b/modules/auth/lib/src/features/onboarding/presentation/onboarding_screen.dart new file mode 100644 index 00000000..a263d04c --- /dev/null +++ b/modules/auth/lib/src/features/onboarding/presentation/onboarding_screen.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(( + 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), + ], + ), + ), + ); + } +} diff --git a/modules/auth/lib/src/onboarding/presentation/onboarding_view_model.dart b/modules/auth/lib/src/features/onboarding/presentation/onboarding_view_model.dart similarity index 83% rename from modules/auth/lib/src/onboarding/presentation/onboarding_view_model.dart rename to modules/auth/lib/src/features/onboarding/presentation/onboarding_view_model.dart index 640e645d..426bf412 100644 --- a/modules/auth/lib/src/onboarding/presentation/onboarding_view_model.dart +++ b/modules/auth/lib/src/features/onboarding/presentation/onboarding_view_model.dart @@ -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( diff --git a/modules/auth/lib/src/onboarding/presentation/onboarding_view_state.dart b/modules/auth/lib/src/features/onboarding/presentation/onboarding_view_state.dart similarity index 100% rename from modules/auth/lib/src/onboarding/presentation/onboarding_view_state.dart rename to modules/auth/lib/src/features/onboarding/presentation/onboarding_view_state.dart diff --git a/modules/auth/lib/src/onboarding/presentation/onboarding_view_state.freezed.dart b/modules/auth/lib/src/features/onboarding/presentation/onboarding_view_state.freezed.dart similarity index 100% rename from modules/auth/lib/src/onboarding/presentation/onboarding_view_state.freezed.dart rename to modules/auth/lib/src/features/onboarding/presentation/onboarding_view_state.freezed.dart diff --git a/modules/auth/lib/src/onboarding/presentation/welcome_screen.dart b/modules/auth/lib/src/features/onboarding/presentation/welcome_screen.dart similarity index 100% rename from modules/auth/lib/src/onboarding/presentation/welcome_screen.dart rename to modules/auth/lib/src/features/onboarding/presentation/welcome_screen.dart diff --git a/modules/auth/lib/src/onboarding/presentation/widgets/onboarding_content.dart b/modules/auth/lib/src/features/onboarding/presentation/widgets/onboarding_content.dart similarity index 100% rename from modules/auth/lib/src/onboarding/presentation/widgets/onboarding_content.dart rename to modules/auth/lib/src/features/onboarding/presentation/widgets/onboarding_content.dart diff --git a/modules/auth/lib/src/recover_password/presentation/new_password_screen.dart b/modules/auth/lib/src/features/recover_password/presentation/new_password_screen.dart similarity index 100% rename from modules/auth/lib/src/recover_password/presentation/new_password_screen.dart rename to modules/auth/lib/src/features/recover_password/presentation/new_password_screen.dart diff --git a/modules/auth/lib/src/recover_password/presentation/restore_password_screen.dart b/modules/auth/lib/src/features/recover_password/presentation/restore_password_screen.dart similarity index 72% rename from modules/auth/lib/src/recover_password/presentation/restore_password_screen.dart rename to modules/auth/lib/src/features/recover_password/presentation/restore_password_screen.dart index c3f1bfcd..7068801f 100644 --- a/modules/auth/lib/src/recover_password/presentation/restore_password_screen.dart +++ b/modules/auth/lib/src/features/recover_password/presentation/restore_password_screen.dart @@ -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", + numeric: true, + ), ), ], ), @@ -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), + ), + ), ], ), ], diff --git a/modules/auth/lib/src/recover_password/presentation/sent_screen.dart b/modules/auth/lib/src/features/recover_password/presentation/sent_screen.dart similarity index 59% rename from modules/auth/lib/src/recover_password/presentation/sent_screen.dart rename to modules/auth/lib/src/features/recover_password/presentation/sent_screen.dart index 2dc4e3f6..f386c359 100644 --- a/modules/auth/lib/src/recover_password/presentation/sent_screen.dart +++ b/modules/auth/lib/src/features/recover_password/presentation/sent_screen.dart @@ -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), ), ), ], diff --git a/modules/auth/lib/src/recover_password/recover_password_builder.dart b/modules/auth/lib/src/features/recover_password/recover_password_builder.dart similarity index 84% rename from modules/auth/lib/src/recover_password/recover_password_builder.dart rename to modules/auth/lib/src/features/recover_password/recover_password_builder.dart index 9741c4fc..930f53ba 100644 --- a/modules/auth/lib/src/recover_password/recover_password_builder.dart +++ b/modules/auth/lib/src/features/recover_password/recover_password_builder.dart @@ -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'; diff --git a/modules/auth/lib/src/sign_up/account_created_screen.dart b/modules/auth/lib/src/features/sign_up/account_created_screen.dart similarity index 100% rename from modules/auth/lib/src/sign_up/account_created_screen.dart rename to modules/auth/lib/src/features/sign_up/account_created_screen.dart diff --git a/modules/auth/lib/src/sign_up/signup_address_screen.dart b/modules/auth/lib/src/features/sign_up/signup_address_screen.dart similarity index 100% rename from modules/auth/lib/src/sign_up/signup_address_screen.dart rename to modules/auth/lib/src/features/sign_up/signup_address_screen.dart diff --git a/modules/auth/lib/src/sign_up/signup_builder.dart b/modules/auth/lib/src/features/sign_up/signup_builder.dart similarity index 88% rename from modules/auth/lib/src/sign_up/signup_builder.dart rename to modules/auth/lib/src/features/sign_up/signup_builder.dart index 4356b0b7..70834e73 100644 --- a/modules/auth/lib/src/sign_up/signup_builder.dart +++ b/modules/auth/lib/src/features/sign_up/signup_builder.dart @@ -1,4 +1,4 @@ -import 'package:auth/src/sign_up/signup_screen.dart'; +import 'package:auth/src/features/sign_up/signup_screen.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:get_it/get_it.dart'; diff --git a/modules/auth/lib/src/sign_up/signup_personal_screen.dart b/modules/auth/lib/src/features/sign_up/signup_personal_screen.dart similarity index 100% rename from modules/auth/lib/src/sign_up/signup_personal_screen.dart rename to modules/auth/lib/src/features/sign_up/signup_personal_screen.dart diff --git a/modules/auth/lib/src/sign_up/signup_screen.dart b/modules/auth/lib/src/features/sign_up/signup_screen.dart similarity index 50% rename from modules/auth/lib/src/sign_up/signup_screen.dart rename to modules/auth/lib/src/features/sign_up/signup_screen.dart index 6de7de56..e1fdc9f9 100644 --- a/modules/auth/lib/src/sign_up/signup_screen.dart +++ b/modules/auth/lib/src/features/sign_up/signup_screen.dart @@ -1,9 +1,9 @@ import 'package:auth/src/widgets/layouts/form_step_layout.dart'; import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; -import 'package:auth/src/sign_up/signup_address_screen.dart'; -import 'package:auth/src/sign_up/signup_personal_screen.dart'; -import 'package:auth/src/sign_up/signup_user_screen.dart'; +import 'package:auth/src/features/sign_up/signup_address_screen.dart'; +import 'package:auth/src/features/sign_up/signup_personal_screen.dart'; +import 'package:auth/src/features/sign_up/signup_user_screen.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:get_it/get_it.dart'; import 'package:navigation/navigation.dart'; @@ -13,10 +13,7 @@ import 'account_created_screen.dart'; class SignupScreen extends ConsumerStatefulWidget { NavigationContract navigationContract; - SignupScreen({ - super.key, - required this.navigationContract - }); + SignupScreen({super.key, required this.navigationContract}); @override ConsumerState createState() => _SignupScreenState(); @@ -37,8 +34,9 @@ class _SignupScreenState extends ConsumerState { return [ FormStepLayout( title: "Crea tu usuario", - subtitle: "Con tu email y tu número podremos mantenerte siempre informado", - supertitle: "Usuario y contacto", + subtitle: + "Con tu email y tu número podremos mantenerte siempre informado", + supertitle: "Usuario y contacto", currentStep: 1, numSteps: 3, body: [SignupPersonalScreen()], @@ -46,20 +44,26 @@ class _SignupScreenState extends ConsumerState { Row( spacing: 16, children: [ - Expanded(child: SecondaryButton( - onPressed: ()=>{}, - text: "Atrás", - size: 16, - )), - Expanded(child: PrimaryButton( - onPressed: ()=>{setState(() { - currentStep++; - })}, - text: "Siguiente", - size: 16, - color: theme.getColorFor(ThemeCode.buttonSecondary) - )) - ] + Expanded( + child: SecondaryButton( + onPressed: () => {}, + text: "Atrás", + size: 16, + ), + ), + Expanded( + child: PrimaryButton( + onPressed: () => { + setState(() { + currentStep++; + }), + }, + text: "Siguiente", + size: 16, + color: theme.getColorFor(ThemeCode.buttonSecondary), + ), + ), + ], ), CheckboxListTile( value: acceptTerms, @@ -74,42 +78,57 @@ class _SignupScreenState extends ConsumerState { contentPadding: EdgeInsets.zero, activeColor: theme.getColorFor(ThemeCode.buttonPrimary), controlAffinity: ListTileControlAffinity.leading, - ) + ), ], - nextStep: ()=>{setState(() { - currentStep++; - })}, - previousStep: ()=>{}, + nextStep: () => { + setState(() { + currentStep++; + }), + }, + previousStep: () => {}, ), FormStepLayout( title: "Tu dirección", - subtitle: "Tu dirección nos ayudará a verificar y mantener la seguridad de tu cuenta", + subtitle: + "Tu dirección nos ayudará a verificar y mantener la seguridad de tu cuenta", supertitle: "Domicilio", currentStep: 2, numSteps: 3, body: [SignupAddressScreen()], - nextStep: ()=>{setState(() { - currentStep++; - })}, - previousStep: ()=>{setState(() { - currentStep--; - })}, + nextStep: () => { + setState(() { + currentStep++; + }), + }, + previousStep: () => { + setState(() { + currentStep--; + }), + }, ), FormStepLayout( title: "Identifícate", - subtitle: "Contraseña mínima de 8 caracteres, con una mayúscula, un número y un carácter especial", + subtitle: + "Contraseña mínima de 8 caracteres, con una mayúscula, un número y un carácter especial", supertitle: "Usuario y contacto", currentStep: 3, numSteps: 3, body: [SignupUserScreen()], - nextStep: ()=>{setState(() { - currentStep++; - })}, - previousStep: ()=>{setState(() { - currentStep--; - })}, + nextStep: () => { + setState(() { + currentStep++; + }), + }, + previousStep: () => { + setState(() { + currentStep--; + }), + }, + ), + AccountCreatedScreen( + navigationContract: widget.navigationContract, + kidAccount: false, ), - AccountCreatedScreen(navigationContract: widget.navigationContract, kidAccount: false) ]; } } diff --git a/modules/auth/lib/src/sign_up/signup_user_screen.dart b/modules/auth/lib/src/features/sign_up/signup_user_screen.dart similarity index 100% rename from modules/auth/lib/src/sign_up/signup_user_screen.dart rename to modules/auth/lib/src/features/sign_up/signup_user_screen.dart diff --git a/modules/auth/lib/src/login/presentation/link_phone_screen.dart b/modules/auth/lib/src/login/presentation/link_phone_screen.dart deleted file mode 100644 index 79e2bea6..00000000 --- a/modules/auth/lib/src/login/presentation/link_phone_screen.dart +++ /dev/null @@ -1,78 +0,0 @@ -import 'package:design_system/design_system.dart'; -import 'package:flutter/material.dart'; -import 'package:navigation/navigation.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; - -class LinkPhoneScreen extends ConsumerWidget { - final NavigationContract navigationContract; - - const LinkPhoneScreen({super.key, required this.navigationContract}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final theme = ref.watch(themePortProvider); - - // TextEditingController phoneController = TextEditingController(); - // String? phone; - - return Scaffold( - backgroundColor: theme.getColorFor(ThemeCode.backgroundPrimary), - body: SafeArea( - child: Container( - margin: EdgeInsets.symmetric(horizontal: 24), - child: Expanded( - child: Center( - child: Column( - spacing: 48, - children: [ - Spacer(flex: 8), - Text( - "¡Nos alegra mucho tenerte por aquí!", - textAlign: TextAlign.center, - style: TextStyle(fontSize: 30, fontWeight: FontWeight.w500, letterSpacing: 0), - ), - Text( - "Para poder entrar de forma segura, te vamos a enviar un código al teléfono", - textAlign: TextAlign.center, - style: TextStyle(fontSize: 16, letterSpacing: 0), - ), - Column( - spacing: 8, - children: [ - Align(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)=> {}, - width: 80, - ), - Expanded( - child: CustomTextField( - hint: "Teléfono", - numeric: true - ) - ), - ], - ), - ], - ), - PrimaryButton( - onPressed: () => navigationContract.pushTo(AppRoutes.phoneCode), - text: "Siguiente", - color: theme.getColorFor(ThemeCode.buttonPrimary), - ), - Spacer(flex: 10) - ], - ), - ), - ), - ), - )); - } -} diff --git a/modules/auth/lib/src/onboarding/presentation/onboarding_screen.dart b/modules/auth/lib/src/onboarding/presentation/onboarding_screen.dart deleted file mode 100644 index bef2e8f7..00000000 --- a/modules/auth/lib/src/onboarding/presentation/onboarding_screen.dart +++ /dev/null @@ -1,128 +0,0 @@ -import 'package:auth/src/onboarding/domain/onboarding_page.dart'; -import 'package:auth/src/onboarding/presentation/onboarding_view_model.dart'; -import 'package:auth/src/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(( - 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: SafeArea( - child: 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, - 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: 36), - ], - ), - ), - ), - ); - } -} diff --git a/modules/auth/pubspec.yaml b/modules/auth/pubspec.yaml index feffab44..70be6cdf 100644 --- a/modules/auth/pubspec.yaml +++ b/modules/auth/pubspec.yaml @@ -22,6 +22,8 @@ dependencies: path: ../../packages/navigation sf_localizations: path: ../../packages/sf_localizations + sf_infrastructure: + path: ../../packages/sf_infrastructure #dependencies go here flutter_svg: ^2.2.1 get_it: ^9.0.5 @@ -29,6 +31,7 @@ dependencies: flutter_riverpod: ^3.0.3 freezed_annotation: ^3.1.0 freezed: ^3.2.3 + dio: ^5.9.0 dev_dependencies: flutter_test: diff --git a/modules/auth/pubspec_overrides.yaml b/modules/auth/pubspec_overrides.yaml index 65569a2b..9d5c49cf 100644 --- a/modules/auth/pubspec_overrides.yaml +++ b/modules/auth/pubspec_overrides.yaml @@ -1,4 +1,4 @@ -# melos_managed_dependency_overrides: dashboard_shell,design_system,home,notifications,profile,sf_shared,navigation,utils,sf_localizations,fonts +# melos_managed_dependency_overrides: dashboard_shell,design_system,home,notifications,profile,sf_shared,navigation,utils,sf_localizations,fonts,sf_infrastructure dependency_overrides: dashboard_shell: path: ../dashboard_shell @@ -14,6 +14,8 @@ dependency_overrides: path: ../notifications profile: path: ../profile + sf_infrastructure: + path: ../../packages/sf_infrastructure sf_localizations: path: ../../packages/sf_localizations sf_shared: diff --git a/modules/dashboard_shell/pubspec_overrides.yaml b/modules/dashboard_shell/pubspec_overrides.yaml index 4d8ae344..e06af733 100644 --- a/modules/dashboard_shell/pubspec_overrides.yaml +++ b/modules/dashboard_shell/pubspec_overrides.yaml @@ -1,4 +1,4 @@ -# melos_managed_dependency_overrides: auth,design_system,home,notifications,profile,sf_shared,navigation,utils,sf_localizations,fonts +# melos_managed_dependency_overrides: auth,design_system,home,notifications,profile,sf_shared,navigation,utils,sf_localizations,fonts,sf_infrastructure dependency_overrides: auth: path: ../auth @@ -14,6 +14,8 @@ dependency_overrides: path: ../notifications profile: path: ../profile + sf_infrastructure: + path: ../../packages/sf_infrastructure sf_localizations: path: ../../packages/sf_localizations sf_shared: diff --git a/modules/home/pubspec_overrides.yaml b/modules/home/pubspec_overrides.yaml index 2e540dc0..10a9562f 100644 --- a/modules/home/pubspec_overrides.yaml +++ b/modules/home/pubspec_overrides.yaml @@ -1,4 +1,4 @@ -# melos_managed_dependency_overrides: auth,dashboard_shell,design_system,notifications,profile,sf_shared,navigation,utils,sf_localizations,fonts +# melos_managed_dependency_overrides: auth,dashboard_shell,design_system,notifications,profile,sf_shared,navigation,utils,sf_localizations,fonts,sf_infrastructure dependency_overrides: auth: path: ../auth @@ -14,6 +14,8 @@ dependency_overrides: path: ../notifications profile: path: ../profile + sf_infrastructure: + path: ../../packages/sf_infrastructure sf_localizations: path: ../../packages/sf_localizations sf_shared: diff --git a/packages/sf_infrastructure/.gitignore b/packages/sf_infrastructure/.gitignore new file mode 100644 index 00000000..dd5eb989 --- /dev/null +++ b/packages/sf_infrastructure/.gitignore @@ -0,0 +1,31 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +.flutter-plugins-dependencies +/build/ +/coverage/ diff --git a/packages/sf_infrastructure/.metadata b/packages/sf_infrastructure/.metadata new file mode 100644 index 00000000..d7469f07 --- /dev/null +++ b/packages/sf_infrastructure/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "adc901062556672b4138e18a4dc62a4be8f4b3c2" + channel: "stable" + +project_type: package diff --git a/packages/sf_infrastructure/CHANGELOG.md b/packages/sf_infrastructure/CHANGELOG.md new file mode 100644 index 00000000..41cc7d81 --- /dev/null +++ b/packages/sf_infrastructure/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* TODO: Describe initial release. diff --git a/packages/sf_infrastructure/LICENSE b/packages/sf_infrastructure/LICENSE new file mode 100644 index 00000000..ba75c69f --- /dev/null +++ b/packages/sf_infrastructure/LICENSE @@ -0,0 +1 @@ +TODO: Add your license here. diff --git a/packages/sf_infrastructure/README.md b/packages/sf_infrastructure/README.md new file mode 100644 index 00000000..4a260d8d --- /dev/null +++ b/packages/sf_infrastructure/README.md @@ -0,0 +1,39 @@ + + +TODO: Put a short description of the package here that helps potential users +know whether this package might be useful for them. + +## Features + +TODO: List what your package can do. Maybe include images, gifs, or videos. + +## Getting started + +TODO: List prerequisites and provide or point to information on how to +start using the package. + +## Usage + +TODO: Include short and useful examples for package users. Add longer examples +to `/example` folder. + +```dart +const like = 'sample'; +``` + +## Additional information + +TODO: Tell users more about the package: where to find more information, how to +contribute to the package, how to file issues, what response they can expect +from the package authors, and more. diff --git a/packages/sf_infrastructure/analysis_options.yaml b/packages/sf_infrastructure/analysis_options.yaml new file mode 100644 index 00000000..a5744c1c --- /dev/null +++ b/packages/sf_infrastructure/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/packages/sf_infrastructure/lib/configure_dependencies.dart b/packages/sf_infrastructure/lib/configure_dependencies.dart new file mode 100644 index 00000000..7f18f3cc --- /dev/null +++ b/packages/sf_infrastructure/lib/configure_dependencies.dart @@ -0,0 +1,26 @@ +import 'package:dio/dio.dart'; +import 'package:get_it/get_it.dart'; + +import 'src/network/dio_client.dart'; +import 'src/env/env_contract.dart'; +import 'src/api/questia_api.dart'; +import 'src/repositories/questia_repository_impl.dart'; +import 'src/repositories/questia_repository.dart'; + +export 'src/repositories/questia_repository.dart'; + +final getIt = GetIt.instance; + +Future configureDependencies(EnvConfig env, {bool log = false}) async { + getIt.registerLazySingleton( + () => buildDioClient( + baseUrl: env.apiBaseUrl, + // apiKey: env.apiKey, + log: log, + ), + ); + getIt.registerLazySingleton(() => QuestiaApi(getIt())); + getIt.registerLazySingleton( + () => QuestiaRepositoryImpl(getIt()), + ); +} diff --git a/packages/sf_infrastructure/lib/sf_infrastructure.dart b/packages/sf_infrastructure/lib/sf_infrastructure.dart new file mode 100644 index 00000000..72a8359b --- /dev/null +++ b/packages/sf_infrastructure/lib/sf_infrastructure.dart @@ -0,0 +1,2 @@ +export 'src/env/env_contract.dart'; +export 'configure_dependencies.dart'; diff --git a/packages/sf_infrastructure/lib/src/api/questia_api.dart b/packages/sf_infrastructure/lib/src/api/questia_api.dart new file mode 100644 index 00000000..9a27d95f --- /dev/null +++ b/packages/sf_infrastructure/lib/src/api/questia_api.dart @@ -0,0 +1,79 @@ +import 'package:dio/dio.dart'; + +class QuestiaApi { + final Dio _dio; + + QuestiaApi(this._dio); + + Future> get( + String path, { + Map? queryParameters, + Options? options, + CancelToken? cancelToken, + ProgressCallback? onReceiveProgress, + }) { + return _dio.get( + path, + queryParameters: queryParameters, + options: options, + cancelToken: cancelToken, + onReceiveProgress: onReceiveProgress, + ); + } + + Future> post( + String path, { + dynamic data, + Map? queryParameters, + Options? options, + CancelToken? cancelToken, + ProgressCallback? onSendProgress, + ProgressCallback? onReceiveProgress, + }) { + return _dio.post( + path, + data: data, + queryParameters: queryParameters, + options: options, + cancelToken: cancelToken, + onSendProgress: onSendProgress, + onReceiveProgress: onReceiveProgress, + ); + } + + Future> put( + String path, { + dynamic data, + Map? queryParameters, + Options? options, + CancelToken? cancelToken, + ProgressCallback? onSendProgress, + ProgressCallback? onReceiveProgress, + }) { + return _dio.put( + path, + data: data, + queryParameters: queryParameters, + options: options, + cancelToken: cancelToken, + onSendProgress: onSendProgress, + onReceiveProgress: onReceiveProgress, + ); + } + + Future> delete( + String path, { + dynamic data, + Map? queryParameters, + Options? options, + CancelToken? cancelToken, + }) { + return _dio.delete( + path, + data: data, + queryParameters: queryParameters, + options: options, + cancelToken: cancelToken, + ); + } +} diff --git a/packages/sf_infrastructure/lib/src/env/env_contract.dart b/packages/sf_infrastructure/lib/src/env/env_contract.dart new file mode 100644 index 00000000..a39a2c26 --- /dev/null +++ b/packages/sf_infrastructure/lib/src/env/env_contract.dart @@ -0,0 +1,4 @@ +abstract class EnvConfig { + String get apiBaseUrl; + // String get apiKey; +} diff --git a/packages/sf_infrastructure/lib/src/network/dio_client.dart b/packages/sf_infrastructure/lib/src/network/dio_client.dart new file mode 100644 index 00000000..c56f8963 --- /dev/null +++ b/packages/sf_infrastructure/lib/src/network/dio_client.dart @@ -0,0 +1,36 @@ +import 'package:dio/dio.dart'; + +Dio buildDioClient({ + required String baseUrl, + // required String apiKey, + bool log = false, +}) { + final dio = Dio( + BaseOptions( + baseUrl: baseUrl, + connectTimeout: const Duration(seconds: 20), + receiveTimeout: const Duration(seconds: 20), + sendTimeout: const Duration(seconds: 20), + headers: { + // if (apiKey.isNotEmpty) 'x-api-key': apiKey, + 'accept': 'application/json', + 'content-type': 'application/json', + }, + ), + ); + + if (log) { + dio.interceptors.add( + LogInterceptor( + request: true, + requestHeader: false, + requestBody: true, + responseHeader: false, + responseBody: true, + error: true, + ), + ); + } + + return dio; +} diff --git a/packages/sf_infrastructure/lib/src/repositories/questia_repository.dart b/packages/sf_infrastructure/lib/src/repositories/questia_repository.dart new file mode 100644 index 00000000..fb0b6727 --- /dev/null +++ b/packages/sf_infrastructure/lib/src/repositories/questia_repository.dart @@ -0,0 +1,26 @@ +import 'package:dio/dio.dart'; + +abstract class QuestiaRepository { + Future> get( + String path, { + Map? queryParameters, + }); + + Future> post( + String path, { + dynamic body, + Map? queryParameters, + }); + + Future> put( + String path, { + dynamic body, + Map? queryParameters, + }); + + Future> delete( + String path, { + dynamic body, + Map? queryParameters, + }); +} diff --git a/packages/sf_infrastructure/lib/src/repositories/questia_repository_impl.dart b/packages/sf_infrastructure/lib/src/repositories/questia_repository_impl.dart new file mode 100644 index 00000000..15fcdebb --- /dev/null +++ b/packages/sf_infrastructure/lib/src/repositories/questia_repository_impl.dart @@ -0,0 +1,45 @@ +import 'package:dio/dio.dart'; + +import '../api/questia_api.dart'; +import 'questia_repository.dart'; + +class QuestiaRepositoryImpl implements QuestiaRepository { + final QuestiaApi _api; + + QuestiaRepositoryImpl(this._api); + + @override + Future> get( + String path, { + Map? queryParameters, + }) { + return _api.get(path, queryParameters: queryParameters); + } + + @override + Future> post( + String path, { + dynamic body, + Map? queryParameters, + }) { + return _api.post(path, data: body, queryParameters: queryParameters); + } + + @override + Future> put( + String path, { + dynamic body, + Map? queryParameters, + }) { + return _api.put(path, data: body, queryParameters: queryParameters); + } + + @override + Future> delete( + String path, { + dynamic body, + Map? queryParameters, + }) { + return _api.delete(path, data: body, queryParameters: queryParameters); + } +} diff --git a/packages/sf_infrastructure/pubspec.yaml b/packages/sf_infrastructure/pubspec.yaml new file mode 100644 index 00000000..58b9290d --- /dev/null +++ b/packages/sf_infrastructure/pubspec.yaml @@ -0,0 +1,56 @@ +name: sf_infrastructure +description: "A new Flutter package project." +version: 0.0.1 +homepage: + +environment: + sdk: ^3.9.2 + flutter: ">=1.17.0" + +dependencies: + dio: ^5.9.0 + flutter: + sdk: flutter + get_it: ^9.0.5 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^5.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + + # To add assets to your package, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + # + # For details regarding assets in packages, see + # https://flutter.dev/to/asset-from-package + # + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/to/resolution-aware-images + + # To add custom fonts to your package, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts in packages, see + # https://flutter.dev/to/font-from-package diff --git a/packages/sf_localizations/assets/l10n/de.json b/packages/sf_localizations/assets/l10n/de.json index 72c4b830..932a19c9 100644 --- a/packages/sf_localizations/assets/l10n/de.json +++ b/packages/sf_localizations/assets/l10n/de.json @@ -8,5 +8,9 @@ "onboardingTitle2": "Gelassenheit bei jeder Zahlung", "onboardingSubtitle2": "Überwache ihre Ausgaben, setze Limits und begleite sie bei jedem Schritt", "onboardingTitle3": "Einfache und sichere Zahlungen in ihren Händen", - "onboardingSubtitle3": "Sie können mit ihrer Uhr bezahlen.\nGanz ohne Handy und Bargeld" + "onboardingSubtitle3": "Sie können mit ihrer Uhr bezahlen.\nGanz ohne Handy und Bargeld", + "linkPhoneTitle": "Wir freuen uns sehr, dass du hier bist!", + "linkPhoneSubtitle": "Um dich sicher anzumelden, senden wir dir einen Code an deine Telefonnummer", + "mobilePhone": "Mobiltelefon", + "phoneNumber": "Telefonnummer" } \ No newline at end of file diff --git a/packages/sf_localizations/assets/l10n/en.json b/packages/sf_localizations/assets/l10n/en.json index bcbf501b..74e26676 100755 --- a/packages/sf_localizations/assets/l10n/en.json +++ b/packages/sf_localizations/assets/l10n/en.json @@ -8,5 +8,9 @@ "onboardingSubtitle3": "They can pay from their watch.\nNo phone or cash needed", "start": "Start", "next": "Next", - "skip": "Skip" + "skip": "Skip", + "linkPhoneTitle": "We're really happy to have you here!", + "linkPhoneSubtitle": "To sign in securely, we'll send a code to your phone number", + "mobilePhone": "Mobile phone", + "phoneNumber": "Phone number" } \ No newline at end of file diff --git a/packages/sf_localizations/assets/l10n/es.json b/packages/sf_localizations/assets/l10n/es.json index 01aa6084..174f4f9a 100644 --- a/packages/sf_localizations/assets/l10n/es.json +++ b/packages/sf_localizations/assets/l10n/es.json @@ -8,5 +8,9 @@ "onboardingSubtitle3": "Podrá pagar desde su reloj.\nSin móvil ni efectivo", "start": "Comenzar", "next": "Siguiente", - "skip": "Omitir" + "skip": "Omitir", + "linkPhoneTitle": "¡Nos alegra mucho tenerte por aquí!", + "linkPhoneSubtitle": "Para poder entrar de forma segura, te vamos a enviar un código al teléfono", + "mobilePhone": "Teléfono móvil", + "phoneNumber": "Teléfono" } \ No newline at end of file diff --git a/packages/sf_localizations/assets/l10n/fr.json b/packages/sf_localizations/assets/l10n/fr.json index bf1c9a68..5cf274d5 100644 --- a/packages/sf_localizations/assets/l10n/fr.json +++ b/packages/sf_localizations/assets/l10n/fr.json @@ -8,5 +8,9 @@ "onboardingTitle2": "La tranquillité à chaque paiement", "onboardingSubtitle2": "Surveillez leurs dépenses, fixez des limites et accompagnez-les à chaque étape", "onboardingTitle3": "Des paiements faciles et sécurisés entre leurs mains", - "onboardingSubtitle3": "Ils peuvent payer avec leur montre.\nSans téléphone ni espèces" + "onboardingSubtitle3": "Ils peuvent payer avec leur montre.\nSans téléphone ni espèces", + "linkPhoneTitle": "Nous sommes ravis de te compter parmi nous !", + "linkPhoneSubtitle": "Pour te connecter en toute sécurité, nous allons envoyer un code sur ton téléphone", + "mobilePhone": "Téléphone portable", + "phoneNumber": "Numéro de téléphone" } \ No newline at end of file diff --git a/packages/sf_localizations/assets/l10n/it.json b/packages/sf_localizations/assets/l10n/it.json index 78ef0c94..f32a8895 100644 --- a/packages/sf_localizations/assets/l10n/it.json +++ b/packages/sf_localizations/assets/l10n/it.json @@ -8,5 +8,9 @@ "onboardingTitle2": "Tranquillità in ogni pagamento", "onboardingSubtitle2": "Monitora le sue spese, imposta limiti e accompagnalo in ogni passo", "onboardingTitle3": "Pagamenti facili e sicuri nelle sue mani", - "onboardingSubtitle3": "Potrà pagare dal suo orologio.\nSenza telefono né contanti" + "onboardingSubtitle3": "Potrà pagare dal suo orologio.\nSenza telefono né contanti", + "linkPhoneTitle": "Siamo molto felici di averti qui!", + "linkPhoneSubtitle": "Per accedere in modo sicuro, ti invieremo un codice al tuo telefono", + "mobilePhone": "Telefono cellulare", + "phoneNumber": "Numero di telefono" } \ No newline at end of file diff --git a/packages/sf_localizations/assets/l10n/pt.json b/packages/sf_localizations/assets/l10n/pt.json index 8b8e7c94..bcd5436b 100644 --- a/packages/sf_localizations/assets/l10n/pt.json +++ b/packages/sf_localizations/assets/l10n/pt.json @@ -8,5 +8,9 @@ "onboardingTitle2": "Tranquilidade em cada pagamento", "onboardingSubtitle2": "Monitore os gastos deles, defina limites e acompanhe cada passo", "onboardingTitle3": "Pagamentos fáceis e seguros nas mãos deles", - "onboardingSubtitle3": "Eles poderão pagar pelo relógio.\nSem celular nem dinheiro em espécie" + "onboardingSubtitle3": "Eles poderão pagar pelo relógio.\nSem celular nem dinheiro em espécie", + "linkPhoneTitle": "Ficamos muito felizes em ter você aqui!", + "linkPhoneSubtitle": "Para entrar com segurança, vamos enviar um código para o seu telefone", + "mobilePhone": "Telefone celular", + "phoneNumber": "Número de telefone" } \ No newline at end of file diff --git a/packages/sf_localizations/lib/src/generated/i18n.dart b/packages/sf_localizations/lib/src/generated/i18n.dart index a3cb657a..3c7d3d1a 100755 --- a/packages/sf_localizations/lib/src/generated/i18n.dart +++ b/packages/sf_localizations/lib/src/generated/i18n.dart @@ -13,4 +13,8 @@ class I18n { static const String onboardingSubtitle2 = 'onboardingSubtitle2'; static const String onboardingTitle3 = 'onboardingTitle3'; static const String onboardingSubtitle3 = 'onboardingSubtitle3'; + static const String linkPhoneTitle = 'linkPhoneTitle'; + static const String linkPhoneSubtitle = 'linkPhoneSubtitle'; + static const String mobilePhone = 'mobilePhone'; + static const String phoneNumber = 'phoneNumber'; }