Commit 2f23dbd8 by yenisleydi

Tarea terminada

parent 83a0633f
import 'package:flutter/material.dart'; import 'package:flutter/material.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/articles_page.dart'; import 'package:primer_practica/src/pages/articles_page.dart';
...@@ -7,6 +8,7 @@ Map<String, WidgetBuilder> getApplicationRoutes() { ...@@ -7,6 +8,7 @@ Map<String, WidgetBuilder> getApplicationRoutes() {
return <String, WidgetBuilder>{ return <String, WidgetBuilder>{
'login': (BuildContext context) => const LoginPage(), 'login': (BuildContext context) => const LoginPage(),
'home': (BuildContext context) => const HomePage(), 'home': (BuildContext context) => const HomePage(),
'articles': (BuildContext context) => const ArticlesPage(), //'articles': (BuildContext context) => const ArticlesPage(),
'formulario': (BuildContext context) => const FormularioCategoria(),
}; };
} }
import 'dart:convert';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:primer_practica/src/models/articles_model.dart';
import '../http_api/articles_api.dart';
class ArticleController {
final Connectivity _connectivity = Connectivity();
final ArticlesApi _articleApi = ArticlesApi();
Future<Map<String, dynamic>> getArticles(int categoryId) async {
Map<String, dynamic> mapResp = {
'ok': false,
'message': 'No hay artículos',
'data': null
};
ConnectivityResult connectivityResult = await _connectivity.checkConnectivity();
if (connectivityResult != ConnectivityResult.none) {
if (connectivityResult == ConnectivityResult.wifi || connectivityResult == ConnectivityResult.mobile) {
Map<String, dynamic> respGet = await _articleApi.getArticles();
if (respGet['statusCode'] == 200) {
try {
var decodeResp = json.decode(respGet['body']);
List<ArticlesModel> listArticles = ArticlesModel.fromJsonArray(decodeResp['data']);
mapResp['ok'] = true;
mapResp['message'] = "${listArticles.length} artículos encontrados";
mapResp['data'] = listArticles;
} catch (e) {
mapResp['message'] = "Error en el procesamiento de datos: $e";
}
} else {
mapResp['message'] = "${respGet['body']}";
}
}
}
return mapResp;
}
}
\ No newline at end of file
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:primer_practica/environments/urls.dart' as api;
class ArticlesApi {
Future<Map<String, dynamic>> getArticles() async {
// Usa la constante `apiBaseUrl` de `urls.dart` para construir la URL
String url = '${api.apiApp}/articulo?offset=0&max=100';
if (kDebugMode) {
print('Url -> $url');
}
try {
final resp = await http.get(Uri.parse(url));
return {"statusCode": resp.statusCode, "body": resp.body};
} catch (e) {
return {"statusCode": 501, "body": '$e'};
}
}
}
class ArticlesModel{
final int id;
final String clave;
final String nombre;
final int categoriaId;
final List<Price> precios;
final bool activo;
ArticlesModel({
required this.id,
required this.clave,
required this.nombre,
required this.categoriaId,
required this.precios,
required this.activo,
});
factory ArticlesModel.fromJson(Map<String, dynamic> json) {
var list = json['precios'] as List;
List<Price> preciosList = list.map((i) => Price.fromJson(i)).toList();
return ArticlesModel(
id: json['id'],
clave: json['clave'],
nombre: json['nombre'],
categoriaId: json['categoria']['id'],
precios: preciosList,
activo: json['activo'],
);
}
static List<ArticlesModel> fromJsonArray(List<dynamic> jsonArray) {
return jsonArray.map((json) => ArticlesModel.fromJson(json)).toList();
}
}
class Price {
final int id;
final double precio;
Price({
required this.id,
required this.precio,
});
factory Price.fromJson(Map<String, dynamic> json) {
return Price(
id: json['id'],
precio: json['precio'].toDouble(),
);
}
}
\ No newline at end of file
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:primer_practica/src/controllers/articles_controller.dart';
import 'package:primer_practica/src/models/articles_model.dart';
class ArticlesPage extends StatelessWidget { class ArticlePage extends StatefulWidget {
const ArticlesPage({Key? key}) : super(key: key);
final int categoryId;
// creamos un constructor de ArticlePage que recibe categoryId como parámetro.
const ArticlePage({Key? key, required this.categoryId}) : super(key: key);
@override
_ArticlePageState createState() => _ArticlePageState();
}
class _ArticlePageState extends State<ArticlePage> {
final ArticleController _articleController = ArticleController();
late Future<Map<String, dynamic>> _articlesFuture;
@override
void initState() {
super.initState();
// Inicializa _articlesFuture llamando al método getArticles del controlador de
// artículos con el categoryId.
_articlesFuture = _articleController.getArticles(widget.categoryId);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text('Articles Page'), title: const Text('Artículos'),
backgroundColor: Colors.indigoAccent,
foregroundColor: Colors.white,
), ),
body: const Center(
child: Text('Hola articles page'), body: FutureBuilder<Map<String, dynamic>>(
future: _articlesFuture,
builder: (context, snapshot) {
if (snapshot.hasData) {
if (snapshot.data!['ok']) {
if (snapshot.data!['data'] != null && (snapshot.data!['data'] as List).isNotEmpty) {
List<ArticlesModel> articles = snapshot.data!['data'] as List<ArticlesModel>;
//Lista de articulos
return ListView.builder(
// Definimos el número de elementos en la lista.
itemCount: articles.length,
itemBuilder: (context, index) {
final article = articles[index];
return Card(
child: ListTile(
title: Text(article.nombre),
subtitle: Text('id :${article.categoriaId}'),
//subtitle: Text('Clave: ${article.clave}'),
trailing: Text('\$${article.precios.isNotEmpty ? article.precios.first.precio.toStringAsFixed(2) : 'N/A'}'),
),
);
},
);
} else {
return Center(child: Text('No se encontraron artículos.'));
}
} else {
return Center(child: Text('Error: ${snapshot.data!['message']}'));
}
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
} else {
return const Center(child: CircularProgressIndicator());
}
},
), ),
); );
} }
} }
\ No newline at end of file
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:primer_practica/src/controllers/categoty_controller.dart'; import 'package:primer_practica/src/controllers/categoty_controller.dart';
import 'package:primer_practica/src/pages/articles_page.dart';
import 'package:primer_practica/src/shared_widgets/widget_mensajes.dart' as msg_shared; import 'package:primer_practica/src/shared_widgets/widget_mensajes.dart' as msg_shared;
import 'package:primer_practica/src/models/categoryModel.dart'; import 'package:primer_practica/src/models/categoryModel.dart';
...@@ -25,6 +26,12 @@ class ListaCategorias extends StatelessWidget { ...@@ -25,6 +26,12 @@ class ListaCategorias extends StatelessWidget {
title: Text(category.name?? 'No Name'), // Muestra el nombre de la categoría title: Text(category.name?? 'No Name'), // Muestra el nombre de la categoría
leading: const Icon(Icons.touch_app), leading: const Icon(Icons.touch_app),
onTap: () { onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ArticlePage(categoryId: category.id),
),
);
// Navegar al listado de servicios // Navegar al listado de servicios
}, },
), ),
......
import 'package:flutter/material.dart';
class FormularioCategoria extends StatefulWidget {
const FormularioCategoria({super.key});
@override
_FormularioCategoriaState createState() => _FormularioCategoriaState();
}
class _FormularioCategoriaState extends State<FormularioCategoria> {
final _nombreController = TextEditingController();
final _claveController = TextEditingController();
@override
void dispose() {
_nombreController.dispose();
_claveController.dispose();
super.dispose();
}
void _guardarCategoria() {
final nombre = _nombreController.text;
final clave = _claveController.text;
if (nombre.isEmpty || clave.isEmpty) {
// Mostrar un mensaje de error si algún campo está vacío
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Por favor, complete todos los campos')),
);
return;
}
final fechaCreado = DateTime.now().millisecondsSinceEpoch;
final categoria = {
"clave": clave,
"fechaCreado": fechaCreado,
"nombre": nombre,
};
print(categoria); // Imprime el mensaje en consola
// Aquí puedes agregar lógica adicional para guardar los datos en una base de datos o enviar a una API
// Volver a la pantalla anterior
Navigator.pop(context);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Agregar Categoría'),
),
body: Padding(
padding: const EdgeInsets.all(180.0),
child: Column(
children: <Widget>[
TextField(
controller: _claveController,
decoration: const InputDecoration(labelText: 'Clave'),
keyboardType: TextInputType.text,
),
const SizedBox(height:40),
TextField(
controller: _nombreController,
decoration: const InputDecoration(labelText: 'Nombre'),
keyboardType: TextInputType.text,
),
const SizedBox(height: 30),
ElevatedButton(
onPressed: _guardarCategoria,
child: const Text('GUARDAR'),
),
],
),
),
);
}
}
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:primer_practica/src/pages/category/lista_categorias.dart'; // Importa el widget de la lista de categorías import 'package:primer_practica/src/pages/category/lista_categorias.dart';
class HomePage extends StatelessWidget { class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key); const HomePage({Key? key}) : super(key: key);
...@@ -41,10 +41,10 @@ class HomePage extends StatelessWidget { ...@@ -41,10 +41,10 @@ class HomePage extends StatelessWidget {
], ],
), ),
), ),
body: ListaCategorias(), // Usa el widget de la lista de categorías en el body body: ListaCategorias(),
floatingActionButton: FloatingActionButton( floatingActionButton: FloatingActionButton(
onPressed: () { onPressed: () {
Navigator.pushNamed(context, 'login'); Navigator.pushNamed(context, 'formulario');
}, },
child: const Icon(Icons.add), child: const Icon(Icons.add),
tooltip: 'Agregar categoria', tooltip: 'Agregar categoria',
......
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