From 06eeae4f5eee4fbccee73c66e065fe66b651c5aa Mon Sep 17 00:00:00 2001 From: Mark McGuire Date: Thu, 29 May 2025 19:27:20 -0700 Subject: [PATCH 1/9] feat: fixed job limiting for admin requests --- src/app/admin/page.tsx | 6 ++++-- src/app/api/jobs/route.ts | 9 ++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx index 6bb7b38..5c63b26 100644 --- a/src/app/admin/page.tsx +++ b/src/app/admin/page.tsx @@ -29,7 +29,7 @@ export default function AdminJobs() { const fetchData = async () => { try { - const response = await fetch("/api/jobs"); + const response = await fetch("/api/jobs?admin=true"); const result: IJob[] = await response.json(); //const result: IJob[] = []; @@ -38,7 +38,9 @@ export default function AdminJobs() { // Fetch all job statuses in parallel const jobStatuses = ["pending", "approved", "rejected", "expired"]; - const responses = await Promise.all(jobStatuses.map((status) => fetch(`/api/jobs?jobStatus=${status}`))); + const responses = await Promise.all( + jobStatuses.map((status) => fetch(`/api/jobs?jobStatus=${status}&admin=true`)), + ); const [incomingData, liveData, completeData, expiredData] = await Promise.all(responses.map((res) => res.json())); diff --git a/src/app/api/jobs/route.ts b/src/app/api/jobs/route.ts index 002714e..414821d 100644 --- a/src/app/api/jobs/route.ts +++ b/src/app/api/jobs/route.ts @@ -14,9 +14,12 @@ export const GET = withApiAuth( await connectDB(); const { searchParams } = new URL(req.url); - const page = Math.max(parseInt(searchParams.get("page") || "1", 10), 1); - const limit = Math.max(parseInt(searchParams.get("limit") || "10", 10), 1); - const skip = (page - 1) * limit; // This will always be >= 0 + const isAdminRequest = searchParams.get("admin") === "true"; + + // Only apply pagination for non-admin requests + const page = isAdminRequest ? 1 : Math.max(parseInt(searchParams.get("page") || "1", 10), 1); + const limit = isAdminRequest ? 0 : Math.max(parseInt(searchParams.get("limit") || "10", 10), 1); + const skip = isAdminRequest ? 0 : (page - 1) * limit; // This will always be >= 0 // Filter parameters const employmentFilters = searchParams.getAll("employmentType"); From 3876302ad5e90ac9bce87190b72cf506fa03d4fe Mon Sep 17 00:00:00 2001 From: Mark McGuire Date: Thu, 29 May 2025 19:36:09 -0700 Subject: [PATCH 2/9] feat: added renew job button and associated endpoint suppport --- src/app/api/jobs/[jobId]/route.ts | 18 +++++++++++-- src/components/JobCard/OrgCard.tsx | 41 +++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/app/api/jobs/[jobId]/route.ts b/src/app/api/jobs/[jobId]/route.ts index 8263ced..662c9d7 100644 --- a/src/app/api/jobs/[jobId]/route.ts +++ b/src/app/api/jobs/[jobId]/route.ts @@ -49,7 +49,7 @@ export const PUT = withApiAuth( const jobId = req.nextUrl.pathname.split("/").pop(); const requestData = await req.json(); - const { previousStatus, newStatus, ...jobData } = requestData; + const { previousStatus, newStatus, isRenewal, ...jobData } = requestData; // Handle both cases - with and without status transition data const hasStatusTransition = previousStatus !== undefined && newStatus !== undefined; @@ -76,6 +76,20 @@ export const PUT = withApiAuth( return NextResponse.json({ error: "Insufficient permissions to update this job" }, { status: 403 }); } + // Handle job renewal + if (isRenewal) { + const updatedJob = await Job.findByIdAndUpdate( + jobId, + { + jobStatus: JobStatus.approved, + approvedDate: new Date(), + modifiedDate: new Date(), + }, + { new: true }, + ); + return NextResponse.json({ message: "Job renewed successfully", job: updatedJob }); + } + const updatedJob = { ...jobData, jobStatus: hasStatusTransition @@ -92,7 +106,7 @@ export const PUT = withApiAuth( await Job.findByIdAndUpdate(jobId, updatedJob, { new: true }); return NextResponse.json({ message: "Job updated successfully" }); - } catch (error: any) { + } catch (error) { console.error("PUT Error:", error); return NextResponse.json({ message: "Error updating job: ", error }, { status: 500 }); } diff --git a/src/components/JobCard/OrgCard.tsx b/src/components/JobCard/OrgCard.tsx index 801c9fb..b7da4d2 100644 --- a/src/components/JobCard/OrgCard.tsx +++ b/src/components/JobCard/OrgCard.tsx @@ -16,7 +16,7 @@ import { useDisclosure, Text, } from "@chakra-ui/react"; -import { FiEdit, FiMessageSquare } from "react-icons/fi"; +import { FiEdit, FiMessageSquare, FiRefreshCw } from "react-icons/fi"; import { useRouter } from "next/navigation"; import JobDateInfo, { JobDateKind } from "./JobDateInfo"; import { isMoreThanThirtyDaysAgo } from "@/lib/utils"; @@ -63,6 +63,32 @@ export const OrgCard = forwardRef( router.push(`/jobform?jobId=${job._id}&returnURL=/dashboard`); } + async function handleRenewJob(e: React.ChangeEvent) { + e.preventDefault(); + try { + const response = await fetch(`/api/jobs/${job._id}`, { + method: "PUT", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + isRenewal: true, + previousStatus: job.jobStatus, + newStatus: "approved", + }), + }); + + if (!response.ok) { + throw new Error("Failed to renew job"); + } + + // Refresh the page to show updated status + window.location.reload(); + } catch (error) { + console.error("Error renewing job:", error); + } + } + return ( <>
( )}
+ {isActuallyExpired && ( + + )}