"use client"; /* 1A — Home. * * Two questions, in this order: what is on the way, and what you hold. Everything else is a * shortcut one row lower. There is no list of orders here on purpose — that is the Orders tab, and * a home screen that tried to be both would be neither. * * The one banner at the top is the only place on this screen where somebody else is blocked until * this person acts. At most one is ever drawn: a screen with two things shouting at once has * nothing at the top. */ import { MBody, MRow, MSection, MTopAction, MTopBrand } from "@/components/m"; import { AlertBar, DarkButton, DarkCard, DarkRow, EdgeRow, IdentityBlock, Kicker, N600, Notice, QuickGrid, } from "@/components/staffui"; import StaffNav from "@/components/staffnav"; import { useStaff } from "@/lib/staffclient"; import { statusText } from "@/lib/staffreq"; import type { ReqRow } from "@/lib/staffdata"; type Data = { name: string; num: string; ward: string; group: string; facility: string; hasManager: boolean; wardDesk: boolean; holding: number; live: ReqRow | null; openCount: number; notice: string; /** Open requests this person raised for somebody else — never their own. */ raisedOpen: ReqRow[]; lastRequest: { itemId: string; si: number; reason: string; code: string } | null; }; export type HoldRow = { item: string; size: string; qty: number; last: string }; const plural = (n: number, w: string) => `${n} ${n === 1 ? w : w + "s"}`; export default function HomeScreen({ data, held, lastItem, managerName, kitCheckOpen }: { data: Data; /** Up to three, most recently issued first. The total is the section's own note. */ held: HoldRow[]; /** The garment on the last request, for the "Same again" tile. Null when they never asked. */ lastItem: string | null; managerName: string; kitCheckOpen: boolean; }) { const { me, counts } = useStaff(); const live = data.live; const st = live ? statusText(live) : null; /* At most one banner, approvals first. * * Driven by the count of requests ADDRESSED to this person, never by "is a manager": the linen * room can re-address a request to somebody who manages nobody, and a manager's last report can * move away while their request is still waiting. Gating on the role would take this banner away * from the one person who has to act on it. A desk that is also an approver keeps its bags on * the Team tab's badge. */ const banner = counts.approvals > 0 ? { title: `${plural(counts.approvals, "request")} waiting on you`, href: "/my/approvals" } : me.wardDesk && counts.round > 0 && data.ward ? { title: `${plural(counts.round, "bag")} to sign on ${data.ward}`, href: "/my/round" } : null; return ( <> {/* Sign out has left this screen. It lives on Account, with the password — where people look for it, and where the one thing a wearer can do to a phone they no longer have belongs. */} } /> {banner && }
{live && st ? ( /* The bag furthest along — ready beats out on the round beats waiting on a manager. * One request covers as many garments as the person needed, so the card leads with the * summary and the list itself is a tap away on the order. */
{live.status === "ready" && live.collectCode ? ( <> ) : ( )}
) : (
Nothing on the way
{data.hasManager && managerName ? `Ask for something and it goes to ${managerName} first.` : "Your manager isn’t recorded yet — the linen room has to set who approves your requests."}
)} {held.length > 0 ? held.map((h) => ( )) : (
Nothing on your record yet.
)} {/* 2×2. "Same again" is drawn only when there is a last request to repeat: a shortcut that opens an empty screen is worse than no shortcut. Swapping a size has moved to My kit, which is where a wearer reads the size that is wrong. */}
{/* A chore with a deadline, not an alert: dressing it as one would devalue the banner. The title is word for word the heading on the screen it opens. */} {kitCheckOpen && (
Kit check is open
Have you still got everything on your record?
)} {/* What they raised for other people, as one row rather than a list. Until Orders grew a Raised tab a request typed in for a colleague vanished the moment it was sent. */} {data.raisedOpen.length > 0 && (
Raised by you
{data.raisedOpen.length === 1 ? `One request open for ${data.raisedOpen[0].subjectName}` : `${data.raisedOpen.length} requests open for other people`}
Not yours to collect — this is where they got to.
)} {/* Somebody who will not type a request themselves asks the person who approves it. The server sends anything a manager raises up a level, which is why the row can say so plainly — approving your own raise is the one thing this must never allow. */} {me.isManager && (
Raise for someone you manage
Goes to your own manager, not to you.
)} {/* The round is listed by ward, so a clerk whose ward was never filled in has no round to open. Saying so beats a banner that never appears and a tap that 404s. */} {data.wardDesk && !data.ward && (
)} {data.notice && {data.notice}}
); }