Co-authored-by: MENDOZA BALLARDO GAEL RICARDO <gael-meb123@users.noreply.github.com>
Co-authored-by: Azareth-Tr <Azareth-Tr@users.noreply.github.com> Co-authored-by: eddgranados12 <eddgranados12@users.noreply.github.com> implementacion de login, vistas, correcion de errores en vista registro, domicilios
This commit is contained in:
154
recolecta_app/lib/core/models/ui_models.dart
Normal file
154
recolecta_app/lib/core/models/ui_models.dart
Normal file
@@ -0,0 +1,154 @@
|
||||
// ── Usuario (presentación UI) ─────────────────────────────────────────────────
|
||||
class UIUserModel {
|
||||
final String id;
|
||||
final String nombre;
|
||||
final String apellido;
|
||||
final String email;
|
||||
final String telefono;
|
||||
final String role;
|
||||
|
||||
const UIUserModel({
|
||||
required this.id,
|
||||
required this.nombre,
|
||||
required this.apellido,
|
||||
required this.email,
|
||||
required this.telefono,
|
||||
this.role = 'citizen',
|
||||
});
|
||||
|
||||
String get nombreCompleto => '$nombre $apellido'.trim();
|
||||
String get iniciales {
|
||||
final n = nombre.isNotEmpty ? nombre[0] : '';
|
||||
final a = apellido.isNotEmpty ? apellido[0] : '';
|
||||
return '$n$a'.toUpperCase();
|
||||
}
|
||||
|
||||
bool get isAdmin => role == 'admin';
|
||||
}
|
||||
|
||||
// ── Casa / Domicilio ──────────────────────────────────────────────────────────
|
||||
class UIHouseModel {
|
||||
final String id;
|
||||
final String alias;
|
||||
final String calle;
|
||||
final String colonia;
|
||||
final String? routeId;
|
||||
final int radioAlertaMetros;
|
||||
final bool alertaCercana;
|
||||
final bool alertaMedia;
|
||||
final bool recordatorioDiario;
|
||||
final bool activa;
|
||||
|
||||
const UIHouseModel({
|
||||
required this.id,
|
||||
this.alias = 'Casa principal',
|
||||
required this.calle,
|
||||
required this.colonia,
|
||||
this.routeId,
|
||||
this.radioAlertaMetros = 200,
|
||||
this.alertaCercana = true,
|
||||
this.alertaMedia = false,
|
||||
this.recordatorioDiario = true,
|
||||
this.activa = true,
|
||||
});
|
||||
|
||||
String get direccionCompleta => '$calle, Col. $colonia';
|
||||
|
||||
UIHouseModel copyWith({
|
||||
String? alias,
|
||||
String? calle,
|
||||
String? colonia,
|
||||
String? routeId,
|
||||
int? radioAlertaMetros,
|
||||
bool? alertaCercana,
|
||||
bool? alertaMedia,
|
||||
bool? recordatorioDiario,
|
||||
bool? activa,
|
||||
}) {
|
||||
return UIHouseModel(
|
||||
id: id,
|
||||
alias: alias ?? this.alias,
|
||||
calle: calle ?? this.calle,
|
||||
colonia: colonia ?? this.colonia,
|
||||
routeId: routeId ?? this.routeId,
|
||||
radioAlertaMetros: radioAlertaMetros ?? this.radioAlertaMetros,
|
||||
alertaCercana: alertaCercana ?? this.alertaCercana,
|
||||
alertaMedia: alertaMedia ?? this.alertaMedia,
|
||||
recordatorioDiario: recordatorioDiario ?? this.recordatorioDiario,
|
||||
activa: activa ?? this.activa,
|
||||
);
|
||||
}
|
||||
|
||||
factory UIHouseModel.fromJson(Map<String, dynamic> json) {
|
||||
return UIHouseModel(
|
||||
id: json['id'] as String? ?? '',
|
||||
alias: json['label'] as String? ?? 'Casa principal',
|
||||
calle: json['calle'] as String? ?? '',
|
||||
colonia: json['colonia'] as String? ?? '',
|
||||
routeId: json['route_id'] as String?,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Alerta ───────────────────────────────────────────────────────────────────
|
||||
enum TipoAlerta { cercana, media, recordatorio }
|
||||
|
||||
class UIAlertaModel {
|
||||
final String id;
|
||||
final TipoAlerta tipo;
|
||||
final double distanciaMetros;
|
||||
final DateTime fecha;
|
||||
final String direccionCasa;
|
||||
final bool leida;
|
||||
|
||||
const UIAlertaModel({
|
||||
required this.id,
|
||||
required this.tipo,
|
||||
required this.distanciaMetros,
|
||||
required this.fecha,
|
||||
required this.direccionCasa,
|
||||
this.leida = false,
|
||||
});
|
||||
|
||||
String get distanciaTexto {
|
||||
if (distanciaMetros < 1000) {
|
||||
return '${distanciaMetros.toStringAsFixed(0)} m';
|
||||
}
|
||||
return '${(distanciaMetros / 1000).toStringAsFixed(1)} km';
|
||||
}
|
||||
|
||||
String get tiempoEstimadoTexto {
|
||||
final segundos = (distanciaMetros / (5000 / 3600)).round();
|
||||
if (segundos < 60) return 'Menos de 1 min';
|
||||
final minutos = (segundos / 60).ceil();
|
||||
return '~$minutos min';
|
||||
}
|
||||
|
||||
String get fechaFormateada {
|
||||
final ahora = DateTime.now();
|
||||
final hoy = DateTime(ahora.year, ahora.month, ahora.day);
|
||||
final fechaDia = DateTime(fecha.year, fecha.month, fecha.day);
|
||||
if (fechaDia == hoy) return 'Hoy, ${_formatHora(fecha)}';
|
||||
final ayer = hoy.subtract(const Duration(days: 1));
|
||||
if (fechaDia == ayer) return 'Ayer, ${_formatHora(fecha)}';
|
||||
const dias = ['Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb', 'Dom'];
|
||||
const meses = ['ene','feb','mar','abr','may','jun','jul','ago','sep','oct','nov','dic'];
|
||||
return '${dias[fecha.weekday - 1]} ${fecha.day} ${meses[fecha.month - 1]}, ${_formatHora(fecha)}';
|
||||
}
|
||||
|
||||
String get etiquetaFecha {
|
||||
final ahora = DateTime.now();
|
||||
final hoy = DateTime(ahora.year, ahora.month, ahora.day);
|
||||
final fechaDia = DateTime(fecha.year, fecha.month, fecha.day);
|
||||
if (fechaDia == hoy) return 'Hoy';
|
||||
const dias = ['Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb', 'Dom'];
|
||||
return dias[fecha.weekday - 1];
|
||||
}
|
||||
|
||||
String _formatHora(DateTime dt) {
|
||||
final h = dt.hour > 12 ? dt.hour - 12 : dt.hour == 0 ? 12 : dt.hour;
|
||||
final m = dt.minute.toString().padLeft(2, '0');
|
||||
final ampm = dt.hour >= 12 ? 'p.m.' : 'a.m.';
|
||||
return '$h:$m $ampm';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user