Compare commits

..

2 Commits

Author SHA1 Message Date
8a4c867a8a added it jobbank
All checks were successful
Vercel Production Deployment / Deploy-Production (push) Successful in 1m16s
2024-06-11 13:28:09 +02:00
a43e91e16c installed moment package to parse datetime since posting 2024-06-11 08:49:25 +02:00
9 changed files with 213 additions and 12 deletions

View File

@ -1,14 +1,18 @@
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const nextConfig = { const nextConfig = {
images: { images: {
remotePatterns: [ remotePatterns: [
{ {
protocol: 'https', protocol: "https",
hostname: 'thehub-io.imgix.net', hostname: "thehub-io.imgix.net",
pathname: '/files/s3/*', pathname: "/files/s3/*",
}, },
], {
}, protocol: "https",
hostname: "www.it-jobbank.dk",
},
],
},
}; };
export default nextConfig; export default nextConfig;

71
package-lock.json generated
View File

@ -10,10 +10,12 @@
"dependencies": { "dependencies": {
"@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-tabs": "^1.0.4",
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"html-react-parser": "^5.1.10", "html-react-parser": "^5.1.10",
"lucide-react": "^0.390.0", "lucide-react": "^0.390.0",
"moment": "^2.30.1",
"next": "14.2.3", "next": "14.2.3",
"react": "^18", "react": "^18",
"react-dom": "^18", "react-dom": "^18",
@ -669,6 +671,37 @@
} }
} }
}, },
"node_modules/@radix-ui/react-roving-focus": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz",
"integrity": "sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/primitive": "1.0.1",
"@radix-ui/react-collection": "1.0.3",
"@radix-ui/react-compose-refs": "1.0.1",
"@radix-ui/react-context": "1.0.1",
"@radix-ui/react-direction": "1.0.1",
"@radix-ui/react-id": "1.0.1",
"@radix-ui/react-primitive": "1.0.3",
"@radix-ui/react-use-callback-ref": "1.0.1",
"@radix-ui/react-use-controllable-state": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-slot": { "node_modules/@radix-ui/react-slot": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz",
@ -688,6 +721,36 @@
} }
} }
}, },
"node_modules/@radix-ui/react-tabs": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.0.4.tgz",
"integrity": "sha512-egZfYY/+wRNCflXNHx+dePvnz9FbmssDTJBtgRfDY7e8SE5oIo3Py2eCB1ckAbh1Q7cQ/6yJZThJ++sgbxibog==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/primitive": "1.0.1",
"@radix-ui/react-context": "1.0.1",
"@radix-ui/react-direction": "1.0.1",
"@radix-ui/react-id": "1.0.1",
"@radix-ui/react-presence": "1.0.1",
"@radix-ui/react-primitive": "1.0.3",
"@radix-ui/react-roving-focus": "1.0.4",
"@radix-ui/react-use-controllable-state": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-use-callback-ref": { "node_modules/@radix-ui/react-use-callback-ref": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz",
@ -3715,6 +3778,14 @@
"node": ">=16 || 14 >=14.17" "node": ">=16 || 14 >=14.17"
} }
}, },
"node_modules/moment": {
"version": "2.30.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
"engines": {
"node": "*"
}
},
"node_modules/ms": { "node_modules/ms": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",

View File

@ -11,10 +11,12 @@
"dependencies": { "dependencies": {
"@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-tabs": "^1.0.4",
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"html-react-parser": "^5.1.10", "html-react-parser": "^5.1.10",
"lucide-react": "^0.390.0", "lucide-react": "^0.390.0",
"moment": "^2.30.1",
"next": "14.2.3", "next": "14.2.3",
"react": "^18", "react": "^18",
"react-dom": "^18", "react-dom": "^18",

43
src/app/ITJobbank.tsx Normal file
View File

@ -0,0 +1,43 @@
import { revalidatePath } from "next/cache";
import JobCard from "./_jobcard/JobCard";
interface JobPosting {
title: string;
logo: string;
company: string;
location: string;
type: string;
description: string;
link: string;
skills: {
react: boolean;
python: boolean;
golang: boolean;
svelte: boolean;
nextjs: boolean;
typescript: boolean;
tailwind: boolean;
};
}
async function fetchJobs(): Promise<JobPosting[]> {
const response = await fetch("http://51.20.250.24/jobs/itjobbank");
if (!response.ok) {
throw new Error("Failed to fetch jobs");
}
revalidatePath("/");
return response.json();
}
export default async function ITJobbank() {
const jobs = await fetchJobs();
return (
<>
<h1 className="text-4xl my-4">IT Jobbank</h1>
{jobs.map((job, i) => (
<JobCard key={i} job={job} />
))}
</>
);
}

24
src/app/TabContainer.tsx Normal file
View File

@ -0,0 +1,24 @@
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import TheHub from "./TheHub";
import ITJobbank from "./ITJobbank";
export default function TabContainer() {
return (
<Tabs defaultValue="the-hub" className="flex flex-col my-8">
<TabsList className="w-fit mx-auto">
<TabsTrigger className="text-xl" value="the-hub">
The Hub
</TabsTrigger>
<TabsTrigger className="text-xl" value="it-jobbank">
IT-Jobbank
</TabsTrigger>
</TabsList>
<TabsContent value="the-hub">
<TheHub />
</TabsContent>
<TabsContent value="it-jobbank">
<ITJobbank />
</TabsContent>
</Tabs>
);
}

View File

@ -21,7 +21,7 @@ interface JobPosting {
} }
async function fetchJobs(): Promise<JobPosting[]> { async function fetchJobs(): Promise<JobPosting[]> {
const response = await fetch("http://51.20.250.24/jobs"); const response = await fetch("http://51.20.250.24/jobs/hub");
if (!response.ok) { if (!response.ok) {
throw new Error("Failed to fetch jobs"); throw new Error("Failed to fetch jobs");
} }

View File

@ -42,7 +42,7 @@ export default async function JobCard(props: { job: JobPosting }) {
<div className="flex justify-between w-full"> <div className="flex justify-between w-full">
<div className="flex flex-row items-center gap-4"> <div className="flex flex-row items-center gap-4">
<Image <Image
className="max-h-12 w-auto" className="max-h-12 w-12 h-auto overflow-x-clip"
src={logo} src={logo}
alt={`${company}'s logo`} alt={`${company}'s logo`}
width={100} width={100}

View File

@ -1,4 +1,6 @@
import moment from "moment";
import TheHub from "./TheHub"; import TheHub from "./TheHub";
import TabContainer from "./TabContainer";
export default async function Home() { export default async function Home() {
return ( return (
@ -10,7 +12,7 @@ export default async function Home() {
they are posted! they are posted!
</h2> </h2>
<hr className="stroke stroke-stone-200 my-4" /> <hr className="stroke stroke-stone-200 my-4" />
<TheHub /> <TabContainer />
</div> </div>
</main> </main>
); );

View File

@ -0,0 +1,55 @@
"use client"
import * as React from "react"
import * as TabsPrimitive from "@radix-ui/react-tabs"
import { cn } from "@/lib/utils"
const Tabs = TabsPrimitive.Root
const TabsList = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.List>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
>(({ className, ...props }, ref) => (
<TabsPrimitive.List
ref={ref}
className={cn(
"inline-flex h-10 items-center justify-center rounded-md bg-stone-100 p-1 text-stone-500 dark:bg-stone-800 dark:text-stone-400",
className
)}
{...props}
/>
))
TabsList.displayName = TabsPrimitive.List.displayName
const TabsTrigger = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
>(({ className, ...props }, ref) => (
<TabsPrimitive.Trigger
ref={ref}
className={cn(
"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-white transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-stone-950 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-white data-[state=active]:text-stone-950 data-[state=active]:shadow-sm dark:ring-offset-stone-950 dark:focus-visible:ring-stone-300 dark:data-[state=active]:bg-stone-950 dark:data-[state=active]:text-stone-50",
className
)}
{...props}
/>
))
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName
const TabsContent = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
>(({ className, ...props }, ref) => (
<TabsPrimitive.Content
ref={ref}
className={cn(
"mt-2 ring-offset-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-stone-950 focus-visible:ring-offset-2 dark:ring-offset-stone-950 dark:focus-visible:ring-stone-300",
className
)}
{...props}
/>
))
TabsContent.displayName = TabsPrimitive.Content.displayName
export { Tabs, TabsList, TabsTrigger, TabsContent }