diff --git a/package.json b/package.json index 64ba50e1..d1a451a5 100644 --- a/package.json +++ b/package.json @@ -24,14 +24,13 @@ "@radix-ui/react-dialog": "^1.1.1", "@radix-ui/react-dropdown-menu": "^2.1.1", "@radix-ui/react-label": "^2.1.0", + "@radix-ui/react-popover": "^1.1.1", "@radix-ui/react-radio-group": "^1.2.0", "@radix-ui/react-scroll-area": "^1.1.0", "@radix-ui/react-select": "^2.1.1", "@radix-ui/react-separator": "^1.1.0", "@radix-ui/react-slider": "^1.2.0", - "@radix-ui/react-popover": "^1.1.1", "@radix-ui/react-slot": "^1.1.0", - "dayjs": "^1.11.13", "@radix-ui/react-switch": "^1.1.0", "@radix-ui/react-toast": "^1.2.1", "@types/lodash": "^4.17.7", @@ -39,6 +38,7 @@ "bcryptjs": "^2.4.3", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", + "dayjs": "^1.11.13", "lodash": "^4.17.21", "lucide-react": "^0.426.0", "next": "14.2.5", @@ -51,6 +51,7 @@ "react-icons": "^5.2.1", "tailwind-merge": "^2.4.0", "tailwindcss-animate": "^1.0.7", + "vaul": "^0.9.1", "zod": "^3.23.8", "zod-error": "^1.5.0" }, diff --git a/src/app/jobs/page.tsx b/src/app/jobs/page.tsx index ee41d31e..1df14016 100644 --- a/src/app/jobs/page.tsx +++ b/src/app/jobs/page.tsx @@ -17,8 +17,10 @@ const page = async ({ searchParams }: { searchParams: JobQuerySchemaType }) => { } const parsedSearchParams = parsedData.data; return ( -
- +
+
+ +
{ DEFAULT_PAGE; const currentPage = parseInt(searchParams.page?.toString()) || DEFAULT_PAGE; return ( -
+
{jobs.additional?.jobs.map((job) => { return (
diff --git a/src/components/hero-section.tsx b/src/components/hero-section.tsx index 097f83c1..ef8b3dad 100644 --- a/src/components/hero-section.tsx +++ b/src/components/hero-section.tsx @@ -1,12 +1,12 @@ import { GITHUB_REPO } from '@/lib/constant/app.constant'; import Link from 'next/link'; import Icon from './ui/icon'; -import { MarqueeDemo } from './infinitescroll'; +import { LogoMarquee } from './infinitescroll'; const HeroSection = () => { return ( <> -
+
{
- + ); diff --git a/src/components/infinitescroll.tsx b/src/components/infinitescroll.tsx index 78155f28..c28e4f48 100644 --- a/src/components/infinitescroll.tsx +++ b/src/components/infinitescroll.tsx @@ -1,115 +1,32 @@ -import React from 'react'; -import Marquee from './ui/Marquee'; import Image from 'next/image'; -// import Marquee from "@/components/magicui/marquee"; - -const reviews = [ - { - name: 'Jack', - username: '@jack', - body: "I've never seen anything like this before. It's amazing. I love it.", - img: 'https://avatar.vercel.sh/jack', - }, - { - name: 'Jill', - username: '@jill', - body: "I don't know what to say. I'm speechless. This is amazing.", - img: 'https://avatar.vercel.sh/jill', - }, - { - name: 'John', - username: '@john', - body: "I'm at a loss for words. This is amazing. I love it.", - img: 'https://avatar.vercel.sh/john', - }, - { - name: 'Jane', - username: '@jane', - body: "I'm at a loss for words. This is amazing. I love it.", - img: 'https://avatar.vercel.sh/jane', - }, - { - name: 'Jenny', - username: '@jenny', - body: "I'm at a loss for words. This is amazing. I love it.", - img: 'https://avatar.vercel.sh/jenny', - }, - { - name: 'James', - username: '@james', - body: "I'm at a loss for words. This is amazing. I love it.", - img: 'https://avatar.vercel.sh/james', - }, -]; +import Marquee from './ui/Marquee'; -const imageList = [ - { - id: 1, - src: './microsoft.svg', - }, - { - id: 2, - src: './solana.svg', - }, - { - id: 3, - src: './google.svg', - }, +const logos = [ + { src: '/microsoft.svg', alt: 'Microsoft', width: 190, height: 50 }, + { src: '/google.svg', alt: 'Google', width: 140, height: 25 }, + { src: '/solana.svg', alt: 'Solana', width: 180, height: 50 }, + // Add more logos here ]; -const firstRow = reviews.slice(0, reviews.length / 2); - -const ReviewCard = ({}) => { +export function LogoMarquee() { return ( -
- {imageList.concat(imageList).map((item, index) => { - return ( - companies - ); - })} -
- ); -}; - -export function MarqueeDemo() { - return ( -
- - {firstRow.map((review) => ( - - ))} - - - {/*
-
*/} +
+
+ + {logos.map((logo) => ( +
+ {logo.alt} +
+ ))} +
+
+
+
); } - -//
-// {imageList.concat(imageList).map((item, index) => ( -// companies -// ))} -//
diff --git a/src/components/job-landing.tsx b/src/components/job-landing.tsx index 5f25702c..1149c890 100644 --- a/src/components/job-landing.tsx +++ b/src/components/job-landing.tsx @@ -6,7 +6,10 @@ import JobCardLoader from '@/components/job-card-loader'; import { DEFAULT_PAGE, JOBS_PER_PAGE } from '@/config/app.config'; import JobsHeader from '@/layouts/jobs-header'; import { Suspense } from 'react'; -import { JobQuerySchemaType } from '@/lib/validators/jobs.validator'; +import { + JobQuerySchema, + JobQuerySchemaType, +} from '@/lib/validators/jobs.validator'; import { Pagination, PaginationContent, PaginationItem } from './ui/pagination'; import { PaginationNextButton, @@ -17,6 +20,7 @@ import APP_PATHS from '@/config/path.config'; import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; +import { redirect } from 'next/navigation'; dayjs.extend(relativeTime); export const calculateTimeSincePosted = (postedAt: Date): string => { @@ -28,12 +32,18 @@ export const JobLanding = async ({ }: { searchParams: JobQuerySchemaType; }) => { + const parsedData = JobQuerySchema.safeParse(searchParams); + if (!(parsedData.success && parsedData.data)) { + console.error(parsedData.error); + redirect('/'); + } + const parsedSearchParams = parsedData.data; return ( -
-
- +
+
+ }> - +
@@ -55,12 +65,12 @@ const JobCard = async ({ searchParams }: PaginatorProps) => { DEFAULT_PAGE; const currentPage = parseInt(searchParams.page?.toString()) || DEFAULT_PAGE; return ( -
+
{jobs.additional?.jobs.map((job) => { return (
@@ -85,7 +95,6 @@ const JobCard = async ({ searchParams }: PaginatorProps) => {
- {/* {job.minSalary && } */} {job.minSalary && job.maxSalary ? `$${formatSalary(job.maxSalary)}` : 'NotDisclosed'} @@ -99,7 +108,7 @@ const JobCard = async ({ searchParams }: PaginatorProps) => { ); })} - + {totalPages ? ( ) => ( + +); +Drawer.displayName = 'Drawer'; + +const DrawerTrigger = DrawerPrimitive.Trigger; + +const DrawerPortal = DrawerPrimitive.Portal; + +const DrawerClose = DrawerPrimitive.Close; + +const DrawerOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName; + +const DrawerContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + +
+ {children} + + +)); +DrawerContent.displayName = 'DrawerContent'; + +const DrawerHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+); +DrawerHeader.displayName = 'DrawerHeader'; + +const DrawerFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+); +DrawerFooter.displayName = 'DrawerFooter'; + +const DrawerTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DrawerTitle.displayName = DrawerPrimitive.Title.displayName; + +const DrawerDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DrawerDescription.displayName = DrawerPrimitive.Description.displayName; + +export { + Drawer, + DrawerPortal, + DrawerOverlay, + DrawerTrigger, + DrawerClose, + DrawerContent, + DrawerHeader, + DrawerFooter, + DrawerTitle, + DrawerDescription, +}; diff --git a/src/layouts/footer.tsx b/src/layouts/footer.tsx index 89be9544..e7fbf052 100644 --- a/src/layouts/footer.tsx +++ b/src/layouts/footer.tsx @@ -5,7 +5,7 @@ import Link from 'next/link'; const Footer = () => { return ( -