Files
threadcount-community/components/PlanBanner.tsx
T
ThreadCount 1bc2de655a ThreadCount Community edition
Uniform stock management for healthcare linen rooms. Licensed under the GNU AGPL v3.
2026-09-13 08:45:19 +10:00

29 lines
1.6 KiB
TypeScript

"use client";
import Link from "next/link";
import { useSnap } from "@/lib/client";
/* One bar across every /app screen when the plan needs a coordinator's attention, and nothing
* otherwise. Three states earn it: read-only (writes refused, reads and exports still fine), grace
* (the period has ended, a fortnight to sort the invoice), and the last fortnight of a trial. A
* free or paid room in good standing sees nothing here — plans are not a thing to be reminded of.
* Quiet until plans are live, whatever the columns say. */
export default function PlanBanner() {
const { s } = useSnap();
const p = s.plan;
if (!p || !p.live || s.demo) return null;
let text: string | null = null;
let tone: "warn" | "ink" = "ink";
if (p.readOnly) { text = "Read-only. Reports, exports and the backup still work."; tone = "warn"; }
else if (p.state === "grace") { text = `${p.label} ended. Writable for ${p.graceDaysLeft ?? 0} more days.`; tone = "warn"; }
else if (p.state === "trial" && p.daysLeft !== null && p.daysLeft <= 14) text = `Trial ends in ${p.daysLeft} days.`;
if (!text) return null;
const bg = tone === "warn" ? "var(--color-accent)" : "var(--color-text)";
return (
<div role="status" style={{ display: "flex", alignItems: "center", gap: 14, padding: "8px 16px", background: bg, color: "#fff", fontSize: 12.5, flexWrap: "wrap" }}>
<span style={{ width: 8, height: 8, background: "#fff", flex: "none" }} />
<b>{text}</b>
{s.session.role === "Admin" && <Link href="/app/settings?tab=plan" style={{ marginLeft: "auto", color: "#fff", fontWeight: 700 }}>Plan</Link>}
</div>
);
}