/* 아리 — 스마트 인박스 위젯 입력하면 아리가 실시간으로 분류: 작업/일정/아이디어 × 업무/개인 컨텍스트 + 배치 + 자동화. dash-v2.jsx에서 로 사용 (I = 아이콘 컴포넌트). */ (function () { const { useState, useRef } = React; const SD = window.AriSmartInbox; const SPHERE = { work: { label: "업무", tone: "var(--blue)" }, life: { label: "개인", tone: "var(--green)" }, }; const TYPE_ICON = { task: "check", event: "cal", idea: "brain" }; /* ---------- 데모 파서 — 규칙 기반이지만 '아리의 판단'을 보여주는 용도 ---------- */ function parseCapture(text) { const t = text.trim(); const base = { type: "task", typeLabel: "작업", sphere: "life", proj: "개인 · 분류 중", tone: "green", due: null, when: null, extra: null, reason: "", }; const hasTime = /(\d{1,2})\s*시|오전|오후|내일|모레|이번\s*주|다음\s*주|[월화수목금토일]요일/.test(t); if (/비행기|항공|티켓|예매|숙소|호텔/.test(t)) return { ...base, proj: "개인 › 여행 — 한국", tone: "coral", due: "출발 전", when: "오늘 21:00 빈 시간 추천", extra: "가격 추적 알림 켜둠", reason: "구매 행동이 필요해서 '작업'으로 — 작업 트리의 '개인 › 여행' 프로젝트에 다른 작업과 똑같이 들어가요. 저녁 빈 시간에 하라고 추천만 해두고, 가격 알림도 걸어뒀어요." }; if (/미팅|회의|싱크|리뷰/.test(t) && hasTime) return { ...base, type: "event", typeLabel: "일정", sphere: "work", proj: "업무 캘린더", tone: "blue", when: "캘린더 등록 + 참석자 초대 준비", reason: "시간이 정해진 업무 일은 일정으로 바로 등록해요." }; if (/약속|예약|만나|생일|모임/.test(t) && hasTime) return { ...base, type: "event", typeLabel: "일정", sphere: "life", proj: "개인 캘린더", tone: "blue", when: "캘린더 등록 완료", reason: "시간이 정해진 일은 작업이 아니라 일정으로 바로 등록해요." }; if (/어떨까|해볼까|아이디어|괜찮을 듯|좋을 것 같/.test(t)) return { ...base, type: "idea", typeLabel: "아이디어", sphere: "work", proj: "아이디어 보드", tone: "violet", reason: "아직 행동이 정해지지 않아 보드에 보관해요 — 관련 프로젝트에 연결해뒀어요." }; if (/사기|사야|주문|구매|선물|장보/.test(t)) return { ...base, proj: "쇼핑 리스트", tone: "amber", when: "주말 오전 장보기 블록", reason: "구매 작업은 쇼핑 리스트에 모아 주말 블록에 한 번에 처리해요." }; if (/리포트|온보딩|회신|피드백|배포|QA|문서/.test(t)) return { ...base, sphere: "work", proj: "업무 · 관련 프로젝트", tone: "blue", when: "내일 오전 빈 블록", reason: "업무 작업으로 분류해 내일 오전 빈 블록에 배치했어요." }; return { ...base, when: "이번 주 개인 시간", reason: "마감이 또렷하지 않아 이번 주 개인 시간에 느슨하게 두었어요 — 아니면 칩을 눌러 바꿔주세요." }; } const cycleType = (r) => { const next = { task: "event", event: "idea", idea: "task" }[r.type]; const label = { task: "작업", event: "일정", idea: "아이디어" }[next]; return { ...r, type: next, typeLabel: label }; }; function SmartInbox({ I }) { const [items, setItems] = useState(SD.items); const [input, setInput] = useState(""); const [filter, setFilter] = useState("all"); const seq = useRef(0); const submit = () => { const text = input.trim(); if (!text) return; const id = "u" + (++seq.current); setItems((xs) => [{ id, kind: "text", time: "방금", status: "thinking", raw: text, route: null }, ...xs]); setInput(""); setTimeout(() => { setItems((xs) => xs.map((x) => x.id === id ? { ...x, status: "new", route: parseCapture(text) } : x)); }, 900); }; const confirm = (id) => setItems((xs) => xs.map((x) => x.id === id ? { ...x, status: "done" } : x)); const reType = (id) => setItems((xs) => xs.map((x) => x.id === id ? { ...x, route: cycleType(x.route) } : x)); const shown = items.filter((x) => filter === "all" || (x.route && x.route.sphere === filter)); return (

스마트 인박스

업무든 일상이든 일단 적기 — 분류는 아리가 해요
오늘 {SD.todayRouted}건 정리
{/* 입력 */}
setInput(e.target.value)} onKeyDown={(e) => e.key === "Enter" && submit()} placeholder="갑자기 생각난 것 아무거나… 예) 다음 주 한국 가는 비행기 티켓 사기" />
{/* 컨텍스트 필터 */}
{[["all", "전체"], ["work", "업무"], ["life", "개인"]].map(([k, l]) => ( ))} 업무/개인은 필터일 뿐 — 작업은 한 곳에서 다 보여요
{/* 캡처 목록 */}
{shown.map((c) => (
{c.raw}
{c.status === "thinking" ? (
아리가 분류하고 있어요
) : ( <>
{SPHERE[c.route.sphere].label} {c.route.proj} {c.route.due && {c.route.due}} {c.route.when && {c.route.when}} {c.route.extra && {c.route.extra}}
{c.route.reason}
{c.status === "new" && (
)} )}
{c.status === "done" ? : c.time}
))}
); } window.SmartInbox = SmartInbox; })();