because I got bored of customising my CV for every job
at main 79 lines 2.6 kB view raw
1import { Card, StatusDot } from "@cv/ui"; 2import type { WorkerHealthQuery } from "@/generated/graphql"; 3 4type Worker = WorkerHealthQuery["workerHealth"][number]; 5 6type DotColor = "green" | "yellow" | "red"; 7 8const statusColor: Record<string, DotColor> = { 9 healthy: "green", 10 stale: "yellow", 11 dead: "red", 12}; 13 14const formatRelativeTime = (isoString: string): string => { 15 const diff = Date.now() - new Date(isoString).getTime(); 16 const seconds = Math.floor(diff / 1000); 17 18 if (seconds < 60) return `${seconds}s ago`; 19 const minutes = Math.floor(seconds / 60); 20 if (minutes < 60) return `${minutes}m ago`; 21 const hours = Math.floor(minutes / 60); 22 if (hours < 24) return `${hours}h ago`; 23 return `${Math.floor(hours / 24)}d ago`; 24}; 25 26const truncateUuid = (uuid: string): string => uuid.slice(0, 8); 27 28interface WorkerHealthCardProps { 29 workers: Worker[]; 30} 31 32export const WorkerHealthCard = ({ workers }: WorkerHealthCardProps) => ( 33 <Card> 34 <h3 className="mb-3 text-lg font-medium text-ctp-text">Workers</h3> 35 {workers.length === 0 ? ( 36 <p className="text-sm text-ctp-subtext0">No workers registered</p> 37 ) : ( 38 <div className="overflow-x-auto"> 39 <table className="w-full text-sm"> 40 <thead> 41 <tr className="border-b border-ctp-surface1 text-left text-ctp-subtext0"> 42 <th className="pb-2 pr-4">Worker ID</th> 43 <th className="pb-2 pr-4">Status</th> 44 <th className="pb-2 pr-4">Started</th> 45 <th className="pb-2 pr-4">Last Seen</th> 46 </tr> 47 </thead> 48 <tbody> 49 {workers.map((w) => ( 50 <tr 51 key={w.workerId} 52 className="border-b border-ctp-surface1 last:border-b-0" 53 > 54 <td 55 className="py-1.5 pr-4 font-mono text-xs text-ctp-text" 56 title={w.workerId} 57 > 58 {truncateUuid(w.workerId)} 59 </td> 60 <td className="py-1.5 pr-4"> 61 <span className="flex items-center gap-2"> 62 <StatusDot color={statusColor[w.status] ?? "gray"} /> 63 {w.status} 64 </span> 65 </td> 66 <td className="py-1.5 pr-4 text-ctp-subtext0"> 67 {formatRelativeTime(w.startedAt)} 68 </td> 69 <td className="py-1.5 pr-4 text-ctp-subtext0"> 70 {formatRelativeTime(w.lastSeenAt)} 71 </td> 72 </tr> 73 ))} 74 </tbody> 75 </table> 76 </div> 77 )} 78 </Card> 79);