Commit f518b35c by yenisleydi

tarea 12

parent 6141e6e7
...@@ -70,8 +70,8 @@ class ArticleSearchDelegate extends SearchDelegate { ...@@ -70,8 +70,8 @@ class ArticleSearchDelegate extends SearchDelegate {
icon: Icon(Icons.shopping_cart), icon: Icon(Icons.shopping_cart),
onPressed: () { onPressed: () {
final carritoProvider = Provider.of<CarritoProvider>(context, listen: false); final carritoProvider = Provider.of<CarritoProvider>(context, listen: false);
carritoProvider.agregarCarrito(article); // Llama al método correcto carritoProvider.agregarCarrito(article);
close(context, null); // Cierra el SearchDelegate close(context, null);
}, },
), ),
); );
......
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;
import 'dart:convert';
class ArticlesApi { class ArticlesApi {
Future<Map<String, dynamic>> getArticles() async { Future<Map<String, dynamic>> getArticles() async {
...@@ -32,4 +33,37 @@ class ArticlesApi { ...@@ -32,4 +33,37 @@ class ArticlesApi {
return {"statusCode": 501, "body": '$e'}; return {"statusCode": 501, "body": '$e'};
} }
} }
Future<Map<String, dynamic>> addArticle({
required String clave,
required int categoria,
required String nombre,
required List<double> precios,
required bool activo,
}) async {
String url = '${api.apiApp}/articulo';
final payload = {
'clave': clave,
'categoria': categoria,
'nombre': nombre,
'precios': precios.map((precio) => {'precio': precio}).toList(),
'activo': activo,
};
if (kDebugMode) {
print('Url -> $url');
print('Payload -> $payload');
}
try {
final resp = await http.post(
Uri.parse(url),
headers: {'Content-Type': 'application/json'},
body: json.encode(payload),
);
return {"statusCode": resp.statusCode, "body": resp.body};
} catch (e) {
return {"statusCode": 501, "body": '$e'};
}
}
} }
...@@ -36,7 +36,7 @@ class CategoryService { ...@@ -36,7 +36,7 @@ class CategoryService {
//conversión del objeto a Json //conversión del objeto a Json
final categoryJson = category.toJson(); final categoryJson = category.toJson();
// Imprime la URL y el cuerpo de la solicitud
if (kDebugMode) { if (kDebugMode) {
print('Url -> $url'); print('Url -> $url');
print('Body -> $categoryJson'); print('Body -> $categoryJson');
...@@ -45,8 +45,8 @@ class CategoryService { ...@@ -45,8 +45,8 @@ class CategoryService {
try { try {
// Realiza la solicitud POST al servidor // Realiza la solicitud POST al servidor
final response = await http.post( final response = await http.post(
Uri.parse(url), // Convierte la URL a un objeto Uri Uri.parse(url),
headers: {'Content-Type': 'application/json'}, // Establece el tipo de contenido como JSON headers: {'Content-Type': 'application/json'},
body: json.encode(categoryJson), body: json.encode(categoryJson),
); );
......
...@@ -23,7 +23,7 @@ class CarritoModel { ...@@ -23,7 +23,7 @@ class CarritoModel {
return CarritoModel( return CarritoModel(
articulo: ArticlesModel.fromJson(json['articulo']), articulo: ArticlesModel.fromJson(json['articulo']),
cantidad: json['cantidad'], cantidad: json['cantidad'],
precio: json['precio'], // Asegúrate de que se maneje correctamente el precio precio: json['precio'],
); );
} }
} }
import 'package:flutter/material.dart'; import 'package:flutter/material.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/pages/formulario_articulos.dart';
class ArticlePage extends StatefulWidget { class ArticlePage extends StatefulWidget {
final int categoryId; final int categoryId;
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();
} }
class _ArticlePageState extends State<ArticlePage> { class _ArticlePageState extends State<ArticlePage> {
final ArticleController _articleController = ArticleController(); final ArticleController _articleController = ArticleController();
late Future<Map<String, dynamic>> _articlesFuture; late Future<Map<String, dynamic>> _articlesFuture;
@override @override
...@@ -30,15 +30,14 @@ class _ArticlePageState extends State<ArticlePage> { ...@@ -30,15 +30,14 @@ class _ArticlePageState extends State<ArticlePage> {
backgroundColor: Colors.indigoAccent, backgroundColor: Colors.indigoAccent,
foregroundColor: Colors.white, foregroundColor: Colors.white,
), ),
body: FutureBuilder<Map<String, dynamic>>( body: FutureBuilder<Map<String, dynamic>>(
future: _articlesFuture, future: _articlesFuture,
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.hasData) { if (snapshot.hasData) {
if (snapshot.data!['ok']) { if (snapshot.data!['ok']) {
if (snapshot.data!['data'] != null && (snapshot.data!['data'] as List).isNotEmpty) { if (snapshot.data!['data'] != null && (snapshot.data!['data'] as List).isNotEmpty) {
List<ArticlesModel> articles = snapshot.data!['data'] as List<ArticlesModel>; List<ArticlesModel> articles = (snapshot.data!['data'] as List).cast<ArticlesModel>();
//Lista de articulos // Lista de artículos
return ListView.builder( return ListView.builder(
itemCount: articles.length, itemCount: articles.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
...@@ -47,7 +46,6 @@ class _ArticlePageState extends State<ArticlePage> { ...@@ -47,7 +46,6 @@ class _ArticlePageState extends State<ArticlePage> {
child: ListTile( child: ListTile(
title: Text(article.nombre), title: Text(article.nombre),
subtitle: Text('id :${article.categoriaId}'), subtitle: Text('id :${article.categoriaId}'),
//subtitle: Text('Clave: ${article.clave}'),
trailing: Text('\$${article.precios.isNotEmpty ? article.precios.first.precio.toStringAsFixed(2) : 'N/A'}'), trailing: Text('\$${article.precios.isNotEmpty ? article.precios.first.precio.toStringAsFixed(2) : 'N/A'}'),
), ),
); );
...@@ -66,6 +64,22 @@ class _ArticlePageState extends State<ArticlePage> { ...@@ -66,6 +64,22 @@ class _ArticlePageState extends State<ArticlePage> {
} }
}, },
), ),
floatingActionButton: FloatingActionButton(
onPressed: () async {
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => FormularioArticulos()),
);
if (result == true) {
setState(() {
_articlesFuture = _articleController.getArticles(widget.categoryId);
});
}
},
child: const Icon(Icons.add),
tooltip: 'Agregar artículo',
),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
); );
} }
} }
import 'package:flutter/material.dart';
import 'package:primer_practica/src/http_api/articles_api.dart'; // Asegúrate de importar la clase correcta
class FormularioArticulos extends StatefulWidget {
@override
_FormularioArticulosState createState() => _FormularioArticulosState();
}
class _FormularioArticulosState extends State<FormularioArticulos> {
final _formKey = GlobalKey<FormState>();
String _clave = '';
int _categoria = 1;
String _nombre = '';
List<double> _precios = [0.0, 0.0];
bool _activo = true;
final ArticlesApi _articlesApi = ArticlesApi();
Future<void> _guardarArticulo() async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
final result = await _articlesApi.addArticle(
clave: _clave,
categoria: _categoria,
nombre: _nombre,
precios: _precios,
activo: _activo,
);
if (result['statusCode'] == 200) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Artículo guardado exitosamente')),
);
Navigator.pop(context); // Regresa a la lista de artículos
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error al guardar el artículo')),
);
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Formulario de Artículo'),
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: ListView(
children: [
_buildTextField(
label: 'Clave',
onSaved: (value) => _clave = value!,
inputType: TextInputType.text,
),
_buildTextField(
label: 'Categoría',
onSaved: (value) => _categoria = int.parse(value!),
inputType: TextInputType.number,
),
_buildTextField(
label: 'Nombre',
onSaved: (value) => _nombre = value!,
inputType: TextInputType.text,
),
_buildTextField(
label: 'Precio 1',
onSaved: (value) => _precios[0] = double.parse(value!),
inputType: TextInputType.number,
),
_buildTextField(
label: 'Precio 2',
onSaved: (value) => _precios[1] = double.parse(value!),
inputType: TextInputType.number,
),
SizedBox(height: 30),
Center(
child: ElevatedButton(
onPressed: _guardarArticulo,
style: ElevatedButton.styleFrom(
padding: EdgeInsets.symmetric(horizontal: 24.0, vertical: 12.0),
textStyle: TextStyle(fontSize: 16),
),
child: Text('Guardar'),
),
),
],
),
),
),
);
}
Widget _buildTextField({
required String label,
required FormFieldSetter<String> onSaved,
required TextInputType inputType,
}) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 12.0),
child: TextFormField(
decoration: InputDecoration(
labelText: label,
border: OutlineInputBorder(),
contentPadding: EdgeInsets.symmetric(vertical: 15, horizontal: 10),
),
keyboardType: inputType,
onSaved: onSaved,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Este campo es obligatorio';
}
return null;
},
),
);
}
}
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/custom/custom_app_bar.dart'; import 'package:primer_practica/custom/custom_app_bar.dart';
import 'package:primer_practica/src/providers/carrito_providers.dart'; //import 'package:primer_practica/src/providers/carrito_providers.dart';
import 'package:provider/provider.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);
......
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