show disvoery date
This commit is contained in:
parent
2b2af06bb8
commit
585e5e19e0
@ -6,6 +6,7 @@ import React from "react";
|
|||||||
import {
|
import {
|
||||||
Calendar,
|
Calendar,
|
||||||
CheckCircle2,
|
CheckCircle2,
|
||||||
|
Clock,
|
||||||
Copy,
|
Copy,
|
||||||
DollarSign,
|
DollarSign,
|
||||||
Download,
|
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, "_");
|
const safeFilenamePart = (value: string) => value.replace(/[^a-z0-9]/gi, "_");
|
||||||
|
|
||||||
export const JobCard: React.FC<JobCardProps> = ({
|
export const JobCard: React.FC<JobCardProps> = ({
|
||||||
@ -75,6 +97,7 @@ export const JobCard: React.FC<JobCardProps> = ({
|
|||||||
const jobLink = job.applicationLink || job.jobUrl;
|
const jobLink = job.applicationLink || job.jobUrl;
|
||||||
const pdfHref = `/pdfs/resume_${job.id}.pdf`;
|
const pdfHref = `/pdfs/resume_${job.id}.pdf`;
|
||||||
const deadline = formatDate(job.deadline);
|
const deadline = formatDate(job.deadline);
|
||||||
|
const discoveredAt = formatDateTime(job.discoveredAt);
|
||||||
const isHighlighted = highlightedJobId === job.id;
|
const isHighlighted = highlightedJobId === job.id;
|
||||||
|
|
||||||
const handleCopyInfo = async () => {
|
const handleCopyInfo = async () => {
|
||||||
@ -117,6 +140,12 @@ export const JobCard: React.FC<JobCardProps> = ({
|
|||||||
{deadline}
|
{deadline}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
{discoveredAt && (
|
||||||
|
<span className="flex items-center gap-1">
|
||||||
|
<Clock className="h-4 w-4" />
|
||||||
|
Discovered {discoveredAt}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
{job.salary && (
|
{job.salary && (
|
||||||
<span className="flex items-center gap-1">
|
<span className="flex items-center gap-1">
|
||||||
<DollarSign className="h-4 w-4" />
|
<DollarSign className="h-4 w-4" />
|
||||||
|
|||||||
@ -80,14 +80,22 @@ const defaultSortDirection: Record<JobSortKey, JobSortDirection> = {
|
|||||||
discoveredAt: "desc",
|
discoveredAt: "desc",
|
||||||
};
|
};
|
||||||
|
|
||||||
const formatDate = (dateStr: string | null) => {
|
const formatDateTime = (dateStr: string | null) => {
|
||||||
if (!dateStr) return null;
|
if (!dateStr) return null;
|
||||||
try {
|
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",
|
day: "numeric",
|
||||||
month: "short",
|
month: "short",
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
});
|
});
|
||||||
|
const time = parsed.toLocaleTimeString("en-GB", {
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit",
|
||||||
|
});
|
||||||
|
return `${date} ${time}`;
|
||||||
} catch {
|
} catch {
|
||||||
return dateStr;
|
return dateStr;
|
||||||
}
|
}
|
||||||
@ -272,7 +280,7 @@ export const JobTable: React.FC<JobTableProps> = ({
|
|||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
<TableCell className="tabular-nums text-muted-foreground">
|
<TableCell className="tabular-nums text-muted-foreground">
|
||||||
{formatDate(job.discoveredAt)}
|
{formatDateTime(job.discoveredAt)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
<TableCell className="pr-3 text-right">
|
<TableCell className="pr-3 text-right">
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import {
|
|||||||
Calendar,
|
Calendar,
|
||||||
CheckCircle2,
|
CheckCircle2,
|
||||||
ChevronDown,
|
ChevronDown,
|
||||||
|
Clock,
|
||||||
Copy,
|
Copy,
|
||||||
DollarSign,
|
DollarSign,
|
||||||
ExternalLink,
|
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) => {
|
const dateValue = (value: string | null) => {
|
||||||
if (!value) return null;
|
if (!value) return null;
|
||||||
const parsed = Date.parse(value);
|
const parsed = Date.parse(value);
|
||||||
@ -494,6 +516,7 @@ export const OrchestratorPage: React.FC = () => {
|
|||||||
const selectedJobLink = selectedJob ? selectedJob.applicationLink || selectedJob.jobUrl : "#";
|
const selectedJobLink = selectedJob ? selectedJob.applicationLink || selectedJob.jobUrl : "#";
|
||||||
const selectedPdfHref = selectedJob ? `/pdfs/resume_${selectedJob.id}.pdf` : "#";
|
const selectedPdfHref = selectedJob ? `/pdfs/resume_${selectedJob.id}.pdf` : "#";
|
||||||
const selectedDeadline = selectedJob ? formatDate(selectedJob.deadline) : null;
|
const selectedDeadline = selectedJob ? formatDate(selectedJob.deadline) : null;
|
||||||
|
const selectedDiscoveredAt = selectedJob ? formatDateTime(selectedJob.discoveredAt) : null;
|
||||||
const canApply = selectedJob?.status === "ready";
|
const canApply = selectedJob?.status === "ready";
|
||||||
const canProcess = selectedJob ? ["discovered", "ready"].includes(selectedJob.status) : false;
|
const canProcess = selectedJob ? ["discovered", "ready"].includes(selectedJob.status) : false;
|
||||||
const canReject = 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)}
|
{formatDate(job.deadline)}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
{job.discoveredAt && (
|
||||||
|
<span className="flex items-center gap-1">
|
||||||
|
<Clock className="h-3.5 w-3.5" />
|
||||||
|
Discovered {formatDateTime(job.discoveredAt)}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col items-end gap-2">
|
<div className="flex flex-col items-end gap-2">
|
||||||
@ -820,6 +849,12 @@ export const OrchestratorPage: React.FC = () => {
|
|||||||
{selectedDeadline}
|
{selectedDeadline}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
{selectedDiscoveredAt && (
|
||||||
|
<span className="flex items-center gap-1">
|
||||||
|
<Clock className="h-3.5 w-3.5" />
|
||||||
|
Discovered {selectedDiscoveredAt}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
{selectedJob.salary && (
|
{selectedJob.salary && (
|
||||||
<span className="flex items-center gap-1">
|
<span className="flex items-center gap-1">
|
||||||
<DollarSign className="h-3.5 w-3.5" />
|
<DollarSign className="h-3.5 w-3.5" />
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user