// Dashboard with three layout variants: timeline, checklist, grid. const TaskIcon = ({ name, color }) => { const C = I[name] || I.doc; return (
); }; // completion logic shared const isDone = (taskId, progress) => COMPLETED_BY_PROGRESS[progress]?.has(taskId); // ──────────────── Hero header (greeting + progress) ──────────────── function DashboardHero({ persona, progress, onJump }) { const tasks = TASKS(persona); const total = tasks.length; const done = tasks.filter(t => isDone(t.id, progress)).length; const pct = Math.round(done / total * 100); const day = progress === "day1" ? "Day 1" : progress === "week1" ? "Week 1" : "All set"; return (
{day} · {PERSONAS[persona].startDate}

{progress === "done" ? <>Welcome aboard, {NEW_HIRE.first}. You're all set. : <>Welcome to Convoso, {NEW_HIRE.first}.}

{progress === "done" ? "Onboarding complete — your team is ready when you are. Here's a quick look at what's coming this week." : `You have ${total - done} ${total - done === 1 ? "task" : "tasks"} left in your onboarding plan. Most people finish in about ${progress === "day1" ? "two more hours" : "twenty minutes"}.`}

Your manager
{PERSONAS[persona].manager}
Role
{PERSONAS[persona].role}
Location
{PERSONAS[persona].location}
{pct}%
{done} of {total} done
); } // ──────────────── Quick stats row ──────────────── function QuickStats({ persona, progress, onNav }) { const tasks = TASKS(persona); const docCount = DOCS.filter(d => d.status === "pending").length; const meetingCount = MEETINGS[0].items.length; const trainCount = TRAININGS.filter(t => t.required && t.progress < 100).length; const items = [ { k: "meetings", icon: "calendar", label: "Meetings today", value: meetingCount, hint: "Next at 11:00 AM", color: "#2563eb" }, { k: "documents", icon: "doc", label: "Documents to sign", value: docCount, hint: "2 due tomorrow", color: "#f97316" }, { k: "training", icon: "book", label: "Trainings required", value: trainCount, hint: "12 hours total", color: "#a855f7" }, { k: "insurance", icon: "shield", label: "Benefits enrollment", value: "30d", hint: "Window closes Jun 11", color: "#16a34a" }, ]; return (
{items.map(it => { const C = I[it.icon]; return ( ); })}
); } // ──────────────── TIMELINE layout ──────────────── function TimelineLayout({ persona, progress, onNav }) { const tasks = TASKS(persona); const phases = [ { id: "day1", label: "Day 1", sub: "Mon · May 11", tone: "accent" }, { id: "week1", label: "Week 1", sub: "May 11 – May 15", tone: "info" }, { id: "month1", label: "Month 1", sub: "May 11 – Jun 11", tone: "muted" }, ]; return (
{phases.map((ph, i) => { const phaseTasks = tasks.filter(t => t.phase === ph.id); const phaseDone = phaseTasks.filter(t => isDone(t.id, progress)).length; const allDone = phaseDone === phaseTasks.length; return (
0 ? "active" : "")}> {allDone ? : {i + 1}}
{i < phases.length - 1 &&
}
{ph.label}
{ph.sub}
{phaseDone}/{phaseTasks.length}
{phaseTasks.map(t => ( ))}
); })}
); } const KIND_TONE = { meeting: { label: "Meeting", color: "#2563eb", icon: "calendar", nav: "meetings" }, doc: { label: "Document", color: "#f97316", icon: "doc", nav: "documents" }, training:{ label: "Training", color: "#a855f7", icon: "book", nav: "training" }, task: { label: "Task", color: "#0891b2", icon: "check", nav: null }, media: { label: "Watch", color: "#ec4899", icon: "play", nav: null }, }; function TaskRow({ t, done, onNav }) { const tone = KIND_TONE[t.kind] || KIND_TONE.task; const TIcon = I[t.icon] || I[tone.icon]; return (
{t.title}
{tone.label} {t.time && {t.time}} {t.duration && · {t.duration}} {t.deadline && Due in {t.deadline}} {t.required && Required} {t.count && · {t.count}}
{tone.nav ? ( ) : ( )}
); } // ──────────────── CHECKLIST layout ──────────────── function ChecklistLayout({ persona, progress, onNav }) { const tasks = TASKS(persona); const groups = [ { id: "required", label: "Required this week", tasks: tasks.filter(t => t.required && t.phase !== "month1") }, { id: "month", label: "First 30 days", tasks: tasks.filter(t => t.phase === "month1") }, { id: "optional", label: "Recommended", tasks: tasks.filter(t => !t.required && t.phase !== "month1") }, ]; return (
{groups.map(g => (

{g.label}

{g.tasks.filter(t => isDone(t.id, progress)).length} / {g.tasks.length} complete
{g.tasks.map(t => )}
))}
); } // ──────────────── GRID layout ──────────────── function GridLayout({ persona, progress, onNav }) { const tasks = TASKS(persona); const cats = [ { id: "meeting", label: "Meetings & 1:1s", icon: "calendar" }, { id: "doc", label: "Paperwork & Forms", icon: "doc" }, { id: "training", label: "Training", icon: "book" }, { id: "task", label: "Setup tasks", icon: "laptop" }, { id: "media", label: "Watch", icon: "play" }, ]; return (
{cats.map(c => { const cTasks = tasks.filter(t => t.kind === c.id); if (!cTasks.length) return null; const C = I[c.icon]; const tone = KIND_TONE[c.id]; const cDone = cTasks.filter(t => isDone(t.id, progress)).length; return (
{c.label}
{cDone} / {cTasks.length} complete
{cTasks.slice(0, 4).map(t => (
{t.title}
{t.time || t.duration}
))} {cTasks.length > 4 &&
+ {cTasks.length - 4} more
}
); })}
); } // ──────────────── Side panel: today's events ──────────────── function TodayPanel({ onNav }) { const today = MEETINGS[0]; return (
Today · {today.day} {today.date}

Your schedule

{today.items.map((m, i) => (
{m.time}
{m.end}
{m.title}
{m.with} · {m.loc} {m.loc === "Zoom" && }
))}
); } // ──────────────── Buddy / manager card ──────────────── function PeopleCard({ persona }) { const p = PERSONAS[persona]; const buddy = persona === "eng" ? { name: "Sam Liu", role: "Senior Engineer · Voice Infra" } : persona === "design" ? { name: "Devon Cole", role: "Senior Product Designer" } : { name: "Maya Cruz", role: "AE · Mid-Market" }; return (
Your people
{p.manager}
{p.managerRole}
{buddy.name}
{buddy.role} · Buddy
Lila Park
People Operations
); } // ──────────────── Resources ──────────────── function ResourcesCard() { const items = [ { title: "Employee Handbook", meta: "PDF · 84 pages", icon: "book" }, { title: "Convoso Brand & Voice", meta: "Notion", icon: "notion" }, { title: "Engineering Wiki", meta: "Confluence", icon: "globe" }, { title: "Office Map · DTLA HQ", meta: "PDF · 1 page", icon: "building" }, ]; return (
Resources
{items.map((r, i) => { const C = I[r.icon]; return (
{r.title}
{r.meta}
); })}
); } // ──────────────── Dashboard root ──────────────── function Dashboard({ persona, progress, layout, onNav }) { return (

Your onboarding plan

{layout === "timeline" ? "By week" : layout === "checklist" ? "By priority" : "By category"}
{layout === "timeline" && } {layout === "checklist" && } {layout === "grid" && }
); } window.Dashboard = Dashboard; window.TaskRow = TaskRow;