Componente CorreoPage — página /correo completa
Descripción
CorreoPage es el componente React que renderiza la página /correo completa. Muestra el informe de correo del miembro autenticado dividido en secciones de categoría (Actúa/Entérate), con detalles de cada ítem y enlaces a Zoho.
Estructura
Props
interface DigestItem {
nivel: 'actua' | 'enterate';
urgente?: boolean;
remitente: string;
asunto: string;
porque: string;
zoho_link?: string;
}
interface Digest {
owner: string;
generated_at: string;
resumen: string | null;
ruido_count: number;
items: DigestItem[];
created_at: string;
}
Sin props explícitas — los datos se obtienen del endpoint GET /api/correo/digest en el hook useEffect.
Estado
const [digest, setDigest] = useState<Digest | null>(null);
const [loading, setLoading] = useState(true);
Comportamiento
Ciclo de vida
-
Montaje:
- Si
isLocalDev()→ skip de fetch, muestra vacío (sin datos en dev) - Si no → fetch
GET /api/correo/digest
- Si
-
Fetch:
- Request sin autenticación explícita (CF Access desde sesión)
- Si 200 OK y body válido →
setDigest(data) - Si 404 / no-ok →
setDigest(null) - Finalmente →
setLoading(false)
-
Error handling:
- Catch silencioso en el fetch →
setDigest(null)(no muestra error rojo, sino el estado vacío)
- Catch silencioso en el fetch →
Secciones
Header
> Correo
> Tu buzón, digerido
> Última pasada de /correo: <fmtFecha(generated_at)>
Formato de fecha: es-ES con weekday corto, día, mes corto, HH:MM.
Estado vacío
Si !digest:
> Aún no hay informe tuyo
> Se genera con la pasada programada de tu equipo (o lanzando el skill /correo a mano
> en Claude Code). Los cuerpos de los mensajes nunca se copian aquí: se abren en Zoho.
Sección “Actúa” (si digest)
- Título:
Actúa (N)— donde N es cantidad de ítems connivel='actua' - Si vacío: mensaje
Nada que requiera acción - Si hay: grid de
ItemCard(gap: 8px, flex column)
Sección “Entérate” (si digest)
- Título:
Entérate (M)— donde M es cantidad connivel='enterate' - Si vacío: mensaje
Sin novedades - Si hay: grid de
ItemCard
Footer
- Contador de ruido:
Ruido filtrado: {ruido_count} mensajes que no merecían tu tiempo.
Componente ItemCard
Renderiza un ítem individual (bento style):
Estilo:
- Clase
bento(padding 12px/16px) - Border-left: rojo (
--danger) si urgente, transparente si no - Layout: flex column, gap 4px
Contenido:
-
Línea asunto + urgencia:
- Asunto (fontWeight 700, text-sm)
- Si
urgente=true: badge “URGENTE” (uppercase, fontWeight 700, color danger, text-xs)
-
Remitente (text-xs, color fg-dim)
-
Porque (text-sm, color fg-muted) — la justificación del item
-
Botón Zoho (si
zoho_link):- Clase:
btn xs action - Texto: “Abrir en Zoho”
- Abre en nueva pestaña (
target="_blank",rel="noopener noreferrer") - Title: “Abre el mensaje completo en el cliente de Zoho”
- Clase:
Rutas Astro
src/pages/correo/index.astro:
<BaseLayout title="Correo">
<div class="app-body">
<main>
<div class="mx-auto max-w-6xl px-6 py-8">
<CorreoPage client:load />
</div>
</main>
</div>
</BaseLayout>
- Wrapper:
BaseLayout(header + sidebar + footer) - Main content:
CorreoPageconclient:load(hydratación inmediata)
Véase también
- [[feature—workspace—correo-menu-f0]]
- [[entity—functions—endpoint—correo-digest]]
- [[entity—src—widget—correo-widget]]