"use client"; import Link from "next/link"; import { useState } from "react"; import { useSnap } from "@/lib/client"; /* The first-run checklist on the dashboard. Six things a new room does once, each read from the * records rather than remembered: a tick appears because the staff register has a row in it, not * because somebody clicked "done". Every row links to the screen that does it. The panel goes on * its own once all six are ticked, or once the room is 60 days old with three or more ticked, and * an admin can put it away with Dismiss (Facility.checklistDismissed). Not on the phone app. */ const DAY = 86_400_000; export default function Checklist({ welcome, onDismissWelcome }: { welcome: boolean; onDismissWelcome: () => void }) { const { s, mutate } = useSnap(); const [hidden, setHidden] = useState(false); const admin = s.session.role === "Admin"; const steps: { label: string; done: boolean; href: string; cta: string }[] = [ { label: "Add staff, or import the register", done: s.staff.length > 0, href: "/app/settings?tab=data", cta: "Settings › Data" }, { label: "Add garments", done: s.catalog.length > 0, href: "/app/settings?tab=data", cta: "Settings › Data" }, { label: "Set reorder levels", done: Object.values(s.stock).some((x) => x.reorder !== null && x.reorder !== undefined), href: "/app/stock", cta: "Inventory" }, { label: "Record opening stock", done: s.moves.length > 0 || Object.values(s.stock).some((x) => x.opening > 0), href: "/app/stock", cta: "Inventory" }, { label: "Issue a garment", done: s.issues.length > 0, href: "/app/issue", cta: "Issue stock" }, { label: "Bind a barcode or print labels", done: Object.keys(s.barcodes).length > 0, href: "/app/stock", cta: "Inventory" }, ]; const done = steps.filter((x) => x.done).length; const ageDays = Math.floor((Date.now() - new Date(s.createdAt).getTime()) / DAY); const finished = done === steps.length || (ageDays >= 60 && done >= 3); if (hidden || s.settings.checklistDismissed || (finished && !welcome)) return null; async function dismiss() { setHidden(true); onDismissWelcome(); if (admin) await mutate("settings.checklist", { dismissed: true }); } return (
{welcome ? "Welcome to ThreadCount" : "Getting set up"}
{done} of {steps.length}
{steps.map((st) => (
{st.done ? "✓" : "○"}
{st.label}
{!st.done && {st.cta}}
))}
{(admin || welcome) && (
)}
); }