Documento histórico
Este documento se conserva solo para trazabilidad. Consulte el índice maestro para la fuente vigente.
Pantallas implementadas¶
Documento histórico — detalle de pantallas
Este archivo es el detalle histórico de cada pantalla de la APK. Para conocer el estado actual vigente y el resumen consolidado, consultar estado-actual.md.
Detalle pantalla por pantalla de cada Screen que existe en la APK: qué muestra, qué hace, qué le falta, qué datos usa.
Índice de pantallas¶
| # | Pantalla | Archivo | Ubicación | Estado |
|---|---|---|---|---|
| 1 | Welcome | WelcomeScreen.kt |
ui/screens/auth/ |
⚠️ Drawable falta |
| 2 | Login | LoginScreen.kt |
ui/screens/auth/ |
✅ |
| 3 | Register | RegisterScreen.kt |
ui/screens/auth/ |
⚠️ Handler vacío |
| 4 | ForgotPassword | ForgotPasswordScreen.kt |
ui/screens/auth/ |
✅ |
| 5 | VerificationCode | VerificationCodeScreen.kt |
ui/screens/auth/ |
✅ |
| 6 | Success | SuccessScreen.kt |
ui/screens/auth/ |
⚠️ Drawable falta |
| 7 | Dashboard (Inicio) | DashboardScreen.kt |
ui/screens/main/ |
⚠️ Datos hardcoded |
| 8 | Reportes | ReportesScreen.kt |
ui/screens/main/ |
✅ |
| 9 | ReporteForm (full) | FormularioReporteScreen.kt |
ui/screens/reporte/ |
✅ |
| 10 | ReporteDetalle | ReporteDetalleScreen.kt |
ui/screens/reporte/ |
⚠️ onClicks vacíos |
| 11 | Paquetes | PaquetesScreen.kt |
ui/screens/main/ |
✅ |
| 12 | Guía | GuiaScreen.kt |
ui/screens/main/ |
⚠️ onClicks vacíos |
| 13 | Perfil | PerfilScreen.kt |
ui/screens/main/ |
⚠️ onClicks vacíos, datos hardcoded |
| 14 | Notifications | NotificationsScreen.kt |
ui/screens/main/ |
❌ Solo empty state |
| ❌ | ReporteScreen (huérfana) | ReporteScreen.kt |
ui/screens/main/ |
🔒 A eliminar |
1. Welcome (Bienvenida)¶
Archivo: app/src/main/java/com/example/islabox/ui/screens/auth/WelcomeScreen.kt
Lo que muestra¶
| Elemento | Detalle |
|---|---|
| Fondo | DotGridBackground con animación de entrada |
| Logo (isotipo) | IslaImages.Logo (palmera en círculo) — CRASH porque el drawable no existe |
| Título | "Bienvenido" (displayLarge Primary) |
| Subtítulo | "Tu puente logístico hacia Cuba." (bodyLarge onSurfaceVariant) |
| Botón primario | "Iniciar Sesión" → onLoginClick → Screen.Login |
| Botón outlined | "Crear Cuenta" → onRegisterClick → Screen.Register |
| Copyright | "© 2026 ISLABOX." |
Layout¶
- Surface con
MaterialTheme.colorScheme.background - Box con
DotGridBackgroundde fondo - Column con
systemBarsPadding()+padding(horizontal = spacing.md) - 2 sub-Column con
weight(1f)cada una: - Superior: logo + spacer
- Inferior: textos + botones + copyright
Arrangement.BottomyArrangement.Toppara centrar el logo
Lo que hace¶
- Navega a
LoginoRegistersegún el botón.
Lo que falta¶
- 🔴 Drawable
ic_islabox_logono existe → CRASH - 💡 Alternativa: usar
IslaTextLogomientras se crea el drawable.
2. Login¶
Archivo: app/src/main/java/com/example/islabox/ui/screens/auth/LoginScreen.kt
Lo que muestra¶
| Elemento | Detalle |
|---|---|
| Fondo | DotGridBackground |
| Top bar | IslaTopBar con botón back (vuelve a Welcome) |
| Título | "Iniciar Sesión" (displaySmall Primary) |
| Subtítulo | "Accede a tu panel logístico." |
| Campo email | IslaTextField con ícono Email, placeholder "ejemplo@correo.com" |
| Campo contraseña | IslaTextField con ícono Lock, placeholder "••••••••", PasswordVisualTransformation con toggle |
| Link "¿Olvidaste tu contraseña?" | → Screen.ForgotPassword |
| Botón "Entrar" | → navega a Main (sin validar) |
| Link "Regístrate" | → Screen.Register |
Lo que hace¶
- Click en "Entrar" →
navController.navigate(Screen.Main) { popUpTo(Screen.Welcome) { inclusive = true } }. - Click en "Regístrate" → navega a
Screen.Register. - Click en "¿Olvidaste tu contraseña?" →
Screen.ForgotPassword.
Lo que falta¶
- ❌ Validación de email (formato).
- ❌ Validación de contraseña (longitud mínima, requisitos).
- ❌ Rate limiting (la doc dice 5 intentos/minuto).
- ❌ Mostrar error si credenciales inválidas.
3. Register¶
Archivo: app/src/main/java/com/example/islabox/ui/screens/auth/RegisterScreen.kt
Lo que muestra¶
| Elemento | Detalle |
|---|---|
| Fondo | DotGridBackground |
| Top bar | IslaTopBar con back a Welcome |
| Título | "Crear Cuenta" |
| Subtítulo | "Comienza a enviar paquetes hoy mismo." |
| Campo nombre | IslaTextField con ícono Person, placeholder "Juan" |
| Campo apellidos | IslaTextField, placeholder "Pérez" |
| Campo email | IslaTextField con ícono Email |
| Campo teléfono | IslaPhoneField con country code +1 |
| Campo contraseña | con toggle visibilidad |
| Campo repetir contraseña | con validación inline de match |
| Botón "Registrarse" | deshabilitado si los campos requeridos están vacíos o las contraseñas no coinciden |
| Link "¿Ya tienes cuenta? Inicia Sesión" | → Screen.Login |
Validaciones inline¶
val passwordsMatch = password.isNotEmpty() && confirmPassword.isNotEmpty() && password == confirmPassword
val passwordError = if (confirmPassword.isNotEmpty() && !passwordsMatch) "Las contraseñas no coinciden" else null
val isFormValid = firstName.isNotEmpty() && lastName.isNotEmpty() && email.isNotEmpty() && phone.isNotEmpty() && passwordsMatch
Lo que hace¶
- Click en "Registrarse" →
onRegisterClick(name, email, phone, password)→ handler vacío (TODO). - Click en "Inicia Sesión" →
Screen.Login.
Lo que falta¶
- 🔴 Handler de
onRegisterClick(T-201). - ❌ Validación de formato email.
- ❌ Requisitos mínimos de contraseña (8+ chars, mayúscula, número).
- ❌ Checkbox de términos y condiciones.
- ❌ Verificación de correo por enlace.
- ❌ Verificación de teléfono por OTP (en el registro, no en ForgotPassword).
4. ForgotPassword¶
Archivo: app/src/main/java/com/example/islabox/ui/screens/auth/ForgotPasswordScreen.kt
Lo que muestra¶
| Elemento | Detalle |
|---|---|
| Fondo | DotGridBackground |
| Top bar | IslaTopBar con back a Login |
| Título | "Recuperar Acceso" |
| Subtítulo | "Enviaremos un código de verificación a tu correo electrónico." |
| Campo email | IslaTextField con ícono Email |
| Botón "Enviar Código" | habilitado si email no vacío |
| Link "Volver al Inicio de Sesión" | popBackStack |
Lo que hace¶
- Click en "Enviar Código" →
onSendCodeClick(email)→Screen.VerificationCode(email). - No envía código real (no hay backend).
Lo que falta¶
- ❌ Validación de email.
- ❌ Mostrar mensaje "Si el email existe, te enviamos un código".
5. VerificationCode (OTP)¶
Archivo: app/src/main/java/com/example/islabox/ui/screens/auth/VerificationCodeScreen.kt
Lo que muestra¶
| Elemento | Detalle |
|---|---|
| Fondo | DotGridBackground |
| Top bar | IslaTopBar con back a ForgotPassword |
| Título | "Verificar Código" |
| Subtítulo | "Ingresa el código de 6 dígitos enviado a {email}" |
| OTP Input | 6 boxes de 45×55dp con BasicTextField |
| "¿No recibiste el código?" | texto + botón reenviar |
| Botón "Reenviar código" | deshabilitado hasta que pasen 45s |
| Botón "Verificar código" | habilitado cuando se ingresan 6 dígitos |
OTP Input — detalle técnico¶
@Composable
fun OtpInputField(otpText, onOtpTextChange, otpCount = 6)
BasicTextFieldtransparente encima de 6 boxes decorativas.- Cada box: 45×55dp, border 2dp siFocused sino 1dp, navy si focused, gris si no.
- Solo acepta números (
KeyboardType.Number). - Cursor simulado con
Box(width=1.dp, height=24.dp)cuando el box está focused.
Timer de reenvío¶
var timerSeconds by remember { mutableIntStateOf(45) }
LaunchedEffect(Unit) {
while(timerSeconds > 0) { delay(1000); timerSeconds-- }
}
Si se navega fuera y vuelve, el timer se reinicia.
Lo que hace¶
- Click en "Verificar código" →
onVerifyClick(code)→Screen.Success(sin validar). - Click en "Reenviar código" →
onResendClick()(handler vacío).
Lo que falta¶
- ❌ Validación del código (en backend).
- ❌ Limpiar código si es incorrecto.
- ❌ Bloquear después de N intentos.
- ❌ Animación al enviar.
6. Success¶
Archivo: app/src/main/java/com/example/islabox/ui/screens/auth/SuccessScreen.kt
Lo que muestra¶
| Elemento | Detalle |
|---|---|
| Fondo | DotGridBackground |
| Imagen de éxito | IslaImages.Success — CRASH porque el drawable no existe |
| Título | configurable (default "¡Éxito!") |
| Subtítulo | configurable |
| Botón | configurable (default "Volver al Inicio") |
Configuración por uso¶
| Flujo | Título | Subtítulo | Botón | Destino |
|---|---|---|---|---|
| ForgotPassword → OTP → Success | "¡Contraseña Restaurada!" | "Tu contraseña ha sido actualizada con éxito..." | "Ir al Login" | Screen.Login |
Lo que falta¶
- 🔴 Drawable
ic_islabox_successno existe → CRASH.
7. Dashboard (Inicio)¶
Archivo: app/src/main/java/com/example/islabox/ui/screens/main/DashboardScreen.kt
Lo que muestra¶
| Sección | Componente | Detalle |
|---|---|---|
| Saludo | GreetingSection |
"Bienvenido, Kleudy Victor" |
| Resumen de paquetes | PackageSummarySection |
3 stat cards: En Tránsito (2), En Almacén (3), Entregados (12) |
| Dirección del casillero | LockerAddressSection |
Selector Amazon/Shein/Temu + dirección copiable |
| Banner "¿Compraste algo nuevo?" | ReportActionBanner |
→ navega a Screen.Dashboard.Reportes |
Datos hardcoded¶
GreetingSection(userName = "Kleudy Victor")
PackageSummarySection(
lockerId = "CP-001042-7", // ⚠️ debería ser CP-001042-8
summary = PackageSummary(inTransit = 2, inWarehouse = 3, delivered = 12)
)
LockerAddressSection(
firstName = "Kleudy Victor",
lastName = "Torno Peña",
lockerId = "CP-001042-7", // ⚠️
addressLine1 = "1940 NW 70th Ave",
addressLine2 = "ISLABOX",
city = "Miami",
state = "Florida",
zipCode = "33126",
phone = "+1 (786) 651-0451",
onCopyLine = { text -> clipboardManager.setText(AnnotatedString(text)) }
)
Lo que hace¶
- Click en el banner →
navController.navigate(Screen.Dashboard.Reportes). - Click en "copy" de cada línea → copia al portapapeles.
- Click en la campana (top bar) →
Screen.Notifications.
Lo que falta¶
- 🔴
CP-001042-7→CP-001042-8. - ❌ Datos del usuario (no hardcoded).
- ❌ 4ta sección "Compras en camino al almacén".
- ❌ Banner de KYC.
- ❌ Sección "Requiere tu atención".
8. Reportes (Mis reportes)¶
Archivo: app/src/main/java/com/example/islabox/ui/screens/main/ReportesScreen.kt
Lo que muestra¶
| Elemento | Detalle |
|---|---|
| Título | "Mis reportes" |
| Subtítulo | "Lista de compras reportadas que aún no han llegado al almacén" |
| Lista de prealertas | 4 ejemplos hardcoded |
| Empty state | "No tienes reportes pendientes" |
| FAB | "Nuevo Reporte" → Screen.Dashboard.ReporteForm |
Datos hardcoded¶
val reportes = listOf(
Reporte(tienda = "Amazon", numeroOrden = "112-44521-09", numeroTracking = "TBA3102294120",
fechaCompra = "12/02/2024", estado = "Esperando llegada al almacén"),
Reporte(tienda = "Shein", numeroOrden = "SH-99210-XX", numeroTracking = "",
fechaCompra = "14/02/2024", estado = "Esperando tracking"),
Reporte(tienda = "Temu", numeroOrden = "TM-8821-44", numeroTracking = "940010002234",
fechaCompra = "15/02/2024", estado = "Tracking recibido"),
Reporte(tienda = "eBay", numeroOrden = "EB-12345", numeroTracking = "USP123456789",
fechaCompra = "10/02/2024", estado = "Requiere corrección")
)
Cada card de reporte¶
- Ícono de paquete 72dp
- Tienda (uppercase) + badge con estado
- "Tracking: {tracking}" o "Sin tracking aún"
- 2 columnas: ORDEN y FECHA COMPRA
Lo que hace¶
- Click en una card →
onReporteClick(reporte)→Screen.ReporteDetalle(reporte)(raíz). - Click en FAB →
onNuevoReporteClick()→Screen.Dashboard.ReporteForm.
Lo que falta¶
- ❌ Filtros por estado.
- ❌ Datos del
FakeDataSource. - ❌ Click en tracking abre detalle del transportista.
9. ReporteForm (Formulario de reporte, full screen)¶
Archivo: app/src/main/java/com/example/islabox/ui/screens/reporte/FormularioReporteScreen.kt
Lo que muestra¶
| Elemento | Detalle |
|---|---|
| Top bar | "Nuevo Reporte" con back popBackStack |
| Subtítulo | "Completa los datos de tu compra" |
| Formulario | ReporteForm con 3 secciones (obligatoria, logística, opcional) |
| Captura de confirmación | CaptureUploadSection |
| Remitente | RemitenteSelector (asume "Kleudy Victor") |
| Destinatario | DestinatarioSelector con estado vacío |
| Botón "Enviar Reporte" | habilitado si todo está lleno |
14 campos del formulario¶
| Sección | Campo | Requerido |
|---|---|---|
| Obligatoria | Tienda | ✅ |
| Obligatoria | Nº de Orden | ✅ |
| Obligatoria | Fecha Compra | ✅ |
| Obligatoria | Tracking | ✅ (en el form, pero la doc dice opcional) |
| Obligatoria | Categoría (dropdown) | ✅ |
| Obligatoria | Descripción | ✅ |
| Obligatoria | Cantidad | ✅ |
| Obligatoria | Valor Pagado (USD) | ✅ |
| Logística | ¿Desea consolidar? (Sí/No) | ✅ |
| Opcional | Enlace del Producto (URL) | ❌ |
| Opcional | Instrucciones Especiales | ❌ |
| Opcional | Inspección Visual (checkbox) | ❌ |
| Opcional | Prueba Funcional (checkbox) | ❌ |
| Opcional | Reempaque (checkbox) | ❌ |
Estado del form (sin ViewModel)¶
var tienda by remember { mutableStateOf("") }
var orden by remember { mutableStateOf("") }
var tracking by remember { mutableStateOf("") }
var fecha by remember { mutableStateOf("") }
var categoria by remember { mutableStateOf("") }
var descripcion by remember { mutableStateOf("") }
var cantidad by remember { mutableStateOf("1") }
var valor by remember { mutableStateOf("") }
var enlace by remember { mutableStateOf("") }
var instrucciones by remember { mutableStateOf("") }
var deseaConsolidar by remember { mutableStateOf<Boolean?>(null) }
var serviciosSeleccionados by remember { mutableStateOf(listOf<String>()) }
var selectedDestinatario by remember { mutableStateOf<String?>(null) }
var hasCapture by remember { mutableStateOf(false) }
Lo que hace¶
- Click en "Enviar Reporte" →
navController.popBackStack()(no envía nada, solo cierra).
Lo que falta¶
- ❌ Validación inline por campo.
- ❌ ViewModel / estado persistente (al rotar la pantalla se pierde todo).
- ❌ Selector de destinatario real (abre lista).
- ❌ Selector de remitente real (asume único).
- ❌ Cámara/galería para captura.
- ❌ Date picker para fecha.
- ❌ Validación de tracking con regex.
10. ReporteDetalle (raíz)¶
Archivo: app/src/main/java/com/example/islabox/ui/screens/reporte/ReporteDetalleScreen.kt
Lo que muestra¶
9 secciones scrolleables:
| # | Sección | Componente |
|---|---|---|
| 1 | Header con tienda y categoría | Row custom |
| 2 | Card de tracking y orden | IslaCard con DetalleItem |
| 3 | Información en almacén | IslaCard con DetalleMini (fecha, embalaje, peso, dimensiones) |
| 4 | Timeline de estados | PackageTimeline con default si vacío |
| 5 | Almacenaje | StorageInfoCard |
| 6 | Fotos del paquete | 3 placeholders PhotoLibrary |
| 7 | Detalles de compra | IslaCard (fecha, valor, descripción, cantidad) |
| 8 | Información de entrega | IslaCard (remitente, destinatario, consolidar) |
| 9 | Instrucciones especiales | Card destacado (si existe) |
| 10 | Acciones disponibles | ActionButtonsGroup según reporte.estado |
Acciones por estado¶
val hasActions = when (reporte.estado) {
"En almacén", "En servicio adicional", "Listo para consolidar",
"Consolidado", "Incidencia" -> true
else -> false
}
when (reporte.estado) {
"En almacén" -> listOf("Solicitar inspección", "Solicitar reempaque",
"Solicitar devolución", "Agregar a consolidación",
"Enviar solo")
"En servicio adicional" -> listOf("Ver estado del servicio", "Esperar resultado")
"Listo para consolidar" -> listOf("Agregar a consolidación")
"Consolidado" -> listOf("Ver consolidación")
"Incidencia" -> listOf("Ver motivo", "Resolver problema")
}
Lo que hace¶
- Recibe el
Reportepor argumento de navegación (objeto completo,CustomNavTypes.ReporteNavType). - Top bar con botón back popBackStack.
- Las acciones tienen
onClick = { /* TODO */ }— no hacen nada.
Lo que falta¶
- ❌ onClicks funcionales de cada acción.
- ❌ Datos reales (hoy solo lee del
Reportepasado). - ❌ Editar reporte (si está en borrador).
- ❌ Cancelar reporte.
11. Paquetes (Mis paquetes)¶
Archivo: app/src/main/java/com/example/islabox/ui/screens/main/PaquetesScreen.kt
Lo que muestra¶
| Elemento | Detalle |
|---|---|
| Título | "Mis paquetes" |
| Subtítulo | "Lista de paquetes ya recibidos físicamente en el almacén" |
| Lista | 3 ejemplos con PackageCard |
| Empty state | "No tienes paquetes en el almacén" |
| (sin FAB) | — |
Datos hardcoded¶
val paquetes = listOf(
Reporte(tienda = "Amazon", estado = "En almacén", diasEnAlmacen = 3, ...),
Reporte(tienda = "Shein", estado = "Listo para enviar", diasEnAlmacen = 1, ...),
Reporte(tienda = "Temu", estado = "En tránsito", diasEnAlmacen = 0, ...)
)
Cada card (PackageCard)¶
- Foto del paquete (placeholder con
Icons.Default.Inventory2) - Tienda + badge de estado
- "Tracking: {numeroTracking}"
- 3 columnas: RECIBIDO / DÍAS ALMACÉN (rojo si > 5) / FECHA LÍMITE
Lo que hace¶
- Click en una card →
onPaqueteClick(paquete)→Screen.ReporteDetalle(paquete).
Lo que falta¶
- ❌ Filtros por estado.
- ❌ Datos del
FakeDataSource. - ❌ Sección "Entregados" (lista propia).
- ❌ Sección "En tránsito a Cuba" (lista propia).
12. Guía (Centro de ayuda)¶
Archivo: app/src/main/java/com/example/islabox/ui/screens/main/GuiaScreen.kt
Lo que muestra¶
| Elemento | Detalle |
|---|---|
| Título "CENTRO DE AYUDA" | rosa 0xFFE91E63 |
| Título "Guía" | headlineLarge navy |
| Subtítulo | "Todo lo que necesitas saber sobre IslaBox." |
| Featured card | FeaturedGuideCard con "EMPIEZA AQUÍ" + 3 pasos |
| Lista de 6 items | GuideListItem |
6 items de guía¶
| Ícono | Título | Subtítulo |
|---|---|---|
Inventory2 |
"Cómo enviar con IslaBox" | "Pasos para enviar tu primer paquete a Cuba." |
LocationOn |
"Usa tu dirección en EE. UU." | "Compra en cualquier tienda y recibe en Miami." |
GppGood (verde) |
"Artículos permitidos" | "Qué puedes enviar y restricciones de aduana." |
Schedule |
"Tiempos de entrega" | "Estimaciones de tránsito y entrega final." |
Article (rosa) |
"Información de aduana" | "Tarifas, declaraciones y procesos." |
Help |
"Preguntas frecuentes" | "Respuestas a las dudas más comunes." |
Lo que hace¶
LazyColumnconGuiaTitleSection,FeaturedGuideCardy 6GuideListItem.- Cada item tiene
onClick = { /* TODO */ }— no navega a ningún lado.
Lo que falta¶
- ❌ onClicks que naveguen a TutorialAmazon, TutorialShein, TutorialTemu.
- ❌ Pantalla de "Información de aduana" (módulo informativo).
- ❌ Pantalla de "Preguntas frecuentes" (FAQ navegable).
- ❌ Pantalla de "Tiempos de entrega" (estimaciones por vía).
13. Perfil¶
Archivo: app/src/main/java/com/example/islabox/ui/screens/main/PerfilScreen.kt
Lo que muestra¶
| Sección | Item | onClick |
|---|---|---|
| Header | Avatar "KV" + nombre + email + identificador | — |
| CUENTA | Mi Información | vacío |
| CUENTA | Direcciones | vacío |
| CUENTA | Métodos de Pago | vacío |
| PREFERENCIAS | Notificaciones | vacío |
| PREFERENCIAS | Ayuda y Soporte | vacío |
| PREFERENCIAS | Privacidad | vacío |
| Botón rojo | Cerrar Sesión | vacío |
| Footer | "Versión 1.0.0 - IslaBox" | — |
Datos hardcoded¶
ProfileHeader(
name = "Kleudy Victor Torno Peña",
email = "kleudy@example.com",
lockerId = "CP-001042-7" // ⚠️
)
Iniciales hardcoded: "KV".
Lo que hace¶
navControllerse pasa por si alguna pantalla interna lo necesita, pero ningún item navega.onClick = { /* Logout logic */ }en Cerrar Sesión.
Lo que falta¶
- 🔴
CP-001042-7→CP-001042-8. - ❌ Datos del usuario.
- ❌ Iniciales calculadas.
- ❌ onClicks de los 6 items.
- ❌ Lógica de cerrar sesión (volver a
Welcome).
14. Notifications¶
Archivo: app/src/main/java/com/example/islabox/ui/screens/main/NotificationsScreen.kt
Lo que muestra¶
| Elemento | Detalle |
|---|---|
| Fondo | LiquidGlassBackground |
| Top bar | "Notificaciones" con back popBackStack |
| Empty state | Ícono Notifications 64dp + "No tienes notificaciones" |
Lo que hace¶
- popBackStack al back.
Lo que falta¶
- ❌ Lista de notificaciones reales.
- ❌ Tipos de notificaciones (18+ eventos según doc).
- ❌ Indicador de no leídas.
- ❌ Filtros por tipo.
- ❌ Marcar como leída.
Pantalla huérfana: ReporteScreen¶
Archivo: app/src/main/java/com/example/islabox/ui/screens/main/ReporteScreen.kt
Estado: 🔒 A eliminar.
Tiene la misma estructura que ReportesScreen pero con datos distintos (2 reportes con info completa) y un ModalBottomSheet con el form completo.
MainScreen solo llama a ReportesScreen; ReporteScreen nunca se usa.
Criterio de eliminación: T-204.