import { prisma } from "@/lib/db"; import { notFound } from "next/navigation"; import Link from "next/link"; import JobActions from "./job-actions"; export const dynamic = "force-dynamic"; function getCompanyColor(name: string) { const colors = [ "bg-indigo-100 text-indigo-700 border-indigo-200 dark:bg-indigo-950/80 dark:text-indigo-300 dark:border-indigo-800", "bg-violet-100 text-violet-700 border-violet-200 dark:bg-violet-950/80 dark:text-violet-300 dark:border-violet-800", "bg-blue-100 text-blue-700 border-blue-200 dark:bg-blue-950/80 dark:text-blue-300 dark:border-blue-800", "bg-emerald-100 text-emerald-700 border-emerald-200 dark:bg-emerald-950/80 dark:text-emerald-300 dark:border-emerald-800", "bg-amber-100 text-amber-700 border-amber-200 dark:bg-amber-950/80 dark:text-amber-300 dark:border-amber-800", "bg-rose-100 text-rose-700 border-rose-200 dark:bg-rose-950/80 dark:text-rose-300 dark:border-rose-800", "bg-teal-100 text-teal-700 border-teal-200 dark:bg-teal-950/80 dark:text-teal-300 dark:border-teal-800", "bg-cyan-100 text-cyan-700 border-cyan-200 dark:bg-cyan-950/80 dark:text-cyan-300 dark:border-cyan-800", ]; let hash = 0; for (let i = 0; i < (name || "").length; i++) { hash = name.charCodeAt(i) + ((hash << 5) - hash); } return colors[Math.abs(hash) % colors.length]; } function getInitials(name: string) { if (!name) return "?"; const parts = name.trim().split(/\s+/); if (parts.length >= 2) { return (parts[0][0] + parts[1][0]).toUpperCase(); } return name.slice(0, 2).toUpperCase(); } function formatCompensation(j: { payMin: number | null; payMax: number | null; payCurrency: string | null; payPeriod: string | null }) { if (!j.payMin && !j.payMax) return null; const cur = j.payCurrency === "PHP" ? "₱" : "$"; const per = j.payPeriod === "hour" ? "/hr" : j.payPeriod === "month" ? "/mo" : j.payPeriod === "year" ? "/yr" : ""; const fmt = (n: number) => (n >= 1000 ? `${Math.round(n / 1000)}k` : `${n}`); return `${cur}${fmt(j.payMin ?? 0)}${j.payMax ? ` – ${fmt(j.payMax)}` : ""}${per}`; } export default async function JobDetail({ params }: { params: Promise<{ id: string }> }) { const { id } = await params; const job = await prisma.job.findUnique({ where: { id }, include: { resumes: { orderBy: { updatedAt: "desc" } }, coverLetters: { orderBy: { updatedAt: "desc" } }, applications: { orderBy: { updatedAt: "desc" } }, }, }); if (!job) notFound(); const comp = formatCompensation(job); const companyColor = getCompanyColor(job.company); const initials = getInitials(job.company); return (
{/* Breadcrumb & Top Bar */}
Back to Jobs {/* Main Header Card */}
{initials}

{job.title}

{job.company} · {job.location ?? "Remote"} {job.remoteType && ( <> · {job.remoteType} )}
{/* Badges & Meta */}
{job.phEligibility === "yes" ? ( PH Eligible ) : job.phEligibility === "no" ? ( Not Eligible ) : ( PH: Unclear )} {comp && ( 💰 {comp} )} {job.tags && ( 🏷️ {job.tags} )}
{/* External Links */}
{job.url && ( Listing )} {job.applyUrl && ( Apply Page )}
{/* Action Toolbar */} {/* Tailored Resumes Section */} {job.resumes.length > 0 && (

Tailored Resumes ({job.resumes.length})

{job.resumes.map((r) => (
{r.name}

{r.kind} · v{r.version}

Edit / Print →
))}
)} {/* Cover Letters Section */} {job.coverLetters.length > 0 && (

Cover Letters ({job.coverLetters.length})

{job.coverLetters.map((c) => (
{c.markdown}
))}
)} {/* Description */} {job.description && (

Job Description

{job.description}
)} {/* Requirements */} {job.requirements && (

Requirements

{job.requirements}
)} {/* Notes */} {job.notes && (

📝 Private Notes

{job.notes}

)} {/* Applications Log */} {job.applications.length > 0 && (

Application Submissions

{job.applications.map((a) => (
Method: {a.method} · {a.submittedAt ? `Submitted on ${new Date(a.submittedAt).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric", })}` : "Pending submission"}
{a.confirmation && ( Ref: {a.confirmation} )}
))}
)}
); }