From b6c4c5ed42a9a512608f31c255a092d5cdc47b6c Mon Sep 17 00:00:00 2001 From: hack_23031391_8ff9d8 <23031391@itcelaya.edu.mx> Date: Sat, 23 May 2026 02:51:55 +0000 Subject: [PATCH] =?UTF-8?q?A=C3=B1adir=2002-frontend.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 02-frontend.md.-.md | 442 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 442 insertions(+) create mode 100644 02-frontend.md.-.md diff --git a/02-frontend.md.-.md b/02-frontend.md.-.md new file mode 100644 index 0000000..c096b57 --- /dev/null +++ b/02-frontend.md.-.md @@ -0,0 +1,442 @@ +# Configurar Flutter (Módulos C + D) + +Guía paso a paso para integrar los módulos y correr la app. + +--- + +## 1. Clonar el repo o descargar módulos + +### Si ya está en el repo: +```bash +cd hackathon-acapulquitos-boys +git pull origin dev +cd basura_app +``` + +### Si Persona D entrega su módulo por separado: +```bash +# Descomprimir ZIP del módulo D +unzip persona_d_modulo.zip + +# Copiar archivos al proyecto principal +cp -r persona_d/lib/core basura_app/lib/ +cp -r persona_d/lib/features/recycling_guide basura_app/lib/features/ +cp persona_d/assets/recycling_guide.json basura_app/assets/ +``` + +--- + +## 2. Configurar FVM (recomendado) + +```bash +cd basura_app + +# Instalar la versión acordada por el equipo +fvm install 3.44.0 # o 3.22.0 si bajaron versión +fvm use 3.44.0 + +# Verificar +fvm flutter --version +``` + +Esto crea `.fvm/fvm_config.json` — debe commitearse al repo. + +--- + +## 3. Actualizar `pubspec.yaml` + +Abre `basura_app/pubspec.yaml` y verifica: + +```yaml +name: basura_app +description: App de notificación de recolección de residuos +publish_to: 'none' +version: 1.0.0+1 + +environment: + sdk: '>=3.8.0 <4.0.0' # Dart 3.8 (Flutter 3.44) + flutter: '>=3.44.0' # o '>=3.22.0' si bajaron + +dependencies: + flutter: + sdk: flutter + + # State management + flutter_riverpod: ^2.6.1 + + # HTTP + dio: ^5.4.0 + + # WebSocket + web_socket_channel: ^2.4.0 + + # Routing (Persona C decide cuál usar) + go_router: ^13.2.0 # Recomendado + # o usa Navigator tradicional + + # Utils + intl: ^0.19.0 # Formateo de fechas + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^4.0.0 + +flutter: + uses-material-design: true + assets: + - assets/recycling_guide.json # ← JSON del módulo D +``` + +--- + +## 4. Instalar dependencias + +```bash +fvm flutter pub get +``` + +Deberías ver: +``` +Running "flutter pub get" in basura_app... +Resolving dependencies... +Got dependencies! +``` + +--- + +## 5. Verificar la estructura de carpetas + +```bash +tree -L 4 lib/ +``` + +Debe verse algo así: +``` +lib/ +├── core/ +│ └── theme/ +│ └── app_theme.dart # Tema compartido (Persona D) +│ +├── features/ +│ ├── auth/ # Login (Persona C) +│ │ └── presentation/ +│ │ └── screens/ +│ │ └── login_screen.dart +│ │ +│ ├── eta/ # Home + WebSocket (Persona C) +│ │ ├── domain/ +│ │ ├── data/ +│ │ └── presentation/ +│ │ ├── screens/ +│ │ │ └── eta_home_screen.dart +│ │ └── providers/ +│ │ ├── eta_provider.dart +│ │ └── ws_provider.dart +│ │ +│ └── recycling_guide/ # Guía offline (Persona D) +│ ├── domain/ +│ ├── data/ +│ └── presentation/ +│ ├── screens/ +│ │ ├── recycling_guide_screen.dart +│ │ └── category_detail_screen.dart +│ └── providers/ +│ └── recycling_provider.dart +│ +└── main.dart +``` + +--- + +## 6. Configurar `main.dart` + +```dart +// lib/main.dart +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:go_router/go_router.dart'; + +import 'core/theme/app_theme.dart'; +import 'features/eta/presentation/screens/eta_home_screen.dart'; +import 'features/recycling_guide/presentation/screens/recycling_guide_screen.dart'; + +void main() { + runApp(const ProviderScope(child: MyApp())); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp.router( + title: 'Basura App', + theme: AppTheme.lightTheme, // ← Tema de Persona D + routerConfig: _router, + debugShowCheckedModeBanner: false, + ); + } +} + +// Router (Persona C configura las rutas finales) +final _router = GoRouter( + routes: [ + GoRoute( + path: '/', + builder: (_, __) => const ETAHomeScreen(), // Persona C + ), + GoRoute( + path: '/guia', + builder: (_, __) => const RecyclingGuideScreen(), // Persona D + ), + ], +); +``` + +--- + +## 7. Actualizar la URL del backend + +**Importante:** Por defecto, el backend corre en `localhost:8000`, pero: + +- **Emulador Android:** usa `10.0.2.2:8000` +- **Emulador iOS:** usa `localhost:8000` +- **Dispositivo físico:** usa la IP de tu PC en la red local (ej: `192.168.1.10:8000`) + +### Crear un provider de configuración + +```dart +// lib/core/config/api_config.dart +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:dio/dio.dart'; + +// Cambia esto según tu entorno +const _baseUrl = 'http://10.0.2.2:8000'; // Android emulator +// const _baseUrl = 'http://localhost:8000'; // iOS simulator +// const _baseUrl = 'http://192.168.1.10:8000'; // Dispositivo físico + +final apiBaseUrlProvider = Provider((ref) => _baseUrl); + +final dioProvider = Provider((ref) { + return Dio(BaseOptions( + baseUrl: ref.watch(apiBaseUrlProvider), + connectTimeout: const Duration(seconds: 5), + receiveTimeout: const Duration(seconds: 10), + )); +}); +``` + +Persona C importa este provider en sus datasources. + +--- + +## 8. Correr la app + +### En un emulador + +```bash +# Listar dispositivos disponibles +fvm flutter devices + +# Correr en el primer dispositivo +fvm flutter run + +# O seleccionar uno específico +fvm flutter run -d +``` + +### En dispositivo físico + +1. Habilita **USB Debugging** en el teléfono +2. Conecta el cable +3. `fvm flutter run` + +--- + +## 9. Verificar que funciona + +### Módulo D (offline — funciona sin backend) + +1. Navega a `/guia` (botón en home o URL directa) +2. Deberías ver 4 categorías: Orgánicos, Reciclables, Sanitarios, Especiales +3. Prueba el buscador: escribe "pila" → debe mostrar "Especiales" +4. Toca una categoría → pantalla de detalle con items ✓ y ✗ + +### Módulo C (requiere backend corriendo) + +1. **Arranca el backend primero:** + ```bash + cd basura_backend + uvicorn app.main:app --reload + ``` + +2. **Arranca el simulador:** + ```bash + curl -X POST http://localhost:8000/admin/route/RUTA-01/start + ``` + +3. En Flutter, deberías ver: + - Ventana horaria: "7:20 pm – 7:35 pm" + - Mensaje: "El camión está en camino..." + - Badge de estado: "EN_RUTA" + +4. Cada ~10 segundos, el ETA se actualiza automáticamente vía WebSocket + +--- + +## 10. Hot Reload y Hot Restart + +### Hot Reload (r) +Actualiza cambios en la UI sin perder el estado. +```bash +# En la terminal donde corre flutter run, presiona: +r +``` + +### Hot Restart (R) +Reinicia la app desde cero. +```bash +R +``` + +--- + +## 11. Debugging + +### Ver logs en consola +```bash +fvm flutter run --verbose +``` + +### Flutter DevTools +```bash +fvm flutter pub global activate devtools +fvm flutter pub global run devtools +``` + +Abre el link que aparece en el navegador. + +--- + +## 12. Build para producción + +### Android APK +```bash +fvm flutter build apk --release +``` + +El APK estará en: `build/app/outputs/flutter-apk/app-release.apk` + +### iOS (requiere macOS + Xcode) +```bash +fvm flutter build ios --release +``` + +--- + +## 13. Troubleshooting + +### "Waiting for another flutter command to release the startup lock" +```bash +# Borrar el lock file +rm ~/.dart_tool/dart_tool.lock +``` + +### "Gradle build failed" +Java incorrecto o problema de versión. + +**Solución:** +```bash +# Verificar Java 17 +java -version + +# Limpiar build +cd android +./gradlew clean +cd .. +fvm flutter clean +fvm flutter pub get +``` + +### "Could not connect to WebSocket" +Backend no está corriendo o URL incorrecta. + +**Solución:** +```bash +# Verifica que el backend esté up +curl http://localhost:8000/health + +# Ajusta la URL en api_config.dart según tu entorno +``` + +### "asset not found: assets/recycling_guide.json" +El asset no está declarado en `pubspec.yaml`. + +**Solución:** +```yaml +flutter: + assets: + - assets/recycling_guide.json +``` + +Luego: +```bash +fvm flutter clean +fvm flutter pub get +``` + +### "Unsupported class file major version 65" +Estás usando Java 21 en lugar de Java 17. + +**Solución:** +```bash +# Cambiar a Java 17 (ver setup/00-requisitos.md) +sudo update-alternatives --config java +``` + +--- + +## 14. Integración final con Persona A + +Cuando Persona A tenga el módulo de Auth listo: + +1. **Agregar el JWT token al Dio:** + ```dart + final dioProvider = Provider((ref) { + final dio = Dio(BaseOptions(baseUrl: _baseUrl)); + + // Interceptor para agregar token + dio.interceptors.add(InterceptorsWrapper( + onRequest: (options, handler) { + final token = ref.read(authTokenProvider); + if (token != null) { + options.headers['Authorization'] = 'Bearer $token'; + } + handler.next(options); + }, + )); + + return dio; + }); + ``` + +2. **Proteger las rutas:** + ```dart + GoRoute( + path: '/', + redirect: (context, state) { + final isLoggedIn = ref.read(authProvider).isAuthenticated; + return isLoggedIn ? null : '/login'; + }, + builder: (_, __) => const ETAHomeScreen(), + ), + ``` + +--- + +## Siguiente paso + +- [Variables de entorno](03-env.md) — configurar `.env` para dev/prod +- [Contratos de API](../api/01-endpoints.md) — consumir endpoints REST +- [WebSocket protocol](../api/02-websocket.md) — conectar en tiempo real