Commit 50476693 by nayeli92433

Listado de articulos por categoria

parent 02adba50
...@@ -7,6 +7,6 @@ Map<String, WidgetBuilder> getApplicationRoutes() { ...@@ -7,6 +7,6 @@ Map<String, WidgetBuilder> getApplicationRoutes() {
return <String, WidgetBuilder>{ return <String, WidgetBuilder>{
'login': (context) => const LoginPage(), 'login': (context) => const LoginPage(),
'home': (context) => const HomePage(), 'home': (context) => const HomePage(),
'articles': (context) => const ArticlesPage(), 'articles': (context) => const ArticlePage(categoryId: 1),
}; };
} }
import 'dart:convert';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:miapp_flutter/src/models/ArticuloModel.dart';
import '../http_api/ArticleApi.dart';
class ArticuloController {
final Connectivity _connectivity = Connectivity();
final ArticleApi _articleApi = ArticleApi();
Future<Map<String, dynamic>> getArticles(int categoryId) async {
Map<String, dynamic> mapResp = {
'ok': false,
'message': 'No hay artículos',
'data': null
};
// Verificar la conectividad de la red
List<ConnectivityResult> connectivityResult = await _connectivity.checkConnectivity();
if (!connectivityResult.contains(ConnectivityResult.none)) {
if (connectivityResult.contains(ConnectivityResult.wifi) || connectivityResult.contains(ConnectivityResult.mobile)) {
try {
// Realizar la solicitud a la API
Map<String, dynamic> respGet = await _articleApi.getArticles(categoryId);
if (respGet['statusCode'] == 200) {
try {
var decodeResp = json.decode(respGet['body']);
List<ArticleModel> listArticles = ArticleModel.fromJsonArray(decodeResp['data']);
mapResp['ok'] = true;
mapResp['message'] = "${listArticles.length} artículos encontrados";
mapResp['data'] = listArticles;
} catch (e) {
mapResp['message'] = "Error en procesamiento de datos: $e";
}
} else {
mapResp['message'] = "Error en la respuesta de la API: ${respGet['body']}";
}
} catch (e) {
mapResp['message'] = "Error en la solicitud a la API: $e";
}
} else {
mapResp['message'] = 'No hay conexión a internet';
}
} else {
mapResp['message'] = 'No hay conexión a internet';
}
return mapResp;
}
}
\ No newline at end of file
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/foundation.dart';
import 'package:miapp_flutter/environments/archivo.dart';
class ArticleApi {
final String apiUrl = 'articulo';
// Método para obtener los artículos
Future<Map<String, dynamic>> getArticles(int categoryId) async {
String url = '${apiApp}/$apiUrl?categoria=$categoryId&offset=0&max=100';
if (kDebugMode) {
print('Url -> $url');
}
try {
final response = await http.get(Uri.parse(url));
// Verifica el estado de la respuesta
if (response.statusCode == 200) {
return {
'statusCode': response.statusCode,
'body': response.body,
};
} else {
return {
'statusCode': response.statusCode,
'body': 'Error: ${response.reasonPhrase}',
};
}
} catch (e) {
return {
'statusCode': 501,
'body': 'Error: $e',
};
}
}
}
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class ArticlesPage extends StatelessWidget { import '../controllers/ArticuloController.dart';
const ArticlesPage({Key? key}) : super(key: key); import '../models/ArticuloModel.dart';
class ArticlePage extends StatefulWidget {
final int categoryId;
const ArticlePage({Key? key, required this.categoryId}) : super(key: key);
@override
_ArticlePageState createState() => _ArticlePageState();
}
class _ArticlePageState extends State<ArticlePage> {
final ArticuloController _articleController = ArticuloController();
late Future<Map<String, dynamic>> _articlesFuture;
@override
void initState() {
super.initState();
_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: Center(
child: ElevatedButton( body: FutureBuilder<Map<String, dynamic>>(
onPressed: () { future: _articlesFuture,
Navigator.pushNamed(context, 'login'); builder: (context, snapshot) {
}, if (snapshot.hasData) {
child: const Text('Hola articles_page'), if (snapshot.data!['ok']) {
), if (snapshot.data!['data'] != null && (snapshot.data!['data'] as List).isNotEmpty) {
List<ArticleModel> articles = snapshot.data!['data'] as List<ArticleModel>;
return ListView.builder(
itemCount: articles.length,
itemBuilder: (context, index) {
final article = articles[index];
return Card(
child: ListTile(
title: Text(article.nombre),
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:miapp_flutter/src/pages/articles_page.dart';
import '../../controllers/CategoriaController.dart'; import '../../controllers/CategoriaController.dart';
import '../../models/CategoriaModel.dart'; import '../../models/CategoriaModel.dart';
...@@ -9,15 +9,14 @@ class CategoryListWidget extends StatefulWidget { ...@@ -9,15 +9,14 @@ class CategoryListWidget extends StatefulWidget {
} }
class _CategoryWidgetState extends State<CategoryListWidget> { class _CategoryWidgetState extends State<CategoryListWidget> {
final CategoryController _categoryCtrl = CategoryController(); //El categoryCtrl se usa para obtener las categorías final CategoryController _categoryCtrl = CategoryController();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SafeArea( return SafeArea(
child: Padding( child: Padding(
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
child: FutureBuilder<Map<String, dynamic>>( //El futureBuilder se utiliza para child: FutureBuilder<Map<String, dynamic>>(
// manejar operaciones asíncronas y donde map tiene las categorias
future: _categoryCtrl.getCategories(), future: _categoryCtrl.getCategories(),
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.hasData) { if (snapshot.hasData) {
...@@ -32,7 +31,12 @@ class _CategoryWidgetState extends State<CategoryListWidget> { ...@@ -32,7 +31,12 @@ class _CategoryWidgetState extends State<CategoryListWidget> {
title: Text(category.name ?? 'No Name'), title: Text(category.name ?? 'No Name'),
leading: const Icon(Icons.touch_app), leading: const Icon(Icons.touch_app),
onTap: () { onTap: () {
// Navegar al listado de servicios Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ArticlePage(categoryId: category.id),
),
);
}, },
), ),
); );
...@@ -57,4 +61,4 @@ class _CategoryWidgetState extends State<CategoryListWidget> { ...@@ -57,4 +61,4 @@ class _CategoryWidgetState extends State<CategoryListWidget> {
), ),
); );
} }
} }
\ No newline at end of file
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