46a1911c1c
Uniform stock management for healthcare linen rooms: the coordinator app, the phone counter and the staff app, for your own server. Built from 5470a36 on 2026-09-13. Licensed under the Functional Source License (FSL-1.1-ALv2).
117 lines
7.6 KiB
TypeScript
117 lines
7.6 KiB
TypeScript
"use client";
|
|
/* Help: the rules and routines a coordinator needs to know once, written down in one place so the
|
|
* working screens don't have to carry them. The owner took the explanations off every screen and
|
|
* asked for anything worth keeping to live here instead.
|
|
*
|
|
* Every figure is read from this facility's own settings rather than written in, so the page can't
|
|
* quote a number the facility has changed. The import rules are the templates' own notes, so they
|
|
* can't drift from what the importer accepts. */
|
|
import { useSnap } from "@/lib/client";
|
|
import { PageHead } from "@/components/ui";
|
|
import { CSV_TEMPLATES } from "@/lib/csv";
|
|
import { FTE_SETS, SLIP_DAYS } from "@/lib/compute";
|
|
import { SET_GARMENTS, setsCap, setsOnStart } from "@/lib/sets";
|
|
|
|
function Section({ title, children }: { title: string; children: React.ReactNode }) {
|
|
return (
|
|
<div className="tc-panel" style={{ marginBottom: "var(--space-4)" }}>
|
|
<div className="tc-panel-head"><span>{title}</span></div>
|
|
<div className="tc-panel-body" style={{ fontSize: 14, lineHeight: 1.6 }}>{children}</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const list = { margin: 0, paddingLeft: "1.2em", display: "grid", gap: "var(--space-1)" } as const;
|
|
|
|
export default function Help() {
|
|
const { s } = useSnap();
|
|
const cap = setsCap(s.settings.capSets);
|
|
const start = Math.min(cap, setsOnStart(s.settings.initialSets));
|
|
// The table as the form lists it: a full-timer's figure first, down to the smallest.
|
|
const table = Object.entries(FTE_SETS).filter(([, n]) => n !== null) as [string, number][];
|
|
|
|
return (
|
|
<>
|
|
<PageHead eyebrow="Help" title="How ThreadCount works" sub="The rules behind the screens, with this facility's own figures." />
|
|
|
|
<Section title="What anyone may hold">
|
|
<ul style={list}>
|
|
<li>Up to <b>{cap} sets</b> at any time — {cap} tops and {cap} pairs of trousers. The same for every staff group, nursing included.</li>
|
|
<li>It counts everything issued and not handed in or returned, plus anything on order for them, waiting at the counter, or approved and not yet collected. Pre-loved garments count.</li>
|
|
<li>Garments that aren't part of a set — fleeces, jackets, maternity wear — have their own ceiling of {cap}.</li>
|
|
<li>It isn't a yearly allowance and nothing resets in July. At the ceiling, the next garment comes by handing one in first, or on a coordinator's override, which is recorded.</li>
|
|
<li>Change the figure under Settings → General.</li>
|
|
</ul>
|
|
</Section>
|
|
|
|
<Section title="The three routes">
|
|
<p style={{ margin: "0 0 var(--space-2)" }}>Each staff group is on one route, chosen under Settings → Staff groups. All three stop at the same {cap} sets.</p>
|
|
<ul style={list}>
|
|
<li><b>FTE table</b> — the hours someone works propose their starting kit: {table.map(([fte, n]) => `${fte} FTE ${n}`).join(", ")} sets; a casual is at the manager's discretion. A manager may sign for more.</li>
|
|
<li><b>Starting kit</b> — {start} sets on the first day ({start * SET_GARMENTS} garments), then more as needed. Nothing has to be handed back first.</li>
|
|
<li><b>Manager approval</b> — no starting kit; the manager approves each set.</li>
|
|
<li>A group can't be on two routes, and a group with people in it can't be removed — rename it instead.</li>
|
|
</ul>
|
|
</Section>
|
|
|
|
<Section title="The yearly figure">
|
|
<p style={{ margin: 0 }}>“Items (FY)” on Reports and “drawn since July” on Issue Stock count what someone has drawn since 1 July. They feed the reports and the monthly exceptions list, and never limit what the counter issues. Groups on the FTE table aren't measured against one.</p>
|
|
</Section>
|
|
|
|
<Section title="Hand-ins">
|
|
<ul style={list}>
|
|
<li>Handing a garment in frees room at the counter straight away, whether or not the credit box is ticked.</li>
|
|
<li>The credit tick adds the good garments back to the yearly figure and to the manager's approval. Pre-loved garments earn neither.</li>
|
|
<li>Good garments join the pre-loved pool and are reissued free; rags are counted for disposal.</li>
|
|
</ul>
|
|
</Section>
|
|
|
|
<Section title="Garment types">
|
|
<p style={{ margin: 0 }}>A garment's type decides how it counts. Tops and trousers are each half a set; every other type counts toward the separate ceiling. A type typed in by hand that isn't on the list counts toward no set, so pick from the list.</p>
|
|
<p style={{ margin: "var(--space-2) 0 0" }}>Each garment is tagged for the staff groups that wear it, or for all groups. Staff can only request their own groups' garments, and the counter needs a coordinator's override, which is recorded, to issue anyone a garment outside their group.</p>
|
|
<p style={{ margin: "var(--space-2) 0 0" }}>A garment is also men's, women's or unisex. Somebody is offered the cut set as their Uniform style plus everything unisex; blank means every style until a coordinator sets it, and the counter needs the same override, also recorded, to issue anyone another cut.</p>
|
|
</Section>
|
|
|
|
<Section title="The staff app">
|
|
<ul style={list}>
|
|
<li>Generate a code on the staff record and hand them the slip. A code works once and expires after {SLIP_DAYS} days.</li>
|
|
<li>Record their manager first, under Manager's approval on the staff record — nobody can raise a request without one.</li>
|
|
</ul>
|
|
</Section>
|
|
|
|
<Section title="Requests and approvals">
|
|
<ul style={list}>
|
|
<li>A request goes to the person's manager — the same person who signs their paper order form.</li>
|
|
<li>A manager can raise requests for the people who report to them; those go to the manager above. With nobody above, the request waits under Ward Requests → Needs an approver.</li>
|
|
<li>Nobody approves a request they raised for somebody else.</li>
|
|
<li>Anyone can be set as their own manager; what they approve for themselves is marked Self-approved.</li>
|
|
</ul>
|
|
</Section>
|
|
|
|
<Section title="Stock takes">
|
|
<p style={{ margin: 0 }}>A count in progress is saved in this browser only, under your sign-in. It survives a reload, but not a move to another computer or the phone — finish a count where you started it.</p>
|
|
</Section>
|
|
|
|
<Section title="Importing and exporting">
|
|
<p style={{ margin: "0 0 var(--space-2)" }}>Settings → Data imports each list from a CSV file. The rules for each:</p>
|
|
<ul style={list}>
|
|
{Object.entries(CSV_TEMPLATES).map(([k, t]) => <li key={k}><b>{t.name}</b> — {t.note}</li>)}
|
|
</ul>
|
|
<p style={{ margin: "var(--space-2) 0 0" }}>The Staff Register's Export writes the same columns, so a ward's list can go to its manager, come back with Manager number filled in, and be imported again. The Approver name column is only for checking and is ignored on import.</p>
|
|
</Section>
|
|
|
|
<Section title="Month-end journal">
|
|
<p style={{ margin: 0 }}>One debit line per cost centre, priced at each garment's cost on the day it was issued. Finance posts the balancing credit.</p>
|
|
</Section>
|
|
|
|
<Section title="Who ThreadCount emails">
|
|
<ul style={list}>
|
|
<li>You — password resets, and updates you've subscribed to.</li>
|
|
<li>Staff — only about their own requests, once they've set up the staff app.</li>
|
|
<li>Managers — the link to approve or decline a request.</li>
|
|
</ul>
|
|
</Section>
|
|
</>
|
|
);
|
|
}
|