From 9a4d6966d0116649b92c24cc513c490e9e40c3c1 Mon Sep 17 00:00:00 2001 From: Eugene Fox Date: Sun, 11 May 2025 17:21:53 +0000 Subject: [PATCH] feat: ATS-compliant resume download links --- .env.development | 3 ++- app/resume/download/route.ts | 12 ++++++++---- app/resume/page.module.scss | 10 ++++++++++ app/resume/page.tsx | 23 +++++++++++++++-------- 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/.env.development b/.env.development index 2a77d2c..cbc28d5 100644 --- a/.env.development +++ b/.env.development @@ -11,7 +11,8 @@ SMTP_TO_EMAIL=email # Email to which emails will be sent DOMAIN_NAME=example.com # Your domain name RESUME_URL=URL # Location of the resume PDF -RESUME_HAS_REFS=false # Appends last page of the resume to a result PDF file +ATS_RESUME_URL=URL # Location of the ATS-compatible resume PDF (optional, remove to disable) +RESUME_HAS_REFS=false # Appends last page of the resume to a result PDF file (only appies to non-ATS version) ALERT_TEXT_URL=URL # URL of a txt file with urgent message to be displayed (see app/_components/AlertMessage.tsx) CLARITY_ID=string # Clarity Analytics ID (optional, remove to disable) CLARITY_CONSENT=1 # 1 if you need to request explicit consent from user, 0 if not (requires CLARITY_ID) diff --git a/app/resume/download/route.ts b/app/resume/download/route.ts index e7cc43b..78994f9 100644 --- a/app/resume/download/route.ts +++ b/app/resume/download/route.ts @@ -5,18 +5,22 @@ import { PDFDocument, PDFPage } from "pdf-lib"; export async function GET(req: NextRequest): Promise { const type: string | null = req.nextUrl.searchParams.get("type"); + const isAts: boolean = req.nextUrl.searchParams.get("ats") === "true"; const resume: Resume | undefined = findResume(type); + const url: string | undefined = isAts ? process.env.ATS_RESUME_URL : process.env.RESUME_URL; if (!resume) return error(400, "'type' parameter is invalid"); - if (!process.env.RESUME_URL) + const fileName: string = (isAts ? "(ATS) " + resume.fileName : resume.fileName).replaceAll("\"", "'"); + + if (!url) return error(500, "Cannot find file location."); try { // Fetch the PDF file from the remote URL using the fetch API - const response: Response = await fetch(process.env.RESUME_URL as string); + const response: Response = await fetch(url); if (!response.ok) return error(500, "Failed to fetch PDF file"); @@ -30,7 +34,7 @@ export async function GET(req: NextRequest): Promise const [page, refs]: PDFPage[] = await newDoc.copyPages(srcDoc, [resume.pageIndex, srcDoc.getPageCount() - 1]); newDoc.addPage(page); - if (process.env.RESUME_HAS_REFS === "true") + if (process.env.RESUME_HAS_REFS === "true" && isAts) newDoc.addPage(refs); // Serialize the new PDF document @@ -43,7 +47,7 @@ export async function GET(req: NextRequest): Promise // Set response headers for PDF file headers: { "Content-Type": "application/pdf", - "Content-Disposition": `inline; filename="${resume.fileName.replaceAll("\"", "'")}.pdf"` + "Content-Disposition": `inline; filename="${fileName}.pdf"` } } ); diff --git a/app/resume/page.module.scss b/app/resume/page.module.scss index a06760b..0626bca 100644 --- a/app/resume/page.module.scss +++ b/app/resume/page.module.scss @@ -20,6 +20,16 @@ grid-auto-columns: 1fr; gap: $spacingXL; + .buttonContainer + { + @include flex(column); + } + + .atsLink + { + @include body1(); + } + .button { flex-flow: column; diff --git a/app/resume/page.tsx b/app/resume/page.tsx index 935fc2d..8058b63 100644 --- a/app/resume/page.tsx +++ b/app/resume/page.tsx @@ -21,15 +21,22 @@ const ResumePage: React.FC = () => (

Who are you looking for?

{ resumeList.map(i => - + { i.label } + + { process.env.ATS_RESUME_URL && + + ATS-compatible version + + } +
) }