From dd419244ca98c7ecc03daf26b6979713a6f260f1 Mon Sep 17 00:00:00 2001 From: Paribesh Nepal Date: Sun, 3 Nov 2024 04:40:34 +0530 Subject: [PATCH] feat:added usequery --- package.json | 1 + src/actions/job.action.ts | 20 ++++- src/app/jobs/[id]/page.tsx | 109 +++++++++++++++------------ src/app/jobs/page.tsx | 66 ++++++++++------ src/components/RecommendJobs.tsx | 34 +++++++++ src/components/all-jobs.tsx | 28 ++++--- src/components/job.tsx | 21 +++++- src/lib/validators/jobs.validator.ts | 1 - src/providers/providers.tsx | 29 ++++--- src/providers/queryClient.ts | 20 +++++ 10 files changed, 229 insertions(+), 100 deletions(-) create mode 100644 src/components/RecommendJobs.tsx create mode 100644 src/providers/queryClient.ts diff --git a/package.json b/package.json index 2a7f56c0..f96da66f 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "@radix-ui/react-switch": "^1.1.0", "@radix-ui/react-toast": "^1.2.1", "@t3-oss/env-nextjs": "^0.11.1", + "@tanstack/react-query": "^5.59.17", "@types/lodash": "^4.17.7", "@types/uuid": "^10.0.0", "@uidotdev/usehooks": "^2.4.1", diff --git a/src/actions/job.action.ts b/src/actions/job.action.ts index b3b15ade..ec8494be 100644 --- a/src/actions/job.action.ts +++ b/src/actions/job.action.ts @@ -188,9 +188,25 @@ export const getRecommendedJobs = withServerActionAsyncCatcher< ServerActionReturnType >(async (data) => { const result = RecommendedJobSchema.parse(data); - const { id, category } = result; + const { id } = result; + + const job = await prisma.job.findUnique({ + where: { id }, // Ensure params.id is available + select: { + id: true, + category: true, + // Add any other fields you need from the job + }, + }); + + if (!job) { + throw new Error('Job not found'); + } + + // Use the category from the fetched job + const { category } = job; - // fettching the latest three jobs excluding the current job and in the same category + // Fetch the latest three jobs excluding the current job and in the same category const jobs = await prisma.job.findMany({ where: { category: category, diff --git a/src/app/jobs/[id]/page.tsx b/src/app/jobs/[id]/page.tsx index e34810b3..887b4d45 100644 --- a/src/app/jobs/[id]/page.tsx +++ b/src/app/jobs/[id]/page.tsx @@ -1,62 +1,77 @@ import { getJobById, getRecommendedJobs } from '@/actions/job.action'; import { Job } from '@/components/job'; -import JobCard from '@/components/job-card-rec'; import { JobByIdSchemaType } from '@/lib/validators/jobs.validator'; +import { HydrationBoundary, dehydrate } from '@tanstack/react-query'; import { ArrowLeft } from 'lucide-react'; import Link from 'next/link'; -import { redirect } from 'next/navigation'; +import getQueryClient from '../../../providers/queryClient'; +import { RecommendJobs } from '@/components/RecommendJobs'; const page = async ({ params }: { params: JobByIdSchemaType }) => { - const job = await getJobById(params); - if (!job.status) { - return; - } - - const jobDetail = job.additional?.job; - if (!jobDetail) { - return redirect('/jobs'); - } - - const curatedJobs = await getRecommendedJobs({ - id: jobDetail.id, - category: jobDetail.category, + const queryClient = getQueryClient(); + + await queryClient.prefetchQuery({ + queryKey: ['jobs', params], + queryFn: () => getJobById({ id: params.id }), + staleTime: 1000 * 60 * 5, + }); + + await queryClient.prefetchQuery({ + queryKey: ['RecommendedJobs', params], + queryFn: () => getRecommendedJobs({ id: params.id }), + staleTime: 1000 * 60 * 5, }); - if (!curatedJobs.status) { - return; - } + // const job = await getJobById(params); + // if (!job.status) { + // return; + // } + + // const jobDetail = job.additional?.job; + // if (!jobDetail) { + // return redirect('/jobs'); + // } - const recommendedJobs = curatedJobs.additional?.jobs; + // const curatedJobs = await getRecommendedJobs({ + // id: jobDetail.id, + // category: jobDetail.category, + // }); + + // if (!curatedJobs.status) { + // return; + // } + + // const recommendedJobs = curatedJobs.additional?.jobs; return ( -
-
- - -

Back to All Jobs

- -
-
- {/* the particular job details */} - - - {/* job recommendations */} - -
-
+ +
+
+ + +

Back to All Jobs

+ +
+
+ {/* the particular job details */} + + + + {/* job recommendations */} + +
+
+
); }; diff --git a/src/app/jobs/page.tsx b/src/app/jobs/page.tsx index 3dfd3077..924c1115 100644 --- a/src/app/jobs/page.tsx +++ b/src/app/jobs/page.tsx @@ -8,6 +8,9 @@ import { } from '@/lib/validators/jobs.validator'; import { redirect } from 'next/navigation'; import { Suspense } from 'react'; +import getQueryClient from '../../providers/queryClient'; +import { GetUserBookmarksId, getAllJobs } from '@/actions/job.action'; +import { HydrationBoundary, dehydrate } from '@tanstack/react-query'; const page = async ({ searchParams }: { searchParams: JobQuerySchemaType }) => { const parsedData = JobQuerySchema.safeParse(searchParams); @@ -16,34 +19,49 @@ const page = async ({ searchParams }: { searchParams: JobQuerySchemaType }) => { redirect('/jobs'); } const parsedSearchParams = parsedData.data; + + const queryClient = getQueryClient(); + + await queryClient.prefetchQuery({ + queryKey: ['jobs', parsedSearchParams], + queryFn: () => getAllJobs(parsedSearchParams), + staleTime: 1000 * 60 * 5, + }); + const UserBookmarks = await GetUserBookmarksId(); + return ( -
-
-

Explore Jobs

-

- Explore thousands of remote and onsite jobs that match your skills and - aspirations. -

-
-
-
- + +
+
+

Explore Jobs

+

+ Explore thousands of remote and onsite jobs that match your skills + and aspirations. +

-
- - - -
- } - > - - +
+
+ +
+
+ + + +
+ } + > + + +
-
+ ); }; diff --git a/src/components/RecommendJobs.tsx b/src/components/RecommendJobs.tsx new file mode 100644 index 00000000..573999b1 --- /dev/null +++ b/src/components/RecommendJobs.tsx @@ -0,0 +1,34 @@ +'use client'; +import { getRecommendedJobs } from '@/actions/job.action'; +import { useQuery } from '@tanstack/react-query'; +import JobCard from './Jobcard'; +import { useParams } from 'next/navigation'; + +export const RecommendJobs = ({ jobId }: { jobId: string }) => { + const params = useParams(); + const { data } = useQuery({ + queryKey: ['RecommendedJobs', params], + queryFn: () => getRecommendedJobs({ id: jobId }), + staleTime: 1000 * 60 * 5, + }); + + if (!data?.status) { + return
Error
; + } + const recommendedJobs = data?.additional?.jobs; + + return ( +
+ {recommendedJobs && + recommendedJobs.map((job, index) => { + return ( + + ); + })} +
+ ); +}; diff --git a/src/components/all-jobs.tsx b/src/components/all-jobs.tsx index 4a5f8f2c..45827afd 100644 --- a/src/components/all-jobs.tsx +++ b/src/components/all-jobs.tsx @@ -1,4 +1,5 @@ -import { getAllJobs, GetUserBookmarksId } from '@/actions/job.action'; +'use client'; +import { getAllJobs } from '@/actions/job.action'; import { DEFAULT_PAGE, JOBS_PER_PAGE } from '@/config/app.config'; import { Card, CardContent, CardHeader, CardTitle } from './ui/card'; import { JobQuerySchemaType } from '@/lib/validators/jobs.validator'; @@ -10,31 +11,34 @@ import { Pagination, PaginationContent, PaginationItem } from './ui/pagination'; import { PaginationPages } from './ui/paginator'; import JobCard from './Jobcard'; import APP_PATHS from '@/config/path.config'; +import { useQuery } from '@tanstack/react-query'; type PaginatorProps = { searchParams: JobQuerySchemaType; + userbookmarks: { jobId: string }[] | null; }; -const AllJobs = async ({ searchParams }: PaginatorProps) => { - const [jobs, getUserBookmarks] = await Promise.all([ - await getAllJobs(searchParams), - await GetUserBookmarksId(), - ]); +const AllJobs = ({ searchParams, userbookmarks }: PaginatorProps) => { + const userbookmarkArr: { jobId: string }[] | null = userbookmarks; - const userbookmarkArr: { jobId: string }[] | null = getUserBookmarks.data; - - if (!jobs.status || !jobs.additional) { - return
Error {jobs.message}
; + const { data } = useQuery({ + queryKey: ['jobs', searchParams], + queryFn: () => getAllJobs(searchParams), + staleTime: 1000 * 60 * 5, + }); + if (!data?.status || !data?.additional) { + return
Error {data?.message}
; } + const jobs = data; const totalPages = Math.ceil((jobs.additional?.totalJobs || 0) / JOBS_PER_PAGE) || DEFAULT_PAGE; const currentPage = parseInt(searchParams.page?.toString()) || DEFAULT_PAGE; - + const jobsLength = jobs.additional?.jobs.length || 0; // Defaults to 0 if undefined return (
- {jobs.additional.jobs.length > 0 ? ( + {jobsLength > 0 ? ( jobs.additional?.jobs.map((job, index) => ( { +export const Job = () => { + const params = useParams(); + const id: any = params.id; + const { data } = useQuery({ + queryKey: ['jobs', { id }], + queryFn: () => getJobById({ id }), + staleTime: 1000 * 60 * 5, + }); + if (!data?.status) { + return
Error
; + } + const job = data?.additional?.job; + if (!job) { + return
Error
; + } + return (