Commit bafadde7 by Nayeli Monserrat Velasco Lopez

Merge branch 'nayeli.velasco' into 'master'

Listado de categorias See merge request !6
parents 78e21345 02adba50
plugins { plugins {
id "com.android.application" id "com.android.application"
id "kotlin-android" id "kotlin-android"
......
const apiApp = 'https://basic2.visorus.com.mx';
\ No newline at end of file
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'config/routes.dart'; import 'config/rutas.dart';
void main() { void main() {
runApp(const MyApp()); runApp(const MyApp());
} }
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key); const MyApp({Key? key}) : super(key: key);
......
import 'dart:convert';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:miapp_flutter/src/models/CategoriaModel.dart';
import '../http_api/CategoryApi.dart';
class CategoryController {
final Connectivity _connectivity = Connectivity();
final CategoryApi _categoryApi = CategoryApi();
Future<Map<String, dynamic>> getCategories() async {
Map<String, dynamic> mapResp = {
'ok': false,
'message': 'No hay categorias',
'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 _categoryApi.getCategories();
if (respGet['statusCode'] == 200) {
try {
var decodeResp = json.decode(respGet['body']);
List<CategoriaModel> listCategories = CategoriaModel
.fromJsonArray(decodeResp['data']);
mapResp['ok'] = true;
mapResp['message'] =
"${listCategories.length} categorías encontradas";
mapResp['data'] = listCategories;
} 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;
}
}
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/foundation.dart';
import 'package:miapp_flutter/environments/archivo.dart';
class CategoryApi {
final String apiUrl = 'categoria';
// Método para obtener las categorías
Future<Map<String, dynamic>> getCategories() async {
String url = '${apiApp}/$apiUrl?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 'dart:convert';
class ArticleModel {
final int id;
final String clave;
final String nombre;
final int categoriaId;
final List<Price> precios;
final bool activo;
ArticleModel({
required this.id,
required this.clave,
required this.nombre,
required this.categoriaId,
required this.precios,
required this.activo,
});
factory ArticleModel.fromJson(Map<String, dynamic> json) {
var list = json['precios'] as List;
List<Price> preciosList = list.map((i) => Price.fromJson(i)).toList();
return ArticleModel(
id: json['id'],
clave: json['clave'],
nombre: json['nombre'],
categoriaId: json['categoria']['id'],
precios: preciosList,
activo: json['activo'],
);
}
static List<ArticleModel> fromJsonArray(List<dynamic> jsonArray) {
return jsonArray.map((json) => ArticleModel.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
// lib/src/models/category_model.dart
class CategoriaModel {
int id;
int? version;
String? key;
String? name;
int? createdDate;
CategoriaModel? parentCategory;
List<CategoriaModel>? subCategories;
bool? active;
CategoriaModel({
required this.id,
this.version,
this.key,
this.name,
this.createdDate,
this.parentCategory,
this.subCategories,
this.active,
});
// Método para crear una instancia de CategoryModel desde un JSON
factory CategoriaModel.fromJson(Map<String, dynamic> json) {
return CategoriaModel(
id: json['id'],
version: json['version'],
key: json['clave'],
name: json['nombre'],
createdDate: json['fechaCreado'],
parentCategory: json['categoria'] != null
? CategoriaModel.fromJson(json['categoria'])
: null,
subCategories: json['categorias'] != null
? CategoriaModel.fromJsonArray(json['categorias'])
: [],
active: json['activo'],
);
}
// Este metodo sirve para para convertir una instancia de CategoryModel a JSON
Map<String, dynamic> toJson() {
return {
"id": id,
"version": version,
"clave": key,
"nombre": name,
"fechaCreado": createdDate,
"categoria": parentCategory?.toJson(),
"categorias": subCategories != null
? CategoriaModel.toJsonArray(subCategories!)
: [],
"activo": active,
};
}
// Método para crear una lista de CategoryModel desde un JSON
static List<CategoriaModel> fromJsonArray(json) {
if (json == null) return [];
var list = json as List;
List<CategoriaModel> listResult =
list.map((data) => CategoriaModel.fromJson(data)).toList();
return listResult;
}
static toJsonArray(List<CategoriaModel> list) {
List<Map<String, dynamic>> listMap = [];
for (CategoriaModel item in list) {
listMap.add(item.toJson());
}
return listMap;
}
}
\ No newline at end of file
import 'package:flutter/material.dart';
import '../../controllers/CategoriaController.dart';
import '../../models/CategoriaModel.dart';
class CategoryListWidget extends StatefulWidget {
@override
_CategoryWidgetState createState() => _CategoryWidgetState();
}
class _CategoryWidgetState extends State<CategoryListWidget> {
final CategoryController _categoryCtrl = CategoryController(); //El categoryCtrl se usa para obtener las categorías
@override
Widget build(BuildContext context) {
return SafeArea(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: FutureBuilder<Map<String, dynamic>>( //El futureBuilder se utiliza para
// manejar operaciones asíncronas y donde map tiene las categorias
future: _categoryCtrl.getCategories(),
builder: (context, snapshot) {
if (snapshot.hasData) {
if (snapshot.data!['ok']) {
if (snapshot.data!['data'] != null && (snapshot.data!['data'] as List).isNotEmpty) {
List<CategoriaModel> categories = snapshot.data!['data'];
return ListView.builder(
itemBuilder: (BuildContext context, int index) {
final category = categories[index];
return Card(
child: ListTile(
title: Text(category.name ?? 'No Name'),
leading: const Icon(Icons.touch_app),
onTap: () {
// Navegar al listado de servicios
},
),
);
},
itemCount: categories.length,
);
} else {
return Center(child: Text("No se encontraron categorías"));
}
} else {
return Center(child: Text("Error: ${snapshot.data!['message']}"));
}
} else if (snapshot.hasError) {
return Center(child: Text("Error: ${snapshot.error.toString()}"));
} 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/specific_widgets/menu.dart' ;
import 'category/CategoryListWidget.dart';
void main() => runApp(const DrawerApp()); void main() => runApp(const DrawerApp());
...@@ -59,60 +62,19 @@ class _HomePageState extends State<HomePage> { ...@@ -59,60 +62,19 @@ class _HomePageState extends State<HomePage> {
], ],
), ),
), ),
drawer: Drawer( drawer: MenuWidget(),
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
const DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text(
'Menu App',
style: TextStyle(
color: Colors.white,
fontSize: 24,
),
),
),
ListTile(
leading: const Icon(Icons.message),
title: const Text('Mensajes'),
onTap: () {
setState(() {
selectedPage = 'Messages';
});
Navigator.pop(context); // Close the drawer
},
),
ListTile(
leading: const Icon(Icons.settings),
title: const Text('Configuraciones'),
onTap: () {
setState(() {
selectedPage = 'Settings';
});
Navigator.pop(context); // Close the drawer
},
),
],
),
),
body: TabBarView( body: TabBarView(
children: [ children: [
Column( Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
Expanded( Expanded(
child: Center( child: CategoryListWidget(),
),
), ),
Padding( Padding(
padding: const EdgeInsets.all(50.0), padding: const EdgeInsets.all(16.0),
child: ElevatedButton( child: ElevatedButton(
onPressed: _handleNewCategory, onPressed: _handleNewCategory,
child: const Text('Nueva categoria'), child: const Text('Nueva categoría'),
), ),
), ),
], ],
......
import 'package:flutter/material.dart';
// Widget para mostrar mensajes de error
Widget alertDanger(String message) {
return Container(
width: double.infinity,
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
const Icon(
Icons.error,
color: Colors.white,
),
const SizedBox(
width: 10.0,
),
Expanded(
child: Text(
message,
style: const TextStyle(color: Colors.red),
),
)
],
),
);
}
// Widget para mostrar mensajes de éxito
Widget alertSuccess(String message) {
return Container(
width: double.infinity,
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
const Icon(
Icons.check_circle_outline,
color: Colors.white,
),
const SizedBox(
width: 10.0,
),
Expanded(
child: Text(
message,
style: const TextStyle(color: Colors.lightGreen),
),
)
],
),
);
}
// Widget para mostrar mensajes de espera
Widget alertWait(String message) {
return Container(
width: double.infinity,
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
const Icon(
Icons.info,
color: Colors.white,
),
const SizedBox(
width: 10.0,
),
Expanded(
child: Text(
message,
style: const TextStyle(color: Colors.lightBlueAccent),
),
)
],
),
);
}
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class MenuWidget extends StatelessWidget {
const MenuWidget({super.key});
@override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
const DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text(
'Menu App',
style: TextStyle(
color: Colors.white,
fontSize: 24,
),
),
),
ListTile(
leading: const Icon(Icons.message),
title: const Text('Mensajes'),
onTap: () {
Navigator.pop(context); // Close the drawer
},
),
ListTile(
leading: const Icon(Icons.settings),
title: const Text('Configuraciones'),
onTap: () {
Navigator.pop(context); // Close the drawer
},
),
],
),
);
}
}
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
import FlutterMacOS import FlutterMacOS
import Foundation import Foundation
import connectivity_plus
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
} }
# Generated by pub # Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile # See https://dart.dev/tools/pub/glossary#lockfile
packages: packages:
args:
dependency: transitive
description:
name: args
sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a"
url: "https://pub.dev"
source: hosted
version: "2.5.0"
async: async:
dependency: transitive dependency: transitive
description: description:
...@@ -41,6 +49,22 @@ packages: ...@@ -41,6 +49,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.18.0" version: "1.18.0"
connectivity_plus:
dependency: "direct main"
description:
name: connectivity_plus
sha256: "3e7d1d9dbae40ae82cbe6c23c518f0c4ffe32764ee9749b9a99d32cbac8734f6"
url: "https://pub.dev"
source: hosted
version: "6.0.4"
connectivity_plus_platform_interface:
dependency: transitive
description:
name: connectivity_plus_platform_interface
sha256: "42657c1715d48b167930d5f34d00222ac100475f73d10162ddf43e714932f204"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
...@@ -49,6 +73,14 @@ packages: ...@@ -49,6 +73,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.8" version: "1.0.8"
dbus:
dependency: transitive
description:
name: dbus
sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac"
url: "https://pub.dev"
source: hosted
version: "0.7.10"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
...@@ -57,6 +89,14 @@ packages: ...@@ -57,6 +89,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.1" version: "1.3.1"
ffi:
dependency: transitive
description:
name: ffi
sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
...@@ -75,6 +115,27 @@ packages: ...@@ -75,6 +115,27 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
http:
dependency: "direct main"
description:
name: http
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
url: "https://pub.dev"
source: hosted
version: "1.2.2"
http_parser:
dependency: transitive
description:
name: http_parser
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
leak_tracker: leak_tracker:
dependency: transitive dependency: transitive
description: description:
...@@ -131,6 +192,14 @@ packages: ...@@ -131,6 +192,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.12.0" version: "1.12.0"
nm:
dependency: transitive
description:
name: nm
sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254"
url: "https://pub.dev"
source: hosted
version: "0.5.0"
path: path:
dependency: transitive dependency: transitive
description: description:
...@@ -139,6 +208,22 @@ packages: ...@@ -139,6 +208,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.9.0" version: "1.9.0"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
url: "https://pub.dev"
source: hosted
version: "6.0.2"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
url: "https://pub.dev"
source: hosted
version: "2.1.8"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
...@@ -192,6 +277,14 @@ packages: ...@@ -192,6 +277,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.0" version: "0.7.0"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
url: "https://pub.dev"
source: hosted
version: "1.3.2"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
...@@ -208,6 +301,22 @@ packages: ...@@ -208,6 +301,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "14.2.1" version: "14.2.1"
web:
dependency: transitive
description:
name: web
sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062
url: "https://pub.dev"
source: hosted
version: "1.0.0"
xml:
dependency: transitive
description:
name: xml
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
url: "https://pub.dev"
source: hosted
version: "6.5.0"
sdks: sdks:
dart: ">=3.4.4 <4.0.0" dart: ">=3.4.4 <4.0.0"
flutter: ">=3.18.0-18.0.pre.54" flutter: ">=3.18.0-18.0.pre.54"
...@@ -32,9 +32,13 @@ dependencies: ...@@ -32,9 +32,13 @@ dependencies:
sdk: flutter sdk: flutter
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.6 cupertino_icons: ^1.0.6
http: ^1.2.2
connectivity_plus: ^6.0.4
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
...@@ -93,3 +97,6 @@ flutter: ...@@ -93,3 +97,6 @@ flutter:
assets: assets:
- assets/img/ - assets/img/
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <connectivity_plus/connectivity_plus_windows_plugin.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
ConnectivityPlusWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin"));
} }
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
connectivity_plus
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST
......
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