CreaRack-SL

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

  1. Montaje:

    • Si isLocalDev() → skip de fetch, muestra vacío (sin datos en dev)
    • Si no → fetch GET /api/correo/digest
  2. 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)
  3. Error handling:

    • Catch silencioso en el fetch → setDigest(null) (no muestra error rojo, sino el estado vacío)

Secciones

> 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 con nivel='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 con nivel='enterate'
  • Si vacío: mensaje Sin novedades
  • Si hay: grid de ItemCard
  • 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:

  1. Línea asunto + urgencia:

    • Asunto (fontWeight 700, text-sm)
    • Si urgente=true: badge “URGENTE” (uppercase, fontWeight 700, color danger, text-xs)
  2. Remitente (text-xs, color fg-dim)

  3. Porque (text-sm, color fg-muted) — la justificación del item

  4. 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”

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: CorreoPage con client:load (hydratación inmediata)

Véase también

  • [[feature—workspace—correo-menu-f0]]
  • [[entity—functions—endpoint—correo-digest]]
  • [[entity—src—widget—correo-widget]]