diff --git a/orchestrator/src/client/components/JobCard.tsx b/orchestrator/src/client/components/JobCard.tsx index 405e813..d9bb8a9 100644 --- a/orchestrator/src/client/components/JobCard.tsx +++ b/orchestrator/src/client/components/JobCard.tsx @@ -6,6 +6,7 @@ import React from "react"; import { Calendar, CheckCircle2, + Clock, Copy, DollarSign, Download, @@ -49,6 +50,27 @@ const formatDate = (dateStr: string | null) => { } }; +const formatDateTime = (dateStr: string | null) => { + if (!dateStr) return null; + try { + const normalized = dateStr.includes("T") ? dateStr : dateStr.replace(" ", "T"); + const parsed = new Date(normalized); + if (Number.isNaN(parsed.getTime())) return dateStr; + const date = parsed.toLocaleDateString("en-GB", { + day: "numeric", + month: "short", + year: "numeric", + }); + const time = parsed.toLocaleTimeString("en-GB", { + hour: "2-digit", + minute: "2-digit", + }); + return `${date} ${time}`; + } catch { + return dateStr; + } +}; + const safeFilenamePart = (value: string) => value.replace(/[^a-z0-9]/gi, "_"); export const JobCard: React.FC = ({ @@ -75,6 +97,7 @@ export const JobCard: React.FC = ({ const jobLink = job.applicationLink || job.jobUrl; const pdfHref = `/pdfs/resume_${job.id}.pdf`; const deadline = formatDate(job.deadline); + const discoveredAt = formatDateTime(job.discoveredAt); const isHighlighted = highlightedJobId === job.id; const handleCopyInfo = async () => { @@ -117,6 +140,12 @@ export const JobCard: React.FC = ({ {deadline} )} + {discoveredAt && ( + + + Discovered {discoveredAt} + + )} {job.salary && ( diff --git a/orchestrator/src/client/components/JobTable.tsx b/orchestrator/src/client/components/JobTable.tsx index b9fa0ce..0c15cd2 100644 --- a/orchestrator/src/client/components/JobTable.tsx +++ b/orchestrator/src/client/components/JobTable.tsx @@ -80,14 +80,22 @@ const defaultSortDirection: Record = { discoveredAt: "desc", }; -const formatDate = (dateStr: string | null) => { +const formatDateTime = (dateStr: string | null) => { if (!dateStr) return null; try { - return new Date(dateStr).toLocaleDateString("en-GB", { + const normalized = dateStr.includes("T") ? dateStr : dateStr.replace(" ", "T"); + const parsed = new Date(normalized); + if (Number.isNaN(parsed.getTime())) return dateStr; + const date = parsed.toLocaleDateString("en-GB", { day: "numeric", month: "short", year: "numeric", }); + const time = parsed.toLocaleTimeString("en-GB", { + hour: "2-digit", + minute: "2-digit", + }); + return `${date} ${time}`; } catch { return dateStr; } @@ -272,7 +280,7 @@ export const JobTable: React.FC = ({ - {formatDate(job.discoveredAt)} + {formatDateTime(job.discoveredAt)} diff --git a/orchestrator/src/client/pages/OrchestratorPage.tsx b/orchestrator/src/client/pages/OrchestratorPage.tsx index d7a2045..fe42348 100644 --- a/orchestrator/src/client/pages/OrchestratorPage.tsx +++ b/orchestrator/src/client/pages/OrchestratorPage.tsx @@ -8,6 +8,7 @@ import { Calendar, CheckCircle2, ChevronDown, + Clock, Copy, DollarSign, ExternalLink, @@ -154,6 +155,27 @@ const formatDate = (dateStr: string | null) => { } }; +const formatDateTime = (dateStr: string | null) => { + if (!dateStr) return null; + try { + const normalized = dateStr.includes("T") ? dateStr : dateStr.replace(" ", "T"); + const parsed = new Date(normalized); + if (Number.isNaN(parsed.getTime())) return dateStr; + const date = parsed.toLocaleDateString("en-GB", { + day: "numeric", + month: "short", + year: "numeric", + }); + const time = parsed.toLocaleTimeString("en-GB", { + hour: "2-digit", + minute: "2-digit", + }); + return `${date} ${time}`; + } catch { + return dateStr; + } +}; + const dateValue = (value: string | null) => { if (!value) return null; const parsed = Date.parse(value); @@ -494,6 +516,7 @@ export const OrchestratorPage: React.FC = () => { const selectedJobLink = selectedJob ? selectedJob.applicationLink || selectedJob.jobUrl : "#"; const selectedPdfHref = selectedJob ? `/pdfs/resume_${selectedJob.id}.pdf` : "#"; const selectedDeadline = selectedJob ? formatDate(selectedJob.deadline) : null; + const selectedDiscoveredAt = selectedJob ? formatDateTime(selectedJob.discoveredAt) : null; const canApply = selectedJob?.status === "ready"; const canProcess = selectedJob ? ["discovered", "ready"].includes(selectedJob.status) : false; const canReject = selectedJob ? ["discovered", "ready"].includes(selectedJob.status) : false; @@ -771,6 +794,12 @@ export const OrchestratorPage: React.FC = () => { {formatDate(job.deadline)} )} + {job.discoveredAt && ( + + + Discovered {formatDateTime(job.discoveredAt)} + + )}
@@ -820,6 +849,12 @@ export const OrchestratorPage: React.FC = () => { {selectedDeadline} )} + {selectedDiscoveredAt && ( + + + Discovered {selectedDiscoveredAt} + + )} {selectedJob.salary && (