Co-authored-by: MENDOZA BALLARDO GAEL RICARDO <gael-meb123@users.noreply.github.com>
Co-authored-by: Azareth-Tr <Azareth-Tr@users.noreply.github.com>

modificacion de las vistas principales para el usuario ciudadano, primer avance para el panel admin
This commit is contained in:
shinra32
2026-05-23 03:13:46 -06:00
parent 0279ad05f4
commit 45ffba69b2
33 changed files with 2810 additions and 296 deletions

View File

@@ -0,0 +1,96 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
// Modelo de mensaje simple
class ChatMessage {
final String role; // 'user', 'assistant', 'system'
final String content;
ChatMessage({required this.role, required this.content});
Map<String, dynamic> toJson() => {'role': role, 'content': content};
}
class AiChatNotifier extends StateNotifier<List<ChatMessage>> {
AiChatNotifier()
: super([
ChatMessage(
role: 'assistant',
content:
'¡Hola! Soy Eco 🍃, la mascota de Recolecta. '
'Estoy aquí para ayudarte a reciclar y separar tu basura correctamente. ¿Tienes alguna duda?',
),
]);
bool isLoading = false;
Future<void> sendMessage(String userText) async {
if (userText.trim().isEmpty) return;
// Añadir mensaje del usuario
final userMsg = ChatMessage(role: 'user', content: userText);
state = [...state, userMsg];
isLoading = true;
try {
final dio = Dio();
// Importante: En producción, la llamada a OpenAI debería hacerse idealmente
// desde tu backend FastAPI para no exponer la API_KEY en la app Flutter.
// Para el MVP/Hackathon, la leemos del entorno (.env o --dart-define)
final apiKey = dotenv.env['OPENAI_API_KEY'] ?? '';
// Contexto del sistema para que la IA actúe como la mascota
final systemPrompt = ChatMessage(
role: 'system',
content:
'Eres Eco, la mascota virtual de la app Recolecta en Celaya. '
'Tu misión es educar a los ciudadanos sobre cómo separar la basura en 4 categorías: '
'Orgánicos (verde), Reciclables (azul), Sanitarios (naranja) y Especiales (morado). '
'Responde siempre de forma muy amigable, entusiasta, usando emojis. '
'Sé muy conciso y breve (máximo 3 oraciones cortas). '
'Nunca reveles ubicaciones de camiones ni te salgas del tema del reciclaje y medio ambiente.',
);
final messagesForApi = [systemPrompt, ...state];
final response = await dio.post(
'https://api.openai.com/v1/chat/completions',
options: Options(
headers: {
'Authorization': 'Bearer $apiKey',
'Content-Type': 'application/json',
},
),
data: {
'model': 'gpt-3.5-turbo', // Rápido y económico para el hackathon
'messages': messagesForApi.map((m) => m.toJson()).toList(),
'temperature': 0.7,
'max_tokens': 150, // Limitar para que sea conciso
},
);
final botReply = response.data['choices'][0]['message']['content'];
state = [...state, ChatMessage(role: 'assistant', content: botReply)];
} catch (e) {
debugPrint('Error en OpenAI: $e');
state = [
...state,
ChatMessage(
role: 'assistant',
content:
'Uy, tuve un problemita técnico con mi cerebro de hojitas 🧠🍂. ¿Me repites tu pregunta?',
),
];
} finally {
isLoading = false;
}
}
}
final aiChatProvider = StateNotifierProvider<AiChatNotifier, List<ChatMessage>>(
(ref) {
return AiChatNotifier();
},
);