// frontend/components/mail/TriageLogModal.tsx — '오늘 메일 상세 로그' 다이얼로그(히어로 버튼으로 열림) // 정직성: 집중/홍보/스팸 '분류'는 Gmail·Outlook 이 한 것. 아리가 한 일은 '집중 메일 분석'뿐. "use client"; import { useEffect } from "react"; import useSWR from "swr"; import { Icon } from "@/components/Icon"; import { mailApi, type TriageLogEntry } from "@/lib/mail/api"; import type { MailAccount } from "@/lib/types"; // ISO → 'HH:MM'(로컬). function fmtTime(iso: string): string { const d = new Date(iso); if (Number.isNaN(d.getTime())) return ""; return d.toLocaleTimeString("ko-KR", { hour: "numeric", minute: "2-digit" }); } // 분류 버킷 → 칩 색 클래스 / 표시 순서. const BUCKET_TONE: Record = { 집중: "focus", 홍보: "promo", 소셜: "social", 업데이트: "update", 스팸: "spam", 휴지통: "muted", 보관: "muted", 기타: "muted", }; const BUCKET_ORDER = ["집중", "홍보", "소셜", "업데이트", "스팸", "휴지통", "보관", "기타"]; export function TriageLogModal({ open, onClose, log, accounts, accColor, onOpenMail, }: { open: boolean; onClose: () => void; log: TriageLogEntry[]; accounts: Record; accColor: (id: string) => string; onOpenMail: (id: string) => void; }) { useEffect(() => { if (!open) return; const onKey = (e: KeyboardEvent) => e.key === "Escape" && onClose(); window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); }, [open, onClose]); // 열렸을 때만 상세 분류를 가져온다. const { data: rows } = useSWR( open ? "mail/triage/classified" : null, () => { const d = new Date(); d.setHours(0, 0, 0, 0); return mailApi.triageClassified(d.toISOString()); }, { revalidateOnFocus: false }, ); if (!open) return null; const list = rows ?? []; const counts: Record = {}; list.forEach((r) => (counts[r.bucket] = (counts[r.bucket] ?? 0) + 1)); const buckets = BUCKET_ORDER.filter((b) => counts[b]); return (
e.stopPropagation()}>
오늘 메일 상세 로그
{/* 아리가 실제로 한 일 = 집중 메일 LLM 분석(분류 아님). */}

아리가 분석한 집중 메일

{log.length === 0 ? (

오늘 아리가 분석한 집중 메일이 아직 없어요.

) : (
    {log.map((e, i) => (
  • {e.error ? `분석 실패 · ${e.error}` : `집중 메일 ${e.analyzed}통 분석${e.cards ? ` · ${e.cards}건 챙길 거리` : ""}`}
  • ))}
)}
{/* 버킷 분류는 Gmail·Outlook 이 한 것 — 정직하게 출처 표기. */}

오늘 새 메일 {list.length}통

집중·홍보·스팸 분류는 Gmail·Outlook이 한 거예요. 아리는 집중 메일만 읽어 할 일·일정·답장을 정리해요.

{buckets.length > 0 && (
{buckets.map((b) => ( {b} {counts[b]} ))}
)} {!rows ? (

불러오는 중…

) : list.length === 0 ? (

오늘 도착한 새 메일이 없어요.

) : (
    {list.map((r) => { const accName = accounts[r.account]?.name ?? r.account; const noAction = r.tasks === 0 && r.events === 0 && r.replies === 0; return (
  • { onOpenMail(r.id); onClose(); }} >
    {accName.slice(0, 1).toUpperCase()}
    {r.from_name} {r.time}
    {r.subject}
    {r.bucket} {r.focused && (r.analyzed ? ( {[ r.priority, r.tasks > 0 && `할 일 ${r.tasks}`, r.events > 0 && `일정 ${r.events}`, r.replies > 0 && "답장", noAction && "정보성", ] .filter(Boolean) .join(" · ")} ) : ( 분석 대기 ))}
  • ); })}
)}
); }