Commit 6141e6e7 by yenisleydi

tarea 11

parent 8b3ebbf3
description: This file stores settings for Dart & Flutter DevTools.
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
extensions:
import 'package:flutter/material.dart';
import 'package:primer_practica/src/delegates/article_search_delegate.dart';
import 'package:provider/provider.dart';
import 'package:primer_practica/src/providers/carrito_providers.dart';
import 'package:badges/badges.dart' as badges;
class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
@override
Widget build(BuildContext context) {
var carrito = Provider.of<CarritoProvider>(context, listen: true);
return AppBar(
title: const Text('Home'),
backgroundColor: Colors.blue,
actions: [
IconButton(
icon: const Icon(Icons.search),
onPressed: () {
showSearch(
context: context,
delegate: ArticleSearchDelegate(),
);
},
),
Padding(
padding: const EdgeInsets.only(right: 16.0),
child: badges.Badge(
badgeContent: Text(
'${carrito.totalCarrito}',
style: const TextStyle(color: Colors.white),
),
child: IconButton(
icon: const Icon(Icons.shopping_cart),
onPressed: () {
Navigator.pushNamed(context, 'carrito');
},
),
),
),
],
);
}
@override
Size get preferredSize => Size.fromHeight(kToolbarHeight);
}
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:primer_practica/src/providers/carrito_providers.dart';
import 'package:primer_practica/src/config/routes.dart'; import 'package:primer_practica/src/config/routes.dart';
void main() { void main() {
...@@ -10,14 +12,21 @@ class MyApp extends StatelessWidget { ...@@ -10,14 +12,21 @@ class MyApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MultiProvider(
title: 'Primer practica', providers: [
theme: ThemeData( ChangeNotifierProvider(
primarySwatch: Colors.blue, create: (context) => CarritoProvider(),
),
],
child: MaterialApp(
title: 'Primer practica',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: 'login',
debugShowCheckedModeBanner: false,
routes: getApplicationRoutes(),
), ),
initialRoute: 'login', // Establece la ruta inicial
debugShowCheckedModeBanner: false,
routes: getApplicationRoutes(), // Usa las rutas definidas
); );
} }
} }
...@@ -2,13 +2,13 @@ import 'package:flutter/material.dart'; ...@@ -2,13 +2,13 @@ import 'package:flutter/material.dart';
import 'package:primer_practica/src/pages/formulario_categoria.dart'; import 'package:primer_practica/src/pages/formulario_categoria.dart';
import 'package:primer_practica/src/pages/login_page.dart'; import 'package:primer_practica/src/pages/login_page.dart';
import 'package:primer_practica/src/pages/home_page.dart'; import 'package:primer_practica/src/pages/home_page.dart';
import 'package:primer_practica/src/pages/carrito_page.dart';
Map<String, WidgetBuilder> getApplicationRoutes() { Map<String, WidgetBuilder> getApplicationRoutes() {
return <String, WidgetBuilder>{ return <String, WidgetBuilder>{
'login': (BuildContext context) => const LoginPage(), 'login': (BuildContext context) => LoginPage(),
'home': (BuildContext context) => const HomePage(), 'home': (BuildContext context) => HomePage(),
//'articles': (BuildContext context) => const ArticlesPage(), 'carrito': (BuildContext context) => CarritoPage(),
'formulario': (BuildContext context) => const FormularioCategoria(), 'formulario': (BuildContext context) => FormularioCategoria(),
}; };
} }
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:primer_practica/src/controllers/articles_controller.dart'; import 'package:primer_practica/src/controllers/articles_controller.dart';
import 'package:primer_practica/src/models/articles_model.dart'; import 'package:primer_practica/src/models/articles_model.dart';
import 'package:primer_practica/src/providers/carrito_providers.dart'; // Importa CarritoProvider
class ArticleSearchDelegate extends SearchDelegate { class ArticleSearchDelegate extends SearchDelegate {
final ArticleController articleCtrl = ArticleController(); final ArticleController articleCtrl = ArticleController();
...@@ -67,7 +69,8 @@ class ArticleSearchDelegate extends SearchDelegate { ...@@ -67,7 +69,8 @@ class ArticleSearchDelegate extends SearchDelegate {
trailing: IconButton( trailing: IconButton(
icon: Icon(Icons.shopping_cart), icon: Icon(Icons.shopping_cart),
onPressed: () { onPressed: () {
final carritoProvider = Provider.of<CarritoProvider>(context, listen: false);
carritoProvider.agregarCarrito(article); // Llama al método correcto
close(context, null); // Cierra el SearchDelegate close(context, null); // Cierra el SearchDelegate
}, },
), ),
......
import 'dart:convert'; // Para convertir datos a JSON import 'dart:convert';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:primer_practica/environments/urls.dart' as api; import 'package:primer_practica/environments/urls.dart' as api;
......
class ArticlesModel{ class ArticlesModel {
final int id; final int id;
final String clave; final String clave;
final String nombre; final String nombre;
...@@ -29,6 +29,17 @@ class ArticlesModel{ ...@@ -29,6 +29,17 @@ class ArticlesModel{
); );
} }
Map<String, dynamic> toJson() {
return {
'id': id,
'clave': clave,
'nombre': nombre,
'categoriaId': categoriaId,
'precios': precios.map((price) => price.toJson()).toList(),
'activo': activo,
};
}
static List<ArticlesModel> fromJsonArray(List<dynamic> jsonArray) { static List<ArticlesModel> fromJsonArray(List<dynamic> jsonArray) {
return jsonArray.map((json) => ArticlesModel.fromJson(json)).toList(); return jsonArray.map((json) => ArticlesModel.fromJson(json)).toList();
} }
...@@ -49,4 +60,11 @@ class Price { ...@@ -49,4 +60,11 @@ class Price {
precio: json['precio'].toDouble(), precio: json['precio'].toDouble(),
); );
} }
}
\ No newline at end of file Map<String, dynamic> toJson() {
return {
'id': id,
'precio': precio,
};
}
}
import 'package:primer_practica/src/models/articles_model.dart';
class CarritoModel {
final ArticlesModel articulo;
int cantidad;
double precio;
CarritoModel({
required this.articulo,
this.cantidad = 1,
double? precio,
}) : precio = precio ?? (articulo.precios.isNotEmpty ? articulo.precios[0].precio : 0.0);
Map<String, dynamic> toJson() {
return {
'articulo': articulo.toJson(),
'cantidad': cantidad,
'precio': precio,
};
}
factory CarritoModel.fromJson(Map<String, dynamic> json) {
return CarritoModel(
articulo: ArticlesModel.fromJson(json['articulo']),
cantidad: json['cantidad'],
precio: json['precio'], // Asegúrate de que se maneje correctamente el precio
);
}
}
...@@ -6,7 +6,6 @@ class ArticlePage extends StatefulWidget { ...@@ -6,7 +6,6 @@ class ArticlePage extends StatefulWidget {
final int categoryId; final int categoryId;
// creamos un constructor de ArticlePage que recibe categoryId como parámetro.
const ArticlePage({Key? key, required this.categoryId}) : super(key: key); const ArticlePage({Key? key, required this.categoryId}) : super(key: key);
@override @override
_ArticlePageState createState() => _ArticlePageState(); _ArticlePageState createState() => _ArticlePageState();
...@@ -20,8 +19,6 @@ class _ArticlePageState extends State<ArticlePage> { ...@@ -20,8 +19,6 @@ class _ArticlePageState extends State<ArticlePage> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
// Inicializa _articlesFuture llamando al método getArticles del controlador de
// artículos con el categoryId.
_articlesFuture = _articleController.getArticles(widget.categoryId); _articlesFuture = _articleController.getArticles(widget.categoryId);
} }
...@@ -43,7 +40,6 @@ class _ArticlePageState extends State<ArticlePage> { ...@@ -43,7 +40,6 @@ class _ArticlePageState extends State<ArticlePage> {
List<ArticlesModel> articles = snapshot.data!['data'] as List<ArticlesModel>; List<ArticlesModel> articles = snapshot.data!['data'] as List<ArticlesModel>;
//Lista de articulos //Lista de articulos
return ListView.builder( return ListView.builder(
// Definimos el número de elementos en la lista.
itemCount: articles.length, itemCount: articles.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final article = articles[index]; final article = articles[index];
......
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:primer_practica/src/providers/carrito_providers.dart';
import 'package:primer_practica/src/models/carrito_model.dart';
class CarritoPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
var carritoProvider = Provider.of<CarritoProvider>(context);
return Scaffold(
appBar: AppBar(
title: Text('Carrito'),
),
body: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: carritoProvider.carrito.length, // Número de elementos en el carrito
itemBuilder: (context, index) {
final item = carritoProvider.carrito[index];
return CarritoItemWidget(item: item); // Construte los elementos
},
),
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'\$ ${carritoProvider.totalPrecio.toStringAsFixed(2)}', // Total de todos los articulos
style: TextStyle(fontSize: 24, fontWeight: FontWeight.w700),
),
ElevatedButton(
onPressed: () {
},
child: Text('COMPRAR'),
),
],
),
),
],
),
);
}
}
class CarritoItemWidget extends StatelessWidget {
final CarritoModel item;
const CarritoItemWidget({Key? key, required this.item}) : super(key: key);
@override
Widget build(BuildContext context) {
var carritoProvider = Provider.of<CarritoProvider>(context, listen: false);
return Card(
margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
child: Padding(
padding: const EdgeInsets.all(30.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
item.articulo.nombre, // Muestra el nombre del artículo
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Precio: \$${item.precio.toStringAsFixed(2)}'), // Muestra el precio del artículo
Row(
children: [
IconButton(
icon: Icon(Icons.remove),
onPressed: () {
if (item.cantidad > 1) {
carritoProvider.actualizarArticulo(item, item.cantidad - 1); // Disminuye la cantidad del artículo
}
},
),
Text('${item.cantidad}'),
IconButton(
icon: Icon(Icons.add),
onPressed: () {
carritoProvider.actualizarArticulo(item, item.cantidad + 1); // Aumenta la cantidad del artículo
},
),
],
),
Text('Total: \$${(item.precio * item.cantidad).toStringAsFixed(2)}'), // Muestra el total por artículo
],
),
IconButton(
icon: Icon(Icons.delete, color: Colors.red),
onPressed: () {
carritoProvider.eliminarDelCarrito(item);
},
),
],
),
),
);
}
}
...@@ -46,10 +46,9 @@ class _FormularioCategoriaState extends State<FormularioCategoria> { ...@@ -46,10 +46,9 @@ class _FormularioCategoriaState extends State<FormularioCategoria> {
if (result['ok']) { if (result['ok']) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(result['message'])), // Muestra mensaje de éxito SnackBar(content: Text(result['message'])),
); );
print("hola"); print("hola");
//Navigator.pop(context);
Navigator.pushNamed(context, 'home'); Navigator.pushNamed(context, 'home');
} else { } else {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
...@@ -79,7 +78,7 @@ class _FormularioCategoriaState extends State<FormularioCategoria> { ...@@ -79,7 +78,7 @@ class _FormularioCategoriaState extends State<FormularioCategoria> {
decoration: const InputDecoration(labelText: 'Nombre'), decoration: const InputDecoration(labelText: 'Nombre'),
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
), ),
const SizedBox(height: 60), // Ajuste del espacio entre campos y botón const SizedBox(height: 60),
ElevatedButton( ElevatedButton(
onPressed: _guardarCategoria, onPressed: _guardarCategoria,
child: const Text('GUARDAR'), child: const Text('GUARDAR'),
......
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:primer_practica/src/pages/category/lista_categorias.dart'; import 'package:primer_practica/src/pages/category/lista_categorias.dart';
import 'package:primer_practica/src/delegates/article_search_delegate.dart'; import 'package:primer_practica/custom/custom_app_bar.dart';
import 'package:primer_practica/src/providers/carrito_providers.dart';
import 'package:provider/provider.dart';
class HomePage extends StatelessWidget { class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key); const HomePage({Key? key}) : super(key: key);
...@@ -8,21 +10,7 @@ class HomePage extends StatelessWidget { ...@@ -8,21 +10,7 @@ class HomePage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: CustomAppBar(),
title: const Text('Home'),
backgroundColor: Colors.blue,
actions: [
IconButton(
icon: const Icon(Icons.search),
onPressed: () {
showSearch(
context: context,
delegate: ArticleSearchDelegate(),
);
},
)
],
),
drawer: Drawer( drawer: Drawer(
child: ListView( child: ListView(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
......
import 'package:flutter/material.dart';
import 'package:primer_practica/src/models/carrito_model.dart';
import 'package:primer_practica/src/models/articles_model.dart';
class CarritoProvider with ChangeNotifier {
List<CarritoModel> _carrito = [];
List<CarritoModel> get carrito => _carrito;
void agregarCarrito(ArticlesModel article) {
final carritoItem = CarritoModel(
articulo: article,
cantidad: 1,
precio: article.precios.isNotEmpty ? article.precios[0].precio : 0.0,
);
_carrito.add(carritoItem);
notifyListeners();
}
void eliminarDelCarrito(CarritoModel item) {
_carrito.remove(item);
notifyListeners();
}
void actualizarArticulo(CarritoModel item, int quantity) {
int index = _carrito.indexOf(item);
if (index != -1) {
_carrito[index].cantidad = quantity;
notifyListeners();
}
}
double get totalPrecio {
double total = 0.0;
for (var item in _carrito) {
total += item.precio * item.cantidad;
}
return total;
}
int get totalCarrito => _carrito.length;
}
...@@ -17,6 +17,14 @@ packages: ...@@ -17,6 +17,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.11.0" version: "2.11.0"
badges:
dependency: "direct main"
description:
name: badges
sha256: "727580d938b7a1ff47ea42df730d581415606b4224cfa708671c10287f8d3fe6"
url: "https://pub.dev"
source: hosted
version: "2.0.3"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
...@@ -232,6 +240,14 @@ packages: ...@@ -232,6 +240,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.12.0" version: "1.12.0"
nested:
dependency: transitive
description:
name: nested
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
nm: nm:
dependency: transitive dependency: transitive
description: description:
...@@ -264,6 +280,14 @@ packages: ...@@ -264,6 +280,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.8" version: "2.1.8"
provider:
dependency: "direct main"
description:
name: provider
sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c
url: "https://pub.dev"
source: hosted
version: "6.1.2"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
......
...@@ -32,6 +32,8 @@ dependencies: ...@@ -32,6 +32,8 @@ dependencies:
sdk: flutter sdk: flutter
http: ^1.2.2 http: ^1.2.2
connectivity_plus: ^2.3.6 connectivity_plus: ^2.3.6
provider: ^6.1.2
badges: ^2.0.1
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment