- create auth, main shell, home, profile, notifications and settings modules.
- added navigation, utils, design system and shared packages - implemented go router in entiered app - implemented flutter riverpod instead provider
This commit is contained in:
31
modules/auth/.gitignore
vendored
Normal file
31
modules/auth/.gitignore
vendored
Normal file
@@ -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/
|
||||
10
modules/auth/.metadata
Normal file
10
modules/auth/.metadata
Normal file
@@ -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
|
||||
3
modules/auth/CHANGELOG.md
Normal file
3
modules/auth/CHANGELOG.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.0.1
|
||||
|
||||
* TODO: Describe initial release.
|
||||
1
modules/auth/LICENSE
Normal file
1
modules/auth/LICENSE
Normal file
@@ -0,0 +1 @@
|
||||
TODO: Add your license here.
|
||||
39
modules/auth/README.md
Normal file
39
modules/auth/README.md
Normal file
@@ -0,0 +1,39 @@
|
||||
<!--
|
||||
This README describes the package. If you publish this package to pub.dev,
|
||||
this README's contents appear on the landing page for your package.
|
||||
|
||||
For information about how to write a good package README, see the guide for
|
||||
[writing package pages](https://dart.dev/tools/pub/writing-package-pages).
|
||||
|
||||
For general information about developing packages, see the Dart guide for
|
||||
[creating packages](https://dart.dev/guides/libraries/create-packages)
|
||||
and the Flutter guide for
|
||||
[developing packages and plugins](https://flutter.dev/to/develop-packages).
|
||||
-->
|
||||
|
||||
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.
|
||||
4
modules/auth/analysis_options.yaml
Normal file
4
modules/auth/analysis_options.yaml
Normal file
@@ -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
|
||||
6
modules/auth/lib/auth.dart
Normal file
6
modules/auth/lib/auth.dart
Normal file
@@ -0,0 +1,6 @@
|
||||
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';
|
||||
57
modules/auth/lib/src/device_sign_up/add_kid_screen.dart
Normal file
57
modules/auth/lib/src/device_sign_up/add_kid_screen.dart
Normal file
@@ -0,0 +1,57 @@
|
||||
import 'package:auth/src/device_sign_up/link_watch/create_profile_screen.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
// import 'package:sf_app_platform/payments/view/screens/core/dashboard_screen.dart';
|
||||
// import 'package:sf_app_platform/payments/view/screens/link_watch/create_profile_screen.dart';
|
||||
|
||||
class AddKidScreen extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
margin: EdgeInsets.all(30),
|
||||
child: Column(
|
||||
spacing: 15,
|
||||
children: [
|
||||
Spacer(flex: 6),
|
||||
Text("Añade a tu peque"),
|
||||
Text(
|
||||
"Controla su gasto a la vez que aprende hábitos financieros responsables",
|
||||
),
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(vertical: 30, horizontal: 50),
|
||||
child: Row(
|
||||
children: [
|
||||
Column(children: [Text("1"), Text("2"), Text("3")]),
|
||||
Column(
|
||||
children: [
|
||||
Text("Crea su perfil"),
|
||||
Text("Vincula su correa y su reloj"),
|
||||
Text("Carga su hucha"),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Text("¡Y todo listo para que tenga su dinero!"),
|
||||
Text("Recuerda que necesitas tener un Plan SaveFamily"),
|
||||
Text(
|
||||
"Si aún no lo tienes, puedes conseguirlo a través de nuestra web",
|
||||
),
|
||||
Spacer(flex: 8),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
child: FilledButton(
|
||||
onPressed: () => Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (_) => CreateProfileScreen()),
|
||||
),
|
||||
child: Text("¡Empezar!"),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
79
modules/auth/lib/src/device_sign_up/contact_screen.dart
Normal file
79
modules/auth/lib/src/device_sign_up/contact_screen.dart
Normal file
@@ -0,0 +1,79 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ContactScreen extends StatelessWidget {
|
||||
const ContactScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
margin: EdgeInsets.all(30),
|
||||
child: Center(
|
||||
child: Column(
|
||||
spacing: 10,
|
||||
children: [
|
||||
Text(
|
||||
"Contáctanos",
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30),
|
||||
),
|
||||
Text(
|
||||
"Trasládanos tus dudas e intentaremos responderte lo antes posible",
|
||||
),
|
||||
DropdownMenu(
|
||||
initialSelection: "es",
|
||||
label: Text("País"),
|
||||
dropdownMenuEntries: [
|
||||
DropdownMenuEntry(value: "es", label: "España"),
|
||||
DropdownMenuEntry(value: "fr", label: "Francia"),
|
||||
DropdownMenuEntry(value: "pt", label: "Portugal"),
|
||||
],
|
||||
),
|
||||
DropdownMenu(
|
||||
initialSelection: "online",
|
||||
label: Text("Canal de compra"),
|
||||
dropdownMenuEntries: [
|
||||
DropdownMenuEntry(value: "online", label: "SF online shop"),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
decoration: InputDecoration(
|
||||
labelText: "Nombre",
|
||||
hintText: "Nombre y apellidos",
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
decoration: InputDecoration(
|
||||
labelText: "Correo electrónico",
|
||||
hintText: "Correo electrónico",
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
minLines: 3,
|
||||
maxLines: 3,
|
||||
decoration: InputDecoration(
|
||||
labelText: "Asunto del mensaje",
|
||||
hintText: "Escribe tu mensaje",
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: FilledButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: Text("Enviar"),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:auth/src/device_sign_up/add_kid_screen.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
class AccountCreatedKidScreen extends ConsumerWidget {
|
||||
const AccountCreatedKidScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
|
||||
final model = "SaveWatch Plus 2";
|
||||
final id = "1106652524";
|
||||
final fullName = "Carlos Pérez Cruz";
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
body: Container(
|
||||
margin: EdgeInsets.all(30),
|
||||
child: Center(
|
||||
child: Column(
|
||||
spacing: 20,
|
||||
children: [
|
||||
Spacer(flex: 2),
|
||||
Icon(
|
||||
Icons.check,
|
||||
color: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
size: 50,
|
||||
),
|
||||
Text(
|
||||
"Cuenta creada",
|
||||
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
text: "Has creado la cuenta para:\n",
|
||||
children: [
|
||||
TextSpan(
|
||||
text: fullName,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Text("Reloj: $model"),
|
||||
Text("ID del reloj: $id"),
|
||||
Text(
|
||||
"Ya puedes darle su primera paga paa que empiece a disfrutarla en su reloj",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Spacer(flex: 6),
|
||||
Container(
|
||||
padding: EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.only(
|
||||
topRight: Radius.circular(20),
|
||||
topLeft: Radius.circular(20),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: FilledButton(
|
||||
onPressed: () => {
|
||||
Navigator.pushReplacement(
|
||||
context,
|
||||
MaterialPageRoute(builder: (_) => AddKidScreen()),
|
||||
),
|
||||
},
|
||||
child: Text("Dale su primera paga"),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => {},
|
||||
child: Text("Añadir otro peque"),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,304 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
|
||||
class CreateProfileScreen extends ConsumerWidget {
|
||||
CreateProfileScreen({super.key});
|
||||
|
||||
int currentStep = 0;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
body: Container(
|
||||
margin: EdgeInsets.all(30),
|
||||
child: Center(
|
||||
child: Column(
|
||||
spacing: 10,
|
||||
children: [
|
||||
Stepper(
|
||||
type: StepperType.horizontal,
|
||||
currentStep: currentStep,
|
||||
onStepCancel: () => currentStep == 0,
|
||||
// ? null
|
||||
// :
|
||||
// setState(() {
|
||||
// currentStep -= 1;
|
||||
// }),
|
||||
controlsBuilder:
|
||||
(BuildContext context, ControlsDetails controls) {
|
||||
return FilledButton(
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStatePropertyAll<Color>(
|
||||
theme.getColorFor(ThemeCode.buttonPrimary),
|
||||
),
|
||||
),
|
||||
onPressed: controls.onStepContinue,
|
||||
child: const Text('Continuar'),
|
||||
);
|
||||
},
|
||||
steps: [
|
||||
Step(
|
||||
state: currentStep > 0
|
||||
? StepState.complete
|
||||
: StepState.indexed,
|
||||
isActive: currentStep >= 0,
|
||||
stepStyle: currentStep >= 0
|
||||
? StepStyle(
|
||||
connectorThickness: 0,
|
||||
color: Color(0xFF329e95),
|
||||
indexStyle: TextStyle(color: Colors.transparent),
|
||||
)
|
||||
: StepStyle(
|
||||
connectorThickness: 0,
|
||||
color: Colors.transparent,
|
||||
boxShadow: BoxShadow(spreadRadius: 5),
|
||||
indexStyle: TextStyle(color: Colors.transparent),
|
||||
),
|
||||
title: Text(""),
|
||||
content: Column(
|
||||
spacing: 10,
|
||||
children: [
|
||||
Text(
|
||||
"Crea su perfil",
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 30,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"Necesitamos estos datos para crear su cuenta y gestionar sus pagas y gastos",
|
||||
),
|
||||
Text(
|
||||
"Comienza con un peque; luego podrás agregar más",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
TextField(
|
||||
decoration: InputDecoration(
|
||||
labelText: "Nombre",
|
||||
hintText: "Nombre",
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
TextField(
|
||||
decoration: InputDecoration(
|
||||
labelText: "Apellidos",
|
||||
hintText: "Apellidos",
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
spacing: 10,
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextField(
|
||||
decoration: InputDecoration(
|
||||
label: Text("Fecha de nacimiento"),
|
||||
hintText: "DD",
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
decoration: InputDecoration(
|
||||
hintText: "MM",
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
decoration: InputDecoration(
|
||||
hintText: "AAAA",
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
TextField(
|
||||
decoration: InputDecoration(
|
||||
labelText: "Dirección completa",
|
||||
hintText: "Nombre de la calle",
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => {},
|
||||
child: Text(
|
||||
"Cambiar dirección",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Step(
|
||||
state: currentStep > 1
|
||||
? StepState.complete
|
||||
: StepState.indexed,
|
||||
isActive: currentStep >= 1,
|
||||
stepStyle: currentStep >= 1
|
||||
? StepStyle(
|
||||
connectorThickness: 0,
|
||||
color: Color(0xFF329e95),
|
||||
indexStyle: TextStyle(color: Colors.transparent),
|
||||
)
|
||||
: StepStyle(
|
||||
connectorThickness: 0,
|
||||
color: Colors.transparent,
|
||||
boxShadow: BoxShadow(spreadRadius: 5),
|
||||
indexStyle: TextStyle(color: Colors.transparent),
|
||||
),
|
||||
title: Text(""),
|
||||
content: Column(
|
||||
spacing: 10,
|
||||
children: [
|
||||
Text(
|
||||
"Vincula su correa y su reloj",
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 30,
|
||||
),
|
||||
),
|
||||
SvgPicture.asset("assets/images/ui/formulario.svg"),
|
||||
Row(
|
||||
spacing: 10,
|
||||
children: [
|
||||
Text("1"),
|
||||
Column(
|
||||
children: [
|
||||
Text("Escanea la correa"),
|
||||
Text("El peque podrá realizar pagos"),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
spacing: 10,
|
||||
children: [
|
||||
Text("2"),
|
||||
Column(
|
||||
children: [
|
||||
Text("Escanea el reloj"),
|
||||
Text("Visualizarás los gastos que se hagan"),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Step(
|
||||
state: currentStep > 2
|
||||
? StepState.complete
|
||||
: StepState.indexed,
|
||||
isActive: currentStep >= 2,
|
||||
stepStyle: currentStep >= 2
|
||||
? StepStyle(
|
||||
connectorThickness: 0,
|
||||
color: Color(0xFF329e95),
|
||||
indexStyle: TextStyle(color: Colors.transparent),
|
||||
)
|
||||
: StepStyle(
|
||||
connectorThickness: 0,
|
||||
color: Colors.transparent,
|
||||
boxShadow: BoxShadow(spreadRadius: 5),
|
||||
indexStyle: TextStyle(color: Colors.transparent),
|
||||
),
|
||||
title: Text(""),
|
||||
content: Column(
|
||||
spacing: 10,
|
||||
children: [
|
||||
Text(
|
||||
"¡Dale su primera paga!",
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 30,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"Enséñales a gestionar su dinero recargando su reloj",
|
||||
),
|
||||
TextField(
|
||||
decoration: InputDecoration(
|
||||
labelText: "Cantidad de dinero de la paga",
|
||||
hintText: "0€",
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
],
|
||||
),
|
||||
Text("Cantidad mínima: 10€"),
|
||||
Text(
|
||||
"Por seguridad sólo se puede disponer de un máximo de 150€ por wallet",
|
||||
),
|
||||
Text("Método de ingreso"),
|
||||
Row(
|
||||
spacing: 20,
|
||||
children: [
|
||||
OutlinedButton(
|
||||
onPressed: () => {},
|
||||
child: SvgPicture.asset(
|
||||
"assets/images/ui/visa.svg",
|
||||
),
|
||||
),
|
||||
OutlinedButton(
|
||||
onPressed: () => {},
|
||||
child: SvgPicture.asset(
|
||||
"assets/images/ui/paypal.svg",
|
||||
),
|
||||
),
|
||||
OutlinedButton(
|
||||
onPressed: () => {},
|
||||
child: Row(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
"assets/images/ui/banco.svg",
|
||||
),
|
||||
Text("Transferencia"),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.lock_outline),
|
||||
Text(
|
||||
"EL pago en esta app es seguro y cumple la normativa europea. Sólo se usará el dinero que decidas para las huchas de tus hijos.",
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
18
modules/auth/lib/src/login/link_phone_builder.dart
Normal file
18
modules/auth/lib/src/login/link_phone_builder.dart
Normal file
@@ -0,0 +1,18 @@
|
||||
import 'package:auth/src/login/presentation/link_phone_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
|
||||
class LinkPhoneBuilder {
|
||||
const LinkPhoneBuilder();
|
||||
|
||||
Page<void> buildPage(BuildContext context, GoRouterState state) {
|
||||
final NavigationContract navigationContract = GetIt.I<NavigationContract>();
|
||||
|
||||
return MaterialPage<void>(
|
||||
key: state.pageKey,
|
||||
child: LinkPhoneScreen(navigationContract: navigationContract),
|
||||
);
|
||||
}
|
||||
}
|
||||
18
modules/auth/lib/src/login/login_builder.dart
Normal file
18
modules/auth/lib/src/login/login_builder.dart
Normal file
@@ -0,0 +1,18 @@
|
||||
import 'package:auth/src/login/presentation/login_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
|
||||
class LoginBuilder {
|
||||
const LoginBuilder();
|
||||
|
||||
Page<void> buildPage(BuildContext context, GoRouterState state) {
|
||||
final NavigationContract navigationContract = GetIt.I<NavigationContract>();
|
||||
|
||||
return MaterialPage<void>(
|
||||
key: state.pageKey,
|
||||
child: LoginScreen(navigationContract: navigationContract),
|
||||
);
|
||||
}
|
||||
}
|
||||
18
modules/auth/lib/src/login/phone_code_builder.dart
Normal file
18
modules/auth/lib/src/login/phone_code_builder.dart
Normal file
@@ -0,0 +1,18 @@
|
||||
import 'package:auth/src/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';
|
||||
import 'package:navigation/navigation.dart';
|
||||
|
||||
class PhoneCodeBuilder {
|
||||
const PhoneCodeBuilder();
|
||||
|
||||
Page<void> buildPage(BuildContext context, GoRouterState state) {
|
||||
final NavigationContract navigationContract = GetIt.I<NavigationContract>();
|
||||
|
||||
return MaterialPage<void>(
|
||||
key: state.pageKey,
|
||||
child: PhoneCodeScreen(navigationContract: navigationContract),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
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) {
|
||||
TextEditingController phoneController = TextEditingController();
|
||||
// String? phone;
|
||||
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
margin: EdgeInsets.all(30),
|
||||
child: Expanded(
|
||||
child: Center(
|
||||
child: Column(
|
||||
spacing: 10,
|
||||
children: [
|
||||
Text(
|
||||
"¡Nos alegra mucho tenerte por aquí!",
|
||||
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
"Para poder entrar de forma segura, te vamos a enviar un código al teléfono",
|
||||
),
|
||||
Row(
|
||||
spacing: 10,
|
||||
children: [
|
||||
DropdownMenu(
|
||||
initialSelection: "es",
|
||||
dropdownMenuEntries: List<DropdownMenuEntry>.generate(3, (
|
||||
int index,
|
||||
) {
|
||||
return DropdownMenuEntry(
|
||||
labelWidget: Icon(Icons.outlined_flag),
|
||||
label: "es",
|
||||
value: "es",
|
||||
);
|
||||
}),
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
onSubmitted: (String value) {
|
||||
// phone = value;
|
||||
},
|
||||
controller: phoneController,
|
||||
decoration: InputDecoration(
|
||||
labelText: "Teléfono móvil",
|
||||
hintText: "Teléfono",
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: FilledButton(
|
||||
onPressed: () => navigationContract.pushTo('/phone_code'),
|
||||
child: Text("Siguiente"),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import 'package:flutter/material.dart';
|
||||
// import 'package:flutter_svg/flutter_svg.dart';
|
||||
|
||||
class LoadingGoogleScreen extends StatelessWidget {
|
||||
const LoadingGoogleScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Expanded(
|
||||
child: Center(
|
||||
child: Column(
|
||||
spacing: 50,
|
||||
children: [
|
||||
Spacer(flex: 8),
|
||||
Text(
|
||||
"Continuar con Google",
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30),
|
||||
),
|
||||
CircularProgressIndicator(),
|
||||
Text("Redirigiendo a Google"),
|
||||
Spacer(flex: 10),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
25
modules/auth/lib/src/login/presentation/loading_screen.dart
Normal file
25
modules/auth/lib/src/login/presentation/loading_screen.dart
Normal file
@@ -0,0 +1,25 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
|
||||
class LoadingScreen extends StatelessWidget{
|
||||
const LoadingScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Expanded(
|
||||
child: Center(
|
||||
child: Column(
|
||||
spacing: 50,
|
||||
children: [
|
||||
Spacer(flex: 8),
|
||||
SvgPicture.asset("assets/images/ui/logo_sf.svg"),
|
||||
CircularProgressIndicator(),
|
||||
Spacer(flex: 10)
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
107
modules/auth/lib/src/login/presentation/login_screen.dart
Normal file
107
modules/auth/lib/src/login/presentation/login_screen.dart
Normal file
@@ -0,0 +1,107 @@
|
||||
import 'package:auth/src/login/presentation/loading_google_screen.dart';
|
||||
import 'package:auth/src/recover_password/presentation/restore_password_screen.dart';
|
||||
import 'package:auth/src/sign_up/signup_screen.dart';
|
||||
import 'package:dashboard_shell/dashboard_shell.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
// import 'package:sf_app_platform/payments/view/screens/core/dashboard_screen.dart';
|
||||
// import 'package:sf_app_platform/payments/view/screens/loading_google_screen.dart';
|
||||
// import 'package:sf_app_platform/payments/view/screens/restore_password/restore_password_screen.dart';
|
||||
// import 'package:sf_app_platform/payments/view/screens/signup/signup_screen.dart';
|
||||
|
||||
class LoginScreen extends ConsumerWidget {
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
const LoginScreen({super.key, required this.navigationContract});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
bool passwordVisible = true;
|
||||
return Scaffold(
|
||||
body: Expanded(
|
||||
child: Center(
|
||||
child: Container(
|
||||
margin: EdgeInsets.all(30),
|
||||
child: Column(
|
||||
spacing: 10,
|
||||
children: [
|
||||
Icon(Icons.check, color: Color(0xFF329e95), size: 50),
|
||||
Text(
|
||||
"¡Te damos la bienvenida!",
|
||||
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
|
||||
),
|
||||
TextField(
|
||||
decoration: InputDecoration(
|
||||
hintText: "Nombre de usuario",
|
||||
labelText: "Nombre de usuario",
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
TextField(
|
||||
obscureText: passwordVisible,
|
||||
enableSuggestions: false,
|
||||
autocorrect: false,
|
||||
decoration: InputDecoration(
|
||||
labelText: "Contraseña",
|
||||
hintText: "********",
|
||||
border: OutlineInputBorder(),
|
||||
suffixIcon: IconButton(
|
||||
icon: Icon(
|
||||
passwordVisible
|
||||
? Icons.visibility
|
||||
: Icons.visibility_off,
|
||||
),
|
||||
onPressed: () {
|
||||
// setState(() {
|
||||
// passwordVisible = !passwordVisible;
|
||||
// });
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo('/recover_password'),
|
||||
child: Text("¿Has olvidado la contraseña?"),
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo('/dashboard_shell'),
|
||||
child: Text("Iniciar sesión"),
|
||||
),
|
||||
Stack(children: [Divider(), Text("o continúa con")]),
|
||||
Row(
|
||||
spacing: 20,
|
||||
children: [
|
||||
OutlinedButton(
|
||||
onPressed: () => Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (_) => LoadingGoogleScreen(),
|
||||
),
|
||||
),
|
||||
child: Text("Google", semanticsLabel: "Google"),
|
||||
),
|
||||
OutlinedButton(
|
||||
onPressed: () => {},
|
||||
child: Icon(Icons.apple, semanticLabel: "Apple"),
|
||||
),
|
||||
],
|
||||
),
|
||||
Text("¿No tienes cuenta?"),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (_) => SignupScreen()),
|
||||
),
|
||||
child: Text("Crear una ahora"),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
import 'package:auth/src/login/presentation/login_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
// import 'package:sf_app_platform/payments/view/screens/core/dashboard_screen.dart';
|
||||
// import 'package:sf_app_platform/payments/view/screens/login_screen.dart';
|
||||
|
||||
class PhoneCodeScreen extends ConsumerWidget {
|
||||
// final String phone;
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
PhoneCodeScreen({super.key, required this.navigationContract});
|
||||
// const PhoneCodeScreen({super.key, required this.phone});
|
||||
|
||||
// class PhoneCodeScreenState extends State<PhoneCodeScreen> {
|
||||
final focusNodes = List<FocusNode>.generate(6, (int i) {
|
||||
return FocusNode();
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
margin: EdgeInsets.all(30),
|
||||
child: Expanded(
|
||||
child: Center(
|
||||
child: Column(
|
||||
spacing: 15,
|
||||
children: [
|
||||
Spacer(flex: 8),
|
||||
Text(
|
||||
"Conéctate",
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30),
|
||||
),
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
text: "Hemos enviado el código al ",
|
||||
children: [
|
||||
TextSpan(
|
||||
// text: widget.phone,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Text("Introduce el código aquí"),
|
||||
Row(
|
||||
spacing: 20,
|
||||
children: List<Widget>.generate(6, (int i) {
|
||||
return Expanded(
|
||||
child: TextField(
|
||||
focusNode: focusNodes[i],
|
||||
keyboardType: TextInputType.number,
|
||||
decoration: InputDecoration(
|
||||
hintText: "0",
|
||||
counterText: "",
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
maxLength: 1,
|
||||
onChanged: (String value) => {
|
||||
value != ""
|
||||
? focusNodes[i + 1].requestFocus()
|
||||
: focusNodes[i - 1].requestFocus(),
|
||||
},
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: () => {navigationContract.pushTo('/login')},
|
||||
child: Text("Entrar"),
|
||||
),
|
||||
Text("¿No lo has recibido?"),
|
||||
TextButton(
|
||||
onPressed: () => {},
|
||||
child: Text(
|
||||
"Volver a intentarlo",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
Spacer(flex: 10),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
18
modules/auth/lib/src/onboarding/onboarding_builder.dart
Normal file
18
modules/auth/lib/src/onboarding/onboarding_builder.dart
Normal file
@@ -0,0 +1,18 @@
|
||||
import 'package:auth/src/onboarding/presentation/welcome_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
|
||||
class OnboardingBuilder {
|
||||
const OnboardingBuilder();
|
||||
|
||||
Page<void> buildPage(BuildContext context, GoRouterState state) {
|
||||
final NavigationContract navigationContract = GetIt.I<NavigationContract>();
|
||||
|
||||
return MaterialPage<void>(
|
||||
key: state.pageKey,
|
||||
child: WelcomeScreen(navigationContract: navigationContract),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
|
||||
// import 'package:sf_app_platform/payments/view/screens/link_phone_screen.dart';
|
||||
// import 'package:sf_app_platform/payments/view/screens/signup/signup_screen.dart';
|
||||
|
||||
// import '../../../../../apps/mobile_app/lib/payments/view/screens/core/dashboard_screen.dart';
|
||||
|
||||
class WelcomeScreen extends ConsumerWidget {
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
const WelcomeScreen({super.key, required this.navigationContract});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Spacer(),
|
||||
Expanded(
|
||||
child: CarouselView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemExtent: double.infinity,
|
||||
itemSnapping: true,
|
||||
shrinkExtent: 400,
|
||||
children: generateSteps(),
|
||||
),
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: () => navigationContract.goTo('/link_phone'),
|
||||
child: const Text('Continuar'),
|
||||
),
|
||||
Spacer(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void jumpToNext(BuildContext context) {
|
||||
// Navigator.pushReplacement(
|
||||
// context,
|
||||
// MaterialPageRoute(builder: (_) => LinkPhoneScreen()),
|
||||
// );
|
||||
return;
|
||||
}
|
||||
|
||||
List<Widget> generateSteps() {
|
||||
return [
|
||||
Column(
|
||||
spacing: 30,
|
||||
children: [
|
||||
SvgPicture.asset("assets/images/ui/bienvenida_paso1.svg"),
|
||||
Text(
|
||||
"Aprende a gestionar su dinero",
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
|
||||
),
|
||||
Text("Tu peque crea hábitos y se divierte mientras lo hace"),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
SvgPicture.asset("assets/images/ui/bienvenida_paso2.svg"),
|
||||
Text("Tranquilidad en cada pago que hacen"),
|
||||
Text("Supervisa gastos, fija límites y acompáñalos en cada paso"),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
SvgPicture.asset("assets/images/ui/bienvenida_paso3.svg"),
|
||||
Text("Pagos fáciles y seguros en sus manos"),
|
||||
Text("Podrá pagar desde su reloj.\n Sin móvil ni efectivo"),
|
||||
],
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
import 'package:auth/src/recover_password/presentation/new_password_screen.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
// import 'package:sf_app_platform/payments/domain/ports/theme_port.dart';
|
||||
// import 'package:sf_app_platform/payments/view/screens/restore_password/new_password_screen.dart';
|
||||
|
||||
class EmailSentScreen extends StatefulWidget {
|
||||
final String email;
|
||||
|
||||
const EmailSentScreen({super.key, required this.email});
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => EmailSentScreenState();
|
||||
}
|
||||
|
||||
class EmailSentScreenState extends State<EmailSentScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.read<ThemePort>();
|
||||
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
margin: EdgeInsets.all(30),
|
||||
child: Center(
|
||||
child: Column(
|
||||
spacing: 20,
|
||||
children: [
|
||||
Spacer(flex: 8),
|
||||
Text(
|
||||
"Recuperar contraseña",
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30),
|
||||
),
|
||||
Spacer(flex: 1),
|
||||
Row(
|
||||
spacing: 10,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.check,
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary),
|
||||
),
|
||||
Text(
|
||||
"Correo enviado correctamente",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
Spacer(flex: 1),
|
||||
Text(
|
||||
"Revisa tu email y haz clic en el enlace para crear una nueva contraseña",
|
||||
),
|
||||
Text(
|
||||
"Si no recibes el correo en unos minutos, revisa tu carpeta de spam o pulsa \"Reenviar correo\"",
|
||||
),
|
||||
Row(
|
||||
spacing: 10,
|
||||
children: [
|
||||
Expanded(
|
||||
child: OutlinedButton(
|
||||
onPressed: () => {},
|
||||
child: Text("Reenviar correo"),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: FilledButton(
|
||||
onPressed: () => {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (_) => NewPasswordScreen(),
|
||||
),
|
||||
),
|
||||
},
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStatePropertyAll<Color>(
|
||||
theme.getColorFor(ThemeCode.buttonSecondary),
|
||||
),
|
||||
),
|
||||
child: Text("Continuar"),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Spacer(flex: 10),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
// import '../../../domain/ports/theme_port.dart';
|
||||
|
||||
class NewPasswordScreen extends StatefulWidget {
|
||||
const NewPasswordScreen({super.key});
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => NewPasswordScreenState();
|
||||
}
|
||||
|
||||
class NewPasswordScreenState extends State<NewPasswordScreen> {
|
||||
bool passwordVisible = false;
|
||||
bool equalPasswords = false;
|
||||
String password = "";
|
||||
var securityChecks = {
|
||||
"min": false,
|
||||
"capital": false,
|
||||
"number": false,
|
||||
"special": false,
|
||||
};
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
passwordVisible = false;
|
||||
equalPasswords = false;
|
||||
String password = "";
|
||||
securityChecks = {
|
||||
"min": false,
|
||||
"capital": false,
|
||||
"number": false,
|
||||
"special": false,
|
||||
};
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.read<ThemePort>();
|
||||
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
margin: EdgeInsets.all(30),
|
||||
child: Center(
|
||||
child: Column(
|
||||
spacing: 10,
|
||||
children: [
|
||||
Spacer(flex: 4),
|
||||
Text(
|
||||
"Recuperar contraseña",
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30),
|
||||
),
|
||||
TextField(
|
||||
obscureText: passwordVisible,
|
||||
enableSuggestions: false,
|
||||
autocorrect: false,
|
||||
decoration: InputDecoration(
|
||||
labelText: "Nueva contraseña",
|
||||
hintText: "********",
|
||||
border: OutlineInputBorder(),
|
||||
suffixIcon: IconButton(
|
||||
icon: Icon(
|
||||
passwordVisible ? Icons.visibility : Icons.visibility_off,
|
||||
),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
passwordVisible = !passwordVisible;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
onChanged: (value) => {
|
||||
setState(() {
|
||||
password = value;
|
||||
securityChecks = checkSecurity(value);
|
||||
}),
|
||||
},
|
||||
),
|
||||
TextField(
|
||||
obscureText: passwordVisible,
|
||||
enableSuggestions: false,
|
||||
autocorrect: false,
|
||||
decoration: InputDecoration(
|
||||
labelText: "Repetir contraseña",
|
||||
hintText: "********",
|
||||
border: OutlineInputBorder(),
|
||||
suffixIcon: IconButton(
|
||||
icon: Icon(
|
||||
passwordVisible ? Icons.visibility : Icons.visibility_off,
|
||||
),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
passwordVisible = !passwordVisible;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
onChanged: (value) => {
|
||||
setState(() {
|
||||
equalPasswords = password == value;
|
||||
}),
|
||||
},
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
securityChecks["min"]!
|
||||
? Icon(
|
||||
Icons.check,
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary),
|
||||
)
|
||||
: Icon(
|
||||
Icons.cancel_outlined,
|
||||
color: theme.getColorFor(ThemeCode.buttonSecondary),
|
||||
),
|
||||
Text("Al menos 8 caracteres"),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
securityChecks["capital"]!
|
||||
? Icon(
|
||||
Icons.check,
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary),
|
||||
)
|
||||
: Icon(
|
||||
Icons.cancel_outlined,
|
||||
color: theme.getColorFor(ThemeCode.buttonSecondary),
|
||||
),
|
||||
Text("Una mayúscula"),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
securityChecks["number"]!
|
||||
? Icon(
|
||||
Icons.check,
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary),
|
||||
)
|
||||
: Icon(
|
||||
Icons.cancel_outlined,
|
||||
color: theme.getColorFor(ThemeCode.buttonSecondary),
|
||||
),
|
||||
Text("Un número"),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
securityChecks["special"]!
|
||||
? Icon(
|
||||
Icons.check,
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary),
|
||||
)
|
||||
: Icon(
|
||||
Icons.cancel_outlined,
|
||||
color: theme.getColorFor(ThemeCode.buttonSecondary),
|
||||
),
|
||||
Text("Un carácter especial"),
|
||||
],
|
||||
),
|
||||
Spacer(flex: 1),
|
||||
FilledButton(
|
||||
onPressed: () => {},
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.all(20),
|
||||
child: Text("Aceptar"),
|
||||
),
|
||||
),
|
||||
Spacer(flex: 4),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
//TODO: Extraer de la vista
|
||||
Map<String, bool> checkSecurity(String value) {
|
||||
Map<String, bool> checks = {};
|
||||
|
||||
checks["min"] = value.length >= 8;
|
||||
checks["capital"] = RegExp(r'[A-Z]').hasMatch(value);
|
||||
checks["number"] = RegExp(r'[0-9]').hasMatch(value);
|
||||
checks["special"] = RegExp(r'[^A-Za-z0-9]').hasMatch(value);
|
||||
|
||||
return checks;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import 'package:auth/src/recover_password/presentation/email_sent_screen.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
// import 'package:provider/provider.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
// import 'package:sf_app_platform/payments/domain/ports/theme_port.dart';
|
||||
// import 'package:sf_app_platform/payments/view/screens/restore_password/email_sent_screen.dart';
|
||||
|
||||
class RestorePasswordScreen extends ConsumerWidget {
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
const RestorePasswordScreen({super.key, required this.navigationContract});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
// ThemePort theme = context.read<ThemePort>();
|
||||
final theme = ref.watch(themePortProvider);
|
||||
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
margin: EdgeInsets.all(30),
|
||||
child: Center(
|
||||
child: Column(
|
||||
spacing: 30,
|
||||
children: [
|
||||
Spacer(flex: 8),
|
||||
Text(
|
||||
"Recuperar contaseña",
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30),
|
||||
),
|
||||
Text(
|
||||
"Introduce tu email para enviarte un enlace de recuperación",
|
||||
),
|
||||
TextField(
|
||||
decoration: InputDecoration(
|
||||
labelText: "Correo electrónico",
|
||||
hintText: "Correo electrónico",
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
spacing: 20,
|
||||
children: [
|
||||
Expanded(
|
||||
child: OutlinedButton(
|
||||
onPressed: () => {Navigator.pop(context)},
|
||||
child: Text("Volver"),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: FilledButton(
|
||||
onPressed: () => {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (_) => EmailSentScreen(email: ""),
|
||||
),
|
||||
),
|
||||
},
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStatePropertyAll<Color>(
|
||||
theme.getColorFor(ThemeCode.buttonSecondary),
|
||||
),
|
||||
),
|
||||
child: Text("Enviar"),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Spacer(flex: 10),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import 'package:auth/src/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';
|
||||
import 'package:navigation/navigation.dart';
|
||||
|
||||
class RecoverPasswordBuilder {
|
||||
const RecoverPasswordBuilder();
|
||||
|
||||
Page<void> buildPage(BuildContext context, GoRouterState state) {
|
||||
final NavigationContract navigationContract = GetIt.I<NavigationContract>();
|
||||
|
||||
return MaterialPage<void>(
|
||||
key: state.pageKey,
|
||||
child: RestorePasswordScreen(navigationContract: navigationContract),
|
||||
);
|
||||
}
|
||||
}
|
||||
78
modules/auth/lib/src/sign_up/account_created_screen.dart
Normal file
78
modules/auth/lib/src/sign_up/account_created_screen.dart
Normal file
@@ -0,0 +1,78 @@
|
||||
import 'package:auth/src/device_sign_up/add_kid_screen.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
// import 'package:sf_app_platform/payments/view/screens/add_kid_screen.dart';
|
||||
// import 'package:sf_app_platform/payments/view/screens/core/dashboard_screen.dart';
|
||||
|
||||
// import '../../../../../apps/mobile_app/lib/payments/domain/ports/theme_port.dart';
|
||||
|
||||
class AccountCreatedScreen extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
ThemePort theme = context.read<ThemePort>();
|
||||
|
||||
final email = "usuario@example.com";
|
||||
final fullName = "Carlos Pérez Cruz";
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
body: Container(
|
||||
margin: EdgeInsets.all(30),
|
||||
child: Center(
|
||||
child: Column(
|
||||
spacing: 20,
|
||||
children: [
|
||||
Spacer(flex: 10),
|
||||
Icon(
|
||||
Icons.check,
|
||||
color: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
size: 50,
|
||||
),
|
||||
Text(
|
||||
"Cuenta creada",
|
||||
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
text: "Has creado la cuenta para:\n",
|
||||
children: [
|
||||
TextSpan(
|
||||
text: fullName,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
text: "Hemos enviado un email de verificación a:\n",
|
||||
children: [
|
||||
TextSpan(
|
||||
text: email,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"Crea la cuenta de tu peque e ingresa su \nprimera paga para utilizarla con su reloj",
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: () => {
|
||||
Navigator.pushReplacement(
|
||||
context,
|
||||
MaterialPageRoute(builder: (_) => AddKidScreen()),
|
||||
),
|
||||
},
|
||||
child: Text("Continuar"),
|
||||
),
|
||||
Spacer(flex: 8),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
27
modules/auth/lib/src/sign_up/signup_address_screen.dart
Normal file
27
modules/auth/lib/src/sign_up/signup_address_screen.dart
Normal file
@@ -0,0 +1,27 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SignupAddressScreen extends StatelessWidget{
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
spacing: 30,
|
||||
children: [
|
||||
Text("Domicilio"),
|
||||
Text("Tu dirección", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30)),
|
||||
Text("Tu dirección nos ayuda a verificar y mantener la seguridad de tu cuenta"),
|
||||
TextField(decoration: InputDecoration(hintText: "Dirección completa", border: OutlineInputBorder())),
|
||||
TextField(decoration: InputDecoration(hintText: "Ciudad", border: OutlineInputBorder())),
|
||||
DropdownMenu(
|
||||
dropdownMenuEntries: List<DropdownMenuEntry>.generate(3, (int index) {
|
||||
return DropdownMenuEntry(value: "España", label: "España");
|
||||
}),
|
||||
hintText: "País",
|
||||
width: double.infinity,
|
||||
),
|
||||
TextField(decoration: InputDecoration(hintText: "Nacionalidad", border: OutlineInputBorder()))
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
49
modules/auth/lib/src/sign_up/signup_personal_screen.dart
Normal file
49
modules/auth/lib/src/sign_up/signup_personal_screen.dart
Normal file
@@ -0,0 +1,49 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class SignupPersonalScreen extends StatelessWidget{
|
||||
const SignupPersonalScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
spacing: 30,
|
||||
children: [
|
||||
Text("Datos personales"),
|
||||
Text("Identifícate", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30)),
|
||||
Text("Nos aseguraremos de que la cuenta está a nombre del adulto responsable"),
|
||||
TextField(decoration: InputDecoration(labelText: "Nombre", hintText: "Nombre", border: OutlineInputBorder())),
|
||||
TextField(decoration: InputDecoration(labelText: "Apellidos", hintText: "Apellidos", border: OutlineInputBorder())),
|
||||
Row(
|
||||
children: [
|
||||
Expanded( child: TextField(
|
||||
decoration: InputDecoration(label: Text("Fecha de nacimiento"), hintText: "DD", border: OutlineInputBorder()),
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
||||
)),
|
||||
Expanded( child: TextField(
|
||||
decoration: InputDecoration(hintText: "MM", border: OutlineInputBorder()),
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
||||
)),
|
||||
Expanded( child: TextField(
|
||||
decoration: InputDecoration(hintText: "AAAA", border: OutlineInputBorder()),
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
||||
)),
|
||||
],
|
||||
),
|
||||
DropdownMenu(
|
||||
width: double.infinity,
|
||||
label: Text("¿Qué familiar eres?"),
|
||||
dropdownMenuEntries: [
|
||||
DropdownMenuEntry(label: "Padre", value: "Padre"),
|
||||
DropdownMenuEntry(label: "Madre", value: "Madre"),
|
||||
DropdownMenuEntry(label: "Tutor", value: "Tutor"),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
140
modules/auth/lib/src/sign_up/signup_screen.dart
Normal file
140
modules/auth/lib/src/sign_up/signup_screen.dart
Normal file
@@ -0,0 +1,140 @@
|
||||
import 'package:auth/src/sign_up/account_created_screen.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
// import 'package:sf_app_platform/payments/view/screens/account_created_screen.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:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
// import '../../../../../apps/mobile_app/lib/payments/domain/ports/theme_port.dart';
|
||||
|
||||
class SignupScreen extends ConsumerWidget {
|
||||
SignupScreen({super.key});
|
||||
|
||||
int currentStep = 0;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
|
||||
return MaterialApp(
|
||||
home: Scaffold(
|
||||
body: Center(
|
||||
child: Container(
|
||||
color: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: SizedBox(
|
||||
child: Stepper(
|
||||
controlsBuilder:
|
||||
(BuildContext context, ControlsDetails controls) {
|
||||
return Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: OutlinedButton(
|
||||
onPressed: controls.onStepCancel,
|
||||
child: const Text('Atrás'),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: FilledButton(
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStatePropertyAll<Color>(
|
||||
theme.getColorFor(ThemeCode.buttonSecondary),
|
||||
),
|
||||
),
|
||||
onPressed: controls.onStepContinue,
|
||||
child: const Text('Siguiente'),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
type: StepperType.horizontal,
|
||||
currentStep: currentStep,
|
||||
onStepCancel: () => currentStep == 0,
|
||||
// ? null
|
||||
// : setState(() {
|
||||
// currentStep -= 1;
|
||||
// }),
|
||||
onStepContinue: () {
|
||||
bool isLastStep = (currentStep == getSteps().length - 1);
|
||||
if (isLastStep) {
|
||||
Navigator.pushReplacement(
|
||||
context,
|
||||
MaterialPageRoute(builder: (_) => AccountCreatedScreen()),
|
||||
);
|
||||
} else {
|
||||
// setState(() {
|
||||
// currentStep += 1;
|
||||
// });
|
||||
}
|
||||
},
|
||||
steps: getSteps(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Step> getSteps() {
|
||||
return <Step>[
|
||||
Step(
|
||||
state: currentStep > 0 ? StepState.complete : StepState.indexed,
|
||||
isActive: currentStep >= 0,
|
||||
stepStyle: currentStep >= 0
|
||||
? StepStyle(
|
||||
connectorThickness: 0,
|
||||
color: Color(0xFF329e95),
|
||||
indexStyle: TextStyle(color: Colors.transparent),
|
||||
)
|
||||
: StepStyle(
|
||||
connectorThickness: 0,
|
||||
color: Colors.transparent,
|
||||
boxShadow: BoxShadow(spreadRadius: 5),
|
||||
indexStyle: TextStyle(color: Colors.transparent),
|
||||
),
|
||||
title: const Text(""),
|
||||
content: SignupPersonalScreen(),
|
||||
),
|
||||
Step(
|
||||
state: currentStep > 1 ? StepState.complete : StepState.indexed,
|
||||
isActive: currentStep >= 1,
|
||||
stepStyle: currentStep >= 1
|
||||
? StepStyle(
|
||||
connectorThickness: 0,
|
||||
color: Color(0xFF329e95),
|
||||
indexStyle: TextStyle(color: Colors.transparent),
|
||||
)
|
||||
: StepStyle(
|
||||
connectorThickness: 0,
|
||||
color: Colors.white,
|
||||
boxShadow: BoxShadow(spreadRadius: 1),
|
||||
indexStyle: TextStyle(color: Colors.transparent),
|
||||
),
|
||||
title: const Text(""),
|
||||
content: SignupAddressScreen(),
|
||||
),
|
||||
Step(
|
||||
state: currentStep > 2 ? StepState.complete : StepState.indexed,
|
||||
isActive: currentStep >= 2,
|
||||
stepStyle: currentStep >= 2
|
||||
? StepStyle(
|
||||
connectorThickness: 0,
|
||||
color: Color(0xFF329e95),
|
||||
indexStyle: TextStyle(color: Colors.transparent),
|
||||
)
|
||||
: StepStyle(
|
||||
connectorThickness: 0,
|
||||
color: Colors.white,
|
||||
boxShadow: BoxShadow(spreadRadius: 1),
|
||||
indexStyle: TextStyle(color: Colors.transparent),
|
||||
),
|
||||
title: const Text(""),
|
||||
content: SignupUserScreen(),
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
77
modules/auth/lib/src/sign_up/signup_user_screen.dart
Normal file
77
modules/auth/lib/src/sign_up/signup_user_screen.dart
Normal file
@@ -0,0 +1,77 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SignupUserScreen extends StatefulWidget{
|
||||
const SignupUserScreen({super.key});
|
||||
|
||||
@override
|
||||
State<SignupUserScreen> createState() => SignupUserScreenState();
|
||||
}
|
||||
|
||||
class SignupUserScreenState extends State<SignupUserScreen>{
|
||||
bool passwordVisible=false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
spacing: 30,
|
||||
children: [
|
||||
Text("Usuario y contacto"),
|
||||
Text("Crea tu usuario", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30)),
|
||||
Text("Con tu email y tu número podremos mantenerte siempre informado"),
|
||||
TextField(decoration: InputDecoration(labelText: "Correo electrónico", hintText: "Correo electrónico", border: OutlineInputBorder())),
|
||||
Row(children: [
|
||||
DropdownMenu(
|
||||
initialSelection: "es",
|
||||
dropdownMenuEntries: List<DropdownMenuEntry>.generate(3, (int index){
|
||||
return DropdownMenuEntry(labelWidget: Icon(Icons.outlined_flag), label: "es", value: "es");
|
||||
})
|
||||
),
|
||||
Expanded(child: TextField(
|
||||
decoration: InputDecoration(labelText: "Teléfono móvil", hintText: "Teléfono", border: OutlineInputBorder()),
|
||||
keyboardType: TextInputType.number)
|
||||
)
|
||||
]),
|
||||
TextField(
|
||||
obscureText: passwordVisible,
|
||||
enableSuggestions: false,
|
||||
autocorrect: false,
|
||||
decoration: InputDecoration(
|
||||
labelText: "Contraseña",
|
||||
hintText: "********",
|
||||
border: OutlineInputBorder(),
|
||||
suffixIcon: IconButton(
|
||||
icon: Icon(passwordVisible
|
||||
? Icons.visibility
|
||||
: Icons.visibility_off),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
passwordVisible = !passwordVisible;
|
||||
});
|
||||
},
|
||||
),
|
||||
)
|
||||
),
|
||||
TextField(obscureText: passwordVisible,
|
||||
enableSuggestions: false,
|
||||
autocorrect: false,
|
||||
decoration: InputDecoration(
|
||||
labelText: "Repetir contraseña",
|
||||
hintText: "*******",
|
||||
border: OutlineInputBorder(),
|
||||
suffixIcon: IconButton(
|
||||
icon: Icon(passwordVisible
|
||||
? Icons.visibility
|
||||
: Icons.visibility_off),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
passwordVisible = !passwordVisible;
|
||||
});
|
||||
},
|
||||
),
|
||||
)
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
69
modules/auth/pubspec.yaml
Normal file
69
modules/auth/pubspec.yaml
Normal file
@@ -0,0 +1,69 @@
|
||||
name: auth
|
||||
# resolution: workspace
|
||||
description: "A new Flutter package project."
|
||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
version: 0.0.1
|
||||
homepage:
|
||||
|
||||
environment:
|
||||
sdk: ^3.9.2
|
||||
flutter: ">=1.17.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
#modules dependencies go here
|
||||
dashboard_shell:
|
||||
path: ../../modules/dashboard_shell
|
||||
#packages dependencies go here
|
||||
design_system:
|
||||
path: ../../packages/design_system
|
||||
navigation:
|
||||
path: ../../packages/navigation
|
||||
#dependencies go here
|
||||
flutter_svg: ^2.2.1
|
||||
get_it: ^9.0.5
|
||||
go_router: ^17.0.0
|
||||
flutter_riverpod: ^3.0.3
|
||||
|
||||
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
|
||||
16
modules/auth/pubspec_overrides.yaml
Normal file
16
modules/auth/pubspec_overrides.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
# melos_managed_dependency_overrides: dashboard_shell,design_system,home,notifications,profile,sf_shared,navigation
|
||||
dependency_overrides:
|
||||
dashboard_shell:
|
||||
path: ../dashboard_shell
|
||||
design_system:
|
||||
path: ../../packages/design_system
|
||||
home:
|
||||
path: ../home
|
||||
navigation:
|
||||
path: ../../packages/navigation
|
||||
notifications:
|
||||
path: ../notifications
|
||||
profile:
|
||||
path: ../profile
|
||||
sf_shared:
|
||||
path: ../../packages/sf_shared
|
||||
Reference in New Issue
Block a user