build + feat: imlementacion de estrucutras de interfaz grafica, construccion del proyecto. Pendiente de arreglar: errores en interfaces

This commit is contained in:
25030248hasel
2026-05-23 02:50:58 -06:00
commit 536f0a1914
147 changed files with 7387 additions and 0 deletions

View File

@@ -0,0 +1,99 @@
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import '../../domain/entities/auth_user.dart';
import '../../domain/repositories/auth_repository.dart';
import '../models/auth_user_model.dart';
/// Implementación concreta del repositorio de autenticación.
///
/// FASE MVP: Simula un servidor de autenticación localmente.
/// El token JWT generado tiene estructura real pero firma simulada.
///
/// PRODUCCIÓN (futura): Reemplazar [_simulateNetworkCall] con llamada HTTP
/// real al endpoint POST /auth/login usando Dio o http package.
class AuthRepositoryImpl implements AuthRepository {
static const String _sessionKey = 'waste_notify_session';
final SharedPreferences _prefs;
AuthRepositoryImpl(this._prefs);
@override
Future<AuthUser> login({
required String identifier,
required String password,
}) async {
// Simula latencia de red para UX realista
await _simulateNetworkCall();
// FASE MVP: Credenciales hardcoded para demostración
// PRODUCCIÓN: POST /api/v1/auth/login con body {identifier, password}
final validCredentials = {
'ciudadano@ejemplo.com': ('password123', 'citizen'),
'operador@ejemplo.com': ('operador456', 'operator'),
'5551234567': ('pass1234', 'citizen'),
};
final entry = validCredentials[identifier];
if (entry == null || entry.$1 != password) {
throw AuthException(
code: 'INVALID_CREDENTIALS',
message: 'Correo/teléfono o contraseña incorrectos.',
);
}
final user = AuthUserModel.simulatedJwt(
email: identifier,
role: entry.$2,
);
// Persiste sesión localmente (token cifrado en producción con flutter_secure_storage)
await _saveSession(user);
return user;
}
@override
Future<void> logout() async {
await _prefs.remove(_sessionKey);
}
@override
Future<AuthUser?> getStoredSession() async {
final raw = _prefs.getString(_sessionKey);
if (raw == null) return null;
try {
final json = jsonDecode(raw) as Map<String, dynamic>;
final user = AuthUserModel.fromJson(json);
if (user.isExpired) {
await _prefs.remove(_sessionKey);
return null;
}
return user;
} catch (_) {
await _prefs.remove(_sessionKey);
return null;
}
}
Future<void> _saveSession(AuthUserModel user) async {
await _prefs.setString(_sessionKey, jsonEncode(user.toJson()));
}
Future<void> _simulateNetworkCall() async {
await Future.delayed(const Duration(milliseconds: 1200));
}
}
/// Excepción tipada para errores de autenticación.
class AuthException implements Exception {
final String code;
final String message;
const AuthException({required this.code, required this.message});
@override
String toString() => 'AuthException[$code]: $message';
}