import { useState, useRef, useCallback } from "preact/hooks"; import type { WrapupData, WrapupTodo, WrapupExpense, ActualDay } from "../../lib/types"; function processingStatus(actuals: ActualDay[]): { total: number; plan: number; done: number } { let total = 0; let plan = 0; for (const day of actuals) { for (const e of day.entries) { total++; if (e.tags?.includes("plan")) plan++; } } return { total, plan, done: total - plan }; } export function WrapupTab({ wrapup, tripId, actuals }: { wrapup: WrapupData; tripId: string; actuals: ActualDay[] }) { const [data, setData] = useState(wrapup); const saveTimeout = useRef | null>(null); const persist = useCallback((updated: WrapupData) => { if (saveTimeout.current) clearTimeout(saveTimeout.current); saveTimeout.current = setTimeout(() => { fetch(`/travel/api/wrapup?tripId=${tripId}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(updated), }).catch(() => {}); }, 500); }, [tripId]); const toggleTodo = (idx: number) => { const updated = { ...data, todos: data.todos.map((t, i) => i === idx ? { ...t, done: !t.done } : t) }; setData(updated); persist(updated); }; const stats = processingStatus(actuals); const pct = stats.total > 0 ? Math.round((stats.done / stats.total) * 100) : 0; return (
Processing Status
{stats.done} of {stats.total} entries recorded ({pct}%) — {stats.plan} still need actuals
To Do
{data.todos.length === 0 &&
No items
} {data.todos.map((todo, i) => ( ))}
{data.expenses.length > 0 && (
Expenses
{data.expenses.map((exp, i) => (
{exp.item} {exp.category && {exp.category}} {exp.amount}
))}
)} {data.highlights.length > 0 && (
Highlights
{data.highlights.map((h, i) => (
{h}
))}
)} {data.lessons.length > 0 && (
Lessons
{data.lessons.map((l, i) => (
{l}
))}
)} {data.summary && (
Summary
{data.summary}
)}
); }