- 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:
AlcalaJulian
2025-11-13 15:16:00 +01:00
parent 75beafd771
commit 5ca37d2822
332 changed files with 7759 additions and 3452 deletions

31
modules/home/.gitignore vendored Normal file
View 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/home/.metadata Normal file
View 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

View File

@@ -0,0 +1,3 @@
## 0.0.1
* TODO: Describe initial release.

1
modules/home/LICENSE Normal file
View File

@@ -0,0 +1 @@
TODO: Add your license here.

39
modules/home/README.md Normal file
View 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.

View 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

View File

@@ -0,0 +1 @@
export 'src/presentation/home_screen.dart';

View File

@@ -0,0 +1,193 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:sf_shared/sf_shared.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class DepositScreen extends ConsumerWidget {
final Kid kid;
DepositScreen({super.key, required this.kid});
String reason = "other";
bool program = false;
@override
Widget build(BuildContext context, WidgetRef ref) {
final theme = ref.watch(themePortProvider);
return WalletManagementLayout(
kid: kid,
footer: Container(
decoration: BoxDecoration(
color: theme.getColorFor(ThemeCode.backgroundPrimary),
borderRadius: BorderRadius.all(Radius.circular(20)),
),
padding: EdgeInsets.all(10),
child: Column(
children: [
FilledButton(
onPressed: () => {},
child: Container(
width: double.infinity,
padding: EdgeInsets.all(20),
child: Center(child: Text("Añadir dinero")),
),
),
TextButton(
onPressed: () => Navigator.pop(context),
child: Text("Cancelar"),
),
],
),
),
children: [
Container(
decoration: BoxDecoration(
color: theme.getColorFor(ThemeCode.backgroundPrimary),
borderRadius: BorderRadius.all(Radius.circular(20)),
),
padding: EdgeInsets.all(10),
child: Column(
spacing: 10,
children: [
Text(
"Ingresar dinero en el wallet",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
),
TextField(
decoration: InputDecoration(
labelText: "Cantidad",
hintText: "0€",
border: OutlineInputBorder(),
),
keyboardType: TextInputType.number,
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
),
Align(
alignment: Alignment.topLeft,
child: Text("Saldo total disponible después: 30 €"),
),
],
),
),
Container(
decoration: BoxDecoration(
color: theme.getColorFor(ThemeCode.backgroundPrimary),
borderRadius: BorderRadius.all(Radius.circular(20)),
),
padding: EdgeInsets.all(10),
child: Column(
spacing: 10,
children: [
Text(
"Motivo",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
),
Text("Este dato aparecerá en el reloj del peque"),
CheckboxListTile(
title: Text('Paga semanal'),
controlAffinity: ListTileControlAffinity.leading,
value: reason == "weekly",
onChanged: (value) {
// setState(() {
// reason = "weekly";
// });
},
activeColor: theme.getColorFor(ThemeCode.buttonPrimary),
),
CheckboxListTile(
title: Text('Objetivo semanal cumplido'),
controlAffinity: ListTileControlAffinity.leading,
value: reason == "goal",
onChanged: (value) {
// setState(() {
// reason = "goal";
// });
},
activeColor: theme.getColorFor(ThemeCode.buttonPrimary),
),
CheckboxListTile(
title: Text('Gastos extraordinarios'),
controlAffinity: ListTileControlAffinity.leading,
value: reason == "extraordinary",
onChanged: (value) {
// setState(() {
// reason = "extraordinary";
// });
},
activeColor: theme.getColorFor(ThemeCode.buttonPrimary),
),
CheckboxListTile(
title: Text('Otro'),
controlAffinity: ListTileControlAffinity.leading,
value: reason == "other",
onChanged: (value) {
// setState(() {
// reason = "other";
// });
},
activeColor: theme.getColorFor(ThemeCode.buttonPrimary),
),
TextField(
minLines: 3,
maxLines: 3,
maxLength: 150,
decoration: InputDecoration(
labelText:
"Escribir mensaje a ${kid.name} del motivo del ingreso",
hintText: "Escribe tu mensaje",
border: OutlineInputBorder(),
),
),
Align(
alignment: Alignment.topLeft,
child: Text("Máximo 150 caracteres"),
),
],
),
),
Container(
decoration: BoxDecoration(
color: theme.getColorFor(ThemeCode.backgroundPrimary),
borderRadius: BorderRadius.all(Radius.circular(20)),
),
padding: EdgeInsets.all(10),
child: Column(
spacing: 10,
children: [
Text(
"Cuándo se envía el dinero",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
),
Text("Este dato aparecerá en el reloj del peque"),
CheckboxListTile(
title: Text('Ahora'),
controlAffinity: ListTileControlAffinity.leading,
value: program == false,
onChanged: (value) {
// setState(() {
// program = false;
// });
},
activeColor: theme.getColorFor(ThemeCode.buttonPrimary),
),
CheckboxListTile(
title: Text('Programar'),
controlAffinity: ListTileControlAffinity.leading,
value: program == true,
onChanged: (value) {
// setState(() {
// program = true;
// });
},
activeColor: theme.getColorFor(ThemeCode.buttonPrimary),
),
if (program) TextField(),
],
),
),
],
);
}
}

View File

@@ -0,0 +1,274 @@
import 'package:auth/auth.dart';
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:home/src/presentation/deposit_screen.dart';
import 'package:home/src/presentation/kid_wallet_screen.dart';
import 'package:home/src/presentation/money_text.dart';
import 'package:sf_shared/sf_shared.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class HomeScreen extends ConsumerWidget {
final String name = "Juan";
final double total = 95.03;
final List<Kid> kids = [
Kid(name: "Carlos", balance: 25.47),
Kid(name: "Ana", balance: 25.47),
];
late final double available = double.parse(
kids.fold(total, (t, e) => t - e.balance).toStringAsFixed(2),
);
HomeScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final theme = ref.watch(themePortProvider);
return SafeArea(
child: SingleChildScrollView(
child: Container(
color: theme.getColorFor(ThemeCode.backgroundSecondary),
margin: EdgeInsets.all(30),
child: Column(
children: [
Align(
alignment: Alignment.topLeft,
child: Text.rich(
TextSpan(
text: "Hola, ",
style: TextStyle(fontSize: 25),
children: <TextSpan>[
TextSpan(
text: name,
style: TextStyle(fontWeight: FontWeight.bold),
),
],
),
),
),
walletsList(context, kids, ref),
Align(
alignment: Alignment.topLeft,
child: TextButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(builder: (_) => CreateProfileScreen()),
),
child: Text(
"+ Añadir otro peque",
style: TextStyle(
fontWeight: FontWeight.bold,
color: theme.getColorFor(ThemeCode.textPrimary),
),
),
),
),
Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
color: theme.getColorFor(ThemeCode.backgroundPrimary),
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child: Column(
spacing: 5,
children: [
Row(
children: [
Text(
"Wallet",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
),
),
Spacer(),
MoneyText(
text: "$total€ total",
size: 25,
resize: true,
color: theme.getColorFor(ThemeCode.textPrimary),
),
],
),
Stack(
children: [
LinearProgressIndicator(
value: available / total,
minHeight: 70,
borderRadius: BorderRadius.all(Radius.circular(16)),
color: theme.getColorFor(ThemeCode.buttonPrimary),
backgroundColor: theme.getColorFor(
ThemeCode.backgroundTertiary,
),
),
FractionallySizedBox(
widthFactor: available / total,
child: Container(
padding: EdgeInsets.symmetric(vertical: 10),
child: Center(
child: MoneyText(
text: "$available",
size: 35,
resize: true,
color: theme.getColorFor(
ThemeCode.textSecondary,
),
),
),
),
),
],
),
Center(child: Text("Disponible")),
],
),
),
DepositBlock(max: 150 - total),
],
),
),
),
);
}
Widget walletsList(BuildContext context, List<Kid> kids, WidgetRef ref) {
final theme = ref.watch(themePortProvider);
return Column(
spacing: 20,
children: List<Widget>.generate(kids.length, (int index) {
return GestureDetector(
onTap: () => {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => KidWalletScreen(kid: kids[index]),
),
),
},
child: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(16.0)),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 8),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: theme.getCardColorFor(index),
),
),
child: Column(
children: [
Align(
alignment: Alignment.topLeft,
child: Text(
kids[index].name,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25,
color: theme.getColorFor(ThemeCode.textSecondary),
),
),
),
Row(
spacing: 10,
children: [
SizedBox(
height: 60,
width: 60,
child: SvgPicture.asset("assets/images/ui/face.svg"),
),
Spacer(),
Column(
children: [
MoneyText(
text: "${kids[index].balance}",
size: 50,
resize: true,
color: theme.getColorFor(ThemeCode.textSecondary),
),
Text(
"en su hucha",
style: TextStyle(
color: theme.getColorFor(ThemeCode.textSecondary),
),
),
],
),
],
),
Row(
children: [
TextButton(
onPressed: () => showDialog(
context: context,
builder: (BuildContext context) => Dialog(
child: Container(
height: 100,
width: double.infinity,
child: Column(
children: [
FilledButton(
onPressed: () => {},
child: Text("Cámara"),
),
OutlinedButton(
onPressed: () => {},
child: Text("Galería de fotos"),
),
],
),
),
),
),
child: Row(
spacing: 10,
children: [
Icon(
Icons.edit,
color: theme.getColorFor(ThemeCode.textSecondary),
),
Text(
"Editar",
style: TextStyle(
color: theme.getColorFor(
ThemeCode.textSecondary,
),
),
),
],
),
),
Spacer(),
FilledButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (_) => DepositScreen(kid: kids[index]),
),
),
style: ButtonStyle(
backgroundColor: WidgetStatePropertyAll<Color>(
theme.getColorFor(ThemeCode.buttonSecondary),
),
),
child: Container(
padding: EdgeInsets.symmetric(
horizontal: 0,
vertical: 10,
),
child: Text("+ Añadir dinero"),
),
),
],
),
],
),
),
),
);
}),
);
}
}

View File

@@ -0,0 +1,308 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:home/src/presentation/deposit_screen.dart';
import 'package:sf_shared/sf_shared.dart';
import 'package:home/src/presentation/limits_screen.dart';
import 'package:home/src/presentation/money_text.dart';
import 'package:home/src/presentation/wage_screen.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class KidWalletScreen extends ConsumerWidget {
final Kid kid;
const KidWalletScreen({super.key, required this.kid});
@override
Widget build(BuildContext context, WidgetRef ref) {
final theme = ref.watch(themePortProvider);
return Scaffold(
backgroundColor: theme.getColorFor(ThemeCode.backgroundSecondary),
body: Stack(
children: [
DecoratedBox(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(30)),
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: theme.getCardColorFor(0),
),
),
child: SizedBox(width: double.infinity, height: 300),
),
Container(
margin: EdgeInsets.symmetric(vertical: 50, horizontal: 20),
child: Column(
spacing: 15,
children: [
Row(
spacing: 7,
children: [
IconButton(
onPressed: () => Navigator.pop(context),
icon: Icon(
Icons.arrow_back_ios_new_outlined,
color: theme.getColorFor(ThemeCode.backgroundPrimary),
),
),
SizedBox(
height: 50,
child: SvgPicture.asset("assets/images/ui/face.svg"),
),
Text(
kid.name,
style: TextStyle(
color: theme.getColorFor(ThemeCode.backgroundPrimary),
fontWeight: FontWeight.bold,
fontSize: 20,
),
),
Spacer(),
SizedBox(
height: 30,
child: SvgPicture.asset("assets/images/ui/face.svg"),
),
],
),
MoneyText(
text: "${kid.balance.toString()}",
size: 60,
resize: true,
color: theme.getColorFor(ThemeCode.textSecondary),
),
Text(
"Saldo disponible",
style: TextStyle(
color: theme.getColorFor(ThemeCode.backgroundPrimary),
),
),
LinearProgressIndicator(
value: 0.7,
color: theme.getColorFor(ThemeCode.backgroundPrimary),
backgroundColor: theme
.getColorFor(ThemeCode.backgroundPrimary)
.withAlpha(0x4C),
minHeight: 10,
borderRadius: BorderRadius.all(Radius.circular(5)),
),
Container(
padding: EdgeInsets.all(10),
margin: EdgeInsets.only(top: 30),
decoration: BoxDecoration(
color: theme.getColorFor(ThemeCode.backgroundPrimary),
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child: Expanded(
child: Center(
child: Row(
spacing: 10,
children: [
TextButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (_) => DepositScreen(kid: kid),
),
),
child: Column(
spacing: 10,
children: [
Icon(
Icons.add_circle_outline,
color: theme.getColorFor(
ThemeCode.textPrimary,
),
),
Text(
"Añadir",
style: TextStyle(
color: theme.getColorFor(
ThemeCode.textPrimary,
),
),
),
],
),
),
Spacer(),
TextButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (_) => WageScreen(kid: kid),
),
),
child: Column(
spacing: 10,
children: [
Icon(
Icons.account_balance_wallet_outlined,
color: theme.getColorFor(
ThemeCode.textPrimary,
),
),
Text(
"Paga",
style: TextStyle(
color: theme.getColorFor(
ThemeCode.textPrimary,
),
),
),
],
),
),
Spacer(),
TextButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (_) => LimitsScreen(kid: kid),
),
),
child: Column(
spacing: 10,
children: [
Icon(
Icons.list_alt_outlined,
color: theme.getColorFor(
ThemeCode.textPrimary,
),
),
Text(
"Límites",
style: TextStyle(
color: theme.getColorFor(
ThemeCode.textPrimary,
),
),
),
],
),
),
Spacer(),
TextButton(
onPressed: () => {},
child: Column(
spacing: 10,
children: [
Icon(
Icons.emoji_events_outlined,
color: theme.getColorFor(
ThemeCode.textPrimary,
),
),
Text(
"Metas",
style: TextStyle(
color: theme.getColorFor(
ThemeCode.textPrimary,
),
),
),
],
),
),
],
),
),
),
),
Container(
padding: EdgeInsets.all(15),
height: 400,
decoration: BoxDecoration(
color: theme.getColorFor(ThemeCode.backgroundPrimary),
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child: Column(
children: [
Text("Últimos movimientos"),
activityList(context, theme),
TextButton(onPressed: () => {}, child: Text("Ver todos")),
],
),
),
],
),
),
],
),
);
}
Widget activityList(BuildContext context, theme) {
final activity = [
{
"date": "10/05",
"payments": [1, 2, 3],
},
{
"date": "10/04",
"payments": [1, 2],
},
{
"date": "10/02",
"payments": [1, 2, 3, 4],
},
];
return Expanded(
child: ListView(
children: List<Widget>.generate(activity.length, (int index) {
return Column(
spacing: 20,
children: [
Text(activity[index]["date"].toString()),
Column(
spacing: 15,
children: List<Widget>.generate(
(activity[index]["payments"] as List<Object>).length,
(int i) {
//var a = (activity[index]["payments"] as List<Object>)[i];
return Row(
spacing: 7,
children: [
Container(
padding: EdgeInsets.all(9),
decoration: BoxDecoration(
color: theme.getColorFor(
ThemeCode.backgroundTertiary,
),
borderRadius: BorderRadius.all(Radius.circular(16)),
),
child: Icon(
Icons.local_pizza_outlined,
color: theme.getColorFor(ThemeCode.buttonPrimary),
),
),
Column(
children: [
Text(
"Vips",
style: TextStyle(fontWeight: FontWeight.bold),
),
Text("20:15"),
],
),
Spacer(),
MoneyText(
text: "5.1€",
size: 20,
resize: true,
color: theme.getColorFor(ThemeCode.textPrimary),
),
],
);
},
),
),
],
);
}),
),
);
}
}

View File

@@ -0,0 +1,156 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:sf_shared/sf_shared.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class LimitsScreen extends ConsumerStatefulWidget {
final Kid kid;
const LimitsScreen({super.key, required this.kid});
@override
ConsumerState<LimitsScreen> createState() => LimitsScreenState();
}
class LimitsScreenState extends ConsumerState<LimitsScreen> {
late List dailyLimits;
late List timeLimits;
late List conditions;
late List blocks;
@override
void initState() {
super.initState();
dailyLimits = [
{"title": "Diario L-V", "limit": "5", "edit": false},
{"title": "Fines de semana", "limit": "8", "edit": false},
{"title": "Semanal", "limit": "30", "edit": false},
{"title": "Mensual", "limit": "1200", "edit": false},
];
timeLimits = [
{
"title": "Lunes a Viernes",
"start": "08:00",
"end": "20:00",
"edit": false,
},
{
"title": "Fines de semana",
"start": "10:00",
"end": "21:00",
"edit": false,
},
{"title": "Vacaciones", "start": "09:00", "end": "22:00", "edit": false},
];
conditions = [
{"title": "Alimentación", "limit": "10", "edit": false},
{"title": "Transporte", "limit": "10", "edit": false},
{"title": "Alimentación", "limit": "10", "edit": false},
];
blocks = [];
}
@override
Widget build(BuildContext context) {
final theme = ref.watch(themePortProvider);
return WalletManagementLayout(
kid: widget.kid,
footer: Column(
children: [
FilledButton(
onPressed: () => {},
child: SizedBox(
width: double.infinity,
child: Center(child: Text("Guardar límites")),
),
),
],
),
children: [
Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20)),
color: theme.getColorFor(ThemeCode.backgroundPrimary),
),
child: Column(
spacing: 10,
children: [
Text(
"Pon límite de gastos",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
),
Text("Libertad para ellos, tranquilidad para ti"),
...List<Widget>.generate(dailyLimits.length, (int index) {
return Column(
children: [
Row(
children: [
Text(
"${dailyLimits[index]["title"]}: ${dailyLimits[index]["limit"]}",
),
Spacer(),
TextButton(
onPressed: () => {
setState(() {
dailyLimits[index]["edit"] =
!dailyLimits[index]["edit"];
}),
},
child: Text("Editar"),
),
],
),
if (dailyLimits[index]["edit"]) TextField(),
],
);
}),
],
),
),
Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20)),
color: theme.getColorFor(ThemeCode.backgroundPrimary),
),
child: Column(
spacing: 10,
children: [
Text(
"Horarios permitidos",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
),
Text("Controla cuándo pueden comprar"),
...List<Widget>.generate(timeLimits.length, (int index) {
return Column(
children: [
Row(
children: [
Text(
"${timeLimits[index]["title"]}: ${timeLimits[index]["start"]} - ${timeLimits[index]["end"]}",
),
Spacer(),
TextButton(
onPressed: () => {
setState(() {
timeLimits[index]["edit"] =
!timeLimits[index]["edit"];
}),
},
child: Text("Editar"),
),
],
),
if (timeLimits[index]["edit"]) TextField(),
],
);
}),
],
),
),
],
);
}
}

View File

@@ -0,0 +1,35 @@
import 'package:flutter/material.dart';
class MoneyText extends StatelessWidget {
final String text;
final double size;
final bool resize;
final Color color;
const MoneyText({super.key, required this.text, required this.size, required this.resize, required this.color});
@override
Widget build(BuildContext context) {
final units = text.split(".")[0];
final cents = ",${text.split(".")[1]}";
return Text.rich(TextSpan(
text: units,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: size,
color: color
),
children: [
TextSpan(
text: cents,
style: TextStyle(
fontWeight: FontWeight.normal,
fontSize: resize ? size/2 : size
)
)
]
));
}
}

View File

@@ -0,0 +1,228 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:sf_shared/sf_shared.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class WageScreen extends ConsumerWidget {
final Kid kid;
WageScreen({super.key, required this.kid});
String frequence = "weekly";
var conditions = {
"weeklyLimits": false,
"incidences": false,
"holidays": false,
};
@override
Widget build(BuildContext context, WidgetRef ref) {
final theme = ref.watch(themePortProvider);
return WalletManagementLayout(
kid: kid,
footer: Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
color: theme.getColorFor(ThemeCode.backgroundPrimary),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
),
child: Column(
spacing: 10,
children: [
FilledButton(
onPressed: () => {},
child: Container(
width: double.infinity,
padding: EdgeInsets.all(20),
child: Center(child: Text("Activar paga automática")),
),
),
TextButton(onPressed: () => {}, child: Text("Cancelar")),
],
),
),
children: [
Container(
decoration: BoxDecoration(
color: theme.getColorFor(ThemeCode.backgroundPrimary),
borderRadius: BorderRadius.all(Radius.circular(20)),
),
padding: EdgeInsets.all(10),
child: Column(
spacing: 10,
children: [
Text(
"Paga automática",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
),
TextField(
decoration: InputDecoration(
labelText: "Cantidad",
hintText: "0€",
border: OutlineInputBorder(),
),
keyboardType: TextInputType.number,
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
),
Text("Saldo total disponible después: 30 €"),
],
),
),
Container(
decoration: BoxDecoration(
color: theme.getColorFor(ThemeCode.backgroundPrimary),
borderRadius: BorderRadius.all(Radius.circular(20)),
),
padding: EdgeInsets.all(10),
child: Column(
spacing: 10,
children: [
Text(
"Frecuencia",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
),
Text("Cuándo se envía el dinero"),
CheckboxListTile(
title: Text('Semanal'),
controlAffinity: ListTileControlAffinity.leading,
value: frequence == "weekly",
onChanged: (value) {
// setState(() {
// frequence = "weekly";
// });
},
activeColor: theme.getColorFor(ThemeCode.buttonPrimary),
),
CheckboxListTile(
title: Text('Cada dos semanas'),
controlAffinity: ListTileControlAffinity.leading,
value: frequence == "biweekly",
onChanged: (value) {
// setState(() {
// frequence = "biweekly";
// });
},
activeColor: theme.getColorFor(ThemeCode.buttonPrimary),
),
CheckboxListTile(
title: Text('Mensual'),
controlAffinity: ListTileControlAffinity.leading,
value: frequence == "monthly",
onChanged: (value) {
// setState(() {
// frequence = "monthly";
// });
},
activeColor: theme.getColorFor(ThemeCode.buttonPrimary),
),
Container(
width: double.infinity,
child: DropdownMenu(
label: Text("Día de la semana"),
initialSelection: "Domingo",
dropdownMenuEntries: List<DropdownMenuEntry>.generate(7, (
int index,
) {
final days = [
"Lunes",
"Martes",
"Miércoles",
"Jueves",
"Viernes",
"Sábado",
"Domingo",
];
return DropdownMenuEntry(
value: days[index],
label: days[index],
);
}),
),
),
DropdownMenu(
label: Text("Hora del día"),
initialSelection: 9,
dropdownMenuEntries: List<DropdownMenuEntry>.generate(24, (
int index,
) {
return DropdownMenuEntry(value: index, label: "$index:00");
}),
),
TextField(
minLines: 3,
maxLines: 3,
maxLength: 150,
decoration: InputDecoration(
labelText:
"Escribir mensaje a ${kid.name} del motivo del ingreso",
hintText: "Escribe tu mensaje",
border: OutlineInputBorder(),
),
),
Align(
alignment: Alignment.topLeft,
child: Text("Máximo 150 caracteres"),
),
],
),
),
Container(
decoration: BoxDecoration(
color: theme.getColorFor(ThemeCode.backgroundPrimary),
borderRadius: BorderRadius.all(Radius.circular(20)),
),
padding: EdgeInsets.all(10),
child: Column(
spacing: 10,
children: [
Text(
"Condiciones",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
),
Text("Este dato aparecerá en el reloj del peque"),
CheckboxListTile(
title: Text('Sólo si cumple límites semanales'),
controlAffinity: ListTileControlAffinity.leading,
value: conditions["weeklyLimits"],
onChanged: (value) {
// setState(() {
// conditions["weeklyLimits"] = !conditions["weeklyLimits"]!;
// });
},
activeColor: theme.getColorFor(ThemeCode.buttonPrimary),
),
CheckboxListTile(
title: Text('Sólo si no ha tenido incidencias'),
controlAffinity: ListTileControlAffinity.leading,
value: conditions["incidences"],
onChanged: (value) {
// setState(() {
// conditions["incidences"] = !conditions["incidences"]!;
// });
},
activeColor: theme.getColorFor(ThemeCode.buttonPrimary),
),
CheckboxListTile(
title: Text('Pausar durante vacaciones'),
controlAffinity: ListTileControlAffinity.leading,
value: conditions["holidays"],
onChanged: (value) {
// setState(() {
// conditions["holidays"] = !conditions["holidays"]!;
// });
},
activeColor: theme.getColorFor(ThemeCode.buttonPrimary),
),
],
),
),
],
);
}
}

70
modules/home/pubspec.yaml Normal file
View File

@@ -0,0 +1,70 @@
name: home
# 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
auth:
path: ../../modules/auth
notifications:
path: ../../modules/notifications
#packages dependencies go here
design_system:
path: ../../packages/design_system
sf_shared:
path: ../../packages/sf_shared
#dependencies go here
flutter_svg: ^2.2.1
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

View File

@@ -0,0 +1,16 @@
# melos_managed_dependency_overrides: auth,dashboard_shell,design_system,notifications,profile,sf_shared,navigation
dependency_overrides:
auth:
path: ../auth
dashboard_shell:
path: ../dashboard_shell
design_system:
path: ../../packages/design_system
navigation:
path: ../../packages/navigation
notifications:
path: ../notifications
profile:
path: ../profile
sf_shared:
path: ../../packages/sf_shared