- Plant Clock "Job cards" tab: scan a vehicle QR to start a job, scan again to finish with odometer (or no meter), kind of work and a note - /running/job-cards table with period, work, vehicle and mechanic filters - Remove /running/operators and /running/mechanics; mechanic badge PDF moves to Employees Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
21 lines
1 KiB
TypeScript
21 lines
1 KiB
TypeScript
/** Kinds of work a job card can record. Order is the order they are offered. */
|
|
export const JOB_TYPES = [
|
|
{ id: "service", label: "Service" },
|
|
{ id: "breakdown", label: "Breakdown" },
|
|
{ id: "repair", label: "General repairs" },
|
|
] as const;
|
|
export type JobType = (typeof JOB_TYPES)[number]["id"];
|
|
export const jobTypeLabel = (id: string) => JOB_TYPES.find((t) => t.id === id)?.label ?? "";
|
|
export const isJobType = (v: unknown): v is JobType => JOB_TYPES.some((t) => t.id === v);
|
|
|
|
export const MAX_NOTE = 1000;
|
|
|
|
/** Whole minutes between two instants; never negative. PocketBase stamps look like "2026-10-22 08:15:00.000Z". */
|
|
export function minutesBetween(from: string, to: string): number {
|
|
const a = new Date(from.replace(" ", "T")).getTime();
|
|
const b = new Date(to.replace(" ", "T")).getTime();
|
|
if (!Number.isFinite(a) || !Number.isFinite(b)) return 0;
|
|
return Math.max(0, Math.round((b - a) / 60000));
|
|
}
|
|
|
|
export const formatMinutes = (m: number) => `${Math.floor(m / 60)}h ${String(m % 60).padStart(2, "0")}m`;
|