diff --git a/src/features/company-jobs/api/jobs.api.ts b/src/features/company-jobs/api/jobs.api.ts index 9c942fd3..747e2519 100644 --- a/src/features/company-jobs/api/jobs.api.ts +++ b/src/features/company-jobs/api/jobs.api.ts @@ -102,10 +102,14 @@ export async function fetchJobs( ): Promise { const query = new URLSearchParams(); - if (params?.pageIndex || params?.page) - query.set("page", String(params.page ?? params.pageIndex)); - if (params?.perPage || params?.per_page) - query.set("per_page", String(params.per_page ?? params.perPage)); + const page = params?.pageIndex ?? params?.page; + if (page !== undefined) query.set("pageIndex", String(page)); + + const perPage = params?.perPage ?? params?.per_page; + if (perPage !== undefined) { + query.set("perPage", String(perPage)); + query.set("per_page", String(perPage)); + } if (params?.search?.trim()) query.set("search", params.search.trim()); if (params?.sortBy || params?.sort_by) query.set("sort_by", (params.sort_by ?? params.sortBy) as string); diff --git a/src/features/company-jobs/hooks/use-job-applicants.ts b/src/features/company-jobs/hooks/use-job-applicants.ts index 244ce8ae..99fed040 100644 --- a/src/features/company-jobs/hooks/use-job-applicants.ts +++ b/src/features/company-jobs/hooks/use-job-applicants.ts @@ -29,11 +29,15 @@ export function useJobApplicants( pageIndex?: number; perPage?: number; }, + options?: { + enabled?: boolean; + }, ) { return useQuery({ queryKey: JOB_APPLICANTS_KEYS.list(jobId, params), queryFn: () => fetchJobApplicants(jobId, params), refetchOnWindowFocus: false, + enabled: options?.enabled ?? true, }); } diff --git a/src/features/company-jobs/schemas/jobs.schema.ts b/src/features/company-jobs/schemas/jobs.schema.ts index 11d2d3e7..0e7fc8df 100644 --- a/src/features/company-jobs/schemas/jobs.schema.ts +++ b/src/features/company-jobs/schemas/jobs.schema.ts @@ -95,6 +95,11 @@ export const JobSchema = z.object({ if (typeof v === "boolean") return v; return null; }), + applicant_count: z.number().optional().nullable(), + applications_count: z.number().optional().nullable(), + total_applicants: z.number().optional().nullable(), + applicantCount: z.number().optional().nullable(), + applicationsCount: z.number().optional().nullable(), }); export const PaginationSchema = z @@ -154,48 +159,22 @@ export const JobsListDataSchema = z .transform((v) => v ?? ""), data: z.array(JobSchema).nullish(), jobs: z.array(JobSchema).nullish(), - pagination: z - .object({ - count: z - .number() - .nullish() - .transform((v) => v ?? 0), - total_pages: z - .number() - .nullish() - .transform((v) => v ?? 1), - current_page: z - .number() - .nullish() - .transform((v) => v ?? 1), - per_page: z - .number() - .nullish() - .transform((v) => v ?? 10), - next: z.string().nullable().optional(), - previous: z.string().nullable().optional(), - }) - .passthrough() - .optional() - .transform((v) => ({ - count: v?.count ?? 0, - totalPages: v?.total_pages ?? 1, - isNext: !!v?.next, - isPrev: !!v?.previous, - nextPage: v?.next ? (v.current_page ?? 1) + 1 : null, - })), + pagination: PaginationSchema.nullish().transform( + (v) => + v ?? { + count: 0, + totalPages: 1, + isNext: false, + isPrev: false, + nextPage: null, + }, + ), }) .transform((val) => ({ company_id: val.company_id, company_name: val.company_name, jobs: val.jobs ?? val.data ?? [], - pagination: val.pagination ?? { - count: 0, - totalPages: 1, - isNext: false, - isPrev: false, - nextPage: null, - }, + pagination: val.pagination, })); export const JobsListResponseSchema = DjangoResponse(JobsListDataSchema); diff --git a/src/features/company-jobs/types/jobs.types.ts b/src/features/company-jobs/types/jobs.types.ts index 92d56e37..8fffe0a8 100644 --- a/src/features/company-jobs/types/jobs.types.ts +++ b/src/features/company-jobs/types/jobs.types.ts @@ -52,6 +52,11 @@ export interface Job { deliverables?: string[] | string | null; stipend?: string | null; certificate_provided?: boolean | null; + applicant_count?: number | null; + applications_count?: number | null; + total_applicants?: number | null; + applicantCount?: number | null; + applicationsCount?: number | null; } export interface Pagination { diff --git a/src/features/home/components/company/active-job-listings-card.tsx b/src/features/home/components/company/active-job-listings-card.tsx index c9be89c7..f1224224 100644 --- a/src/features/home/components/company/active-job-listings-card.tsx +++ b/src/features/home/components/company/active-job-listings-card.tsx @@ -12,8 +12,7 @@ import Link from "next/link"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Skeleton } from "@/components/ui/skeleton"; -import { useJobs } from "@/features/company-jobs/hooks/use-jobs"; -import type { Job } from "@/features/company-jobs/types"; +import { type Job, useJobApplicants, useJobs } from "@/features/company-jobs"; import { cn } from "@/lib/utils"; const STATUS_STYLES: Record = { @@ -24,6 +23,27 @@ const STATUS_STYLES: Record = { function JobRow({ job }: { job: Job }) { const statusStyle = STATUS_STYLES[job.status] ?? STATUS_STYLES.Draft; + + const embeddedCount = + job.applicant_count ?? + job.applications_count ?? + job.total_applicants ?? + job.applicantCount ?? + job.applicationsCount; + + const hasEmbeddedCount = + embeddedCount !== undefined && embeddedCount !== null; + + const { data: applicantData } = useJobApplicants( + job.id, + { perPage: 1 }, + { enabled: !hasEmbeddedCount }, + ); + + const applicantCount = hasEmbeddedCount + ? embeddedCount + : (applicantData?.pagination.count ?? 0); + return (
-

0

+

{applicantCount}

applicants