- Workforce: Employees register, per-employee dashboards, Attendance table - Plant Clock: scan-only clock, bottom tab bar (Employees / Oil & Diesel / Job cards) - Oil & Diesel stock: diesel tank (650 L, opening 589 L), level overwrite dialog, QR on each card, book-out screen with searchable vehicle picker, filterable "Booked out" table (today/week/month/all/range) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
12 lines
955 B
TypeScript
12 lines
955 B
TypeScript
'use client';
|
|
import { duration } from '@/lib/clock-display';
|
|
|
|
export function StatusChip({status}:{status:'in'|'out'|'away'}) {
|
|
return <span className={`plant-clock-status ${status==='in'?'plant-clock-status-in':''}`}>{status==='in'?'At work':status==='out'?'Clocked out':'No scan today'}</span>;
|
|
}
|
|
export function Kpi({label,value,hint}:{label:string;value:string|number;hint?:string}) {
|
|
return <div className="plant-clock-panel p-3 sm:p-5 min-w-0"><p className="text-2xl sm:text-3xl font-semibold tabular-nums break-words">{value}</p><p className="text-xs text-text-muted mt-1">{label}</p>{hint&&<p className="text-xs text-text-muted mt-1">{hint}</p>}</div>;
|
|
}
|
|
/** Hours are always shown "8h 05m"; a dash means nothing was recorded, never 0h. */
|
|
export const hours=(minutes:number)=>minutes>0?duration(minutes).replace(/ (\d)m$/,' 0$1m'):'—';
|
|
export const rateText=(rate:number|null)=>rate===null?'—':`R ${rate.toFixed(2).replace('.',',')}/h`;
|