Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add position page #3

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
13 changes: 13 additions & 0 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,19 @@
}
}


@layer base {
h1 {
@apply text-[48px] font-bold
}
h2 {
@apply text-[32px] font-bold
}
h3 {
@apply text-[25px] font-semibold
}
}

body {
color: var(--foreground);
background: var(--background);
Expand Down
22 changes: 21 additions & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@ import type { Metadata } from "next";
import localFont from "next/font/local";
import "./globals.css";

import {Montserrat, Roboto} from 'next/font/google';

const montserrat = Montserrat({
subsets: ['latin'],
style: ['normal', 'italic'],
weight:["700", "600"],
variable: '--font-montserrat',
});

const roboto = Roboto({
subsets: ['latin'],
weight:["400","500","700"],
variable: '--font-roboto',
});

const geistSans = localFont({
src: "./fonts/GeistVF.woff",
variable: "--font-geist-sans",
Expand All @@ -26,7 +41,12 @@ export default function RootLayout({
return (
<html lang="en">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
className={`
${montserrat.variable}
${roboto.variable}
${geistSans.variable}
${geistMono.variable}
antialiased`}
>
{children}
</body>
Expand Down
123 changes: 123 additions & 0 deletions src/app/positions/[id]/page.tsx
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we try to follow the figma more closely, perhaps move the back to all roles up, make overview and application wider, and change the font of UI/UX Designer and all.

Thank you!

Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
"use client"

import { useParams } from "next/navigation";
import { useState } from "react";
import Image from "next/image";
import NavBar from "@/components/Navbar";
import Footer from "@/components/Footer"
import PositionNotFound from "../not-found";
import { JobDataType, JobData } from "@/lib/positions/job-data";
import Link from "next/link";


export default function JobApplication() {
const params = useParams();
const jobData: JobDataType = JobData[params.id];

const [activeTab, setActiveTab] = useState("overview");

if (jobData !== undefined) {
return (

<div className="min-h-screen p-8 pb-20 gap-16 sm:p-20 font-body">
<NavBar/>
{/* Back to All Roles Button */}
<GoBack/>
{/* Job Role Title */}
<section className="text-center mb-8 flex flex-col items-center justify-center">
<h1 className="font-header">{jobData.title}</h1>
<div className="text-xl bg-gray-200 text-gray-600 rounded-full mt-4 px-16 py-2 w-fit shadow-lg">
{jobData.department} | {jobData.semester} | {jobData.positionsAvailable}
</div>
</section>

{/* Overview and Application Tabs */}
<div className="flex justify-center mb-10 mt-10">
<button
className={`text-3xl px-48 py-2 border-b-2 ${activeTab === "overview" ? "border-orange-500 text-orange-500 font-semibold" : "border-transparent hover:border-gray-300"}`}
onClick={() => setActiveTab("overview")}
>
Overview
</button>
<button
className={`text-3xl px-48 py-2 border-b-2 ${activeTab === "application" ? "border-orange-500 text-orange-500 font-semibold" : "border-transparent hover:border-gray-300"}`}
onClick={() => setActiveTab("application")}
>
Application
</button>
</div>

{/* Conditional Rendering */}
{activeTab === "overview" ? (
<Overview {...jobData}/>
) : (
<Application {...jobData}/>
)}
<Footer/>
</div>
);
} else {
return (<PositionNotFound/>);
}

}

function Overview(jobData: JobDataType) {
return (
<div>
<div className="max-w-lg mx-auto mb-8 p-4 bg-blue-100 rounded">
<h3 className=" text-black">What you will do</h3>
<div className="text-gray-700 text-xl">{jobData.description}</div>
</div>
<div className="max-w-lg mx-auto mb-8 p-4 bg-blue-100 rounded">
<h3 className=" text-black">Who we are looking for</h3>
<div className="text-gray-700 text-xl">{jobData.requirements}</div>
</div>
</div>
)
}

function Application(jobData: JobDataType) {
return (
<form className="max-w-lg mx-auto font-body text-xl">
<div className="mb-4">
<label className="block mb-2">Full Name</label>
<input type="text" placeholder="e.g. Shawn Tan" className="w-full p-2 border border-gray-300 rounded" />
</div>
<div className="mb-4">
<label className="block mb-2">Faculty / Major</label>
<input type="text" placeholder="e.g. SoC / CS" className="w-full p-2 border border-gray-300 rounded" />
</div>
<div className="mb-4">
<label className="block mb-2">Year of Study</label>
<input type="text" placeholder="e.g. Year 1" className="w-full p-2 border border-gray-300 rounded" />
</div>
<div className="mb-4">
<label className="block mb-2">Linkedin URL</label>
<input type="text" placeholder="Type here" className="w-full p-2 border border-gray-300 rounded" />
</div>
<div className="mb-4">
<label className="block mb-2">Resume link</label>
<input type="text" placeholder="Type here" className="w-full p-2 border border-gray-300 rounded" />
</div>
<div className="mb-4">
<label className="block mb-2">Why do you want to join NFS as {jobData.title}?</label>
<input type="text" placeholder="Type here" className="w-full p-2 border border-gray-300 rounded" />
</div>
<div className="w-full flex items-center justify-center">
<button className="bg-orange-500 text-white rounded-full text-2xl px-10 py-2">Submit</button>
</div>

</form>
)
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we also have a placeholder Submit button? Thank you!

function GoBack() {
return (
<div className="text-right text-black mt-8">
<button className="px-4 py-2 bg-blue-200 text-blue-950 rounded-full">
<Link href = {`/positions/`}>Back to all roles</Link>
</button>
</div>
)
}
7 changes: 7 additions & 0 deletions src/app/positions/not-found.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function PositionNotFound() {
return (
<div className="flex flex-row min-h-screen justify-center items-center">
<div className="text-3xl">Position not found</div>
</div>
)
}
131 changes: 63 additions & 68 deletions src/app/positions/page.tsx
Original file line number Diff line number Diff line change
@@ -1,82 +1,77 @@
"use client";

import NavBar from "@/components/Navbar";
import Footer from "@/components/Footer"
import Link from "next/link";
import { JobData, JobDataType } from "@/lib/positions/job-data";
import { useState } from "react";
import Image from "next/image";

// Landing page
export default function JobApplication() {
const [activeTab, setActiveTab] = useState("overview");

const availableRoutes = Object.keys(JobData); // you can check from @/lib/positions/job-data.tsx
const MIN_ROLE_PER_PAGE = 4;
const maxRole = availableRoutes.length;
const [rolePerPage, setRolePerPage] = useState(MIN_ROLE_PER_PAGE);
return (
<div className="min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
{/* Header Area */}
<header className="flex justify-between items-center mb-8">
<div className="flex items-center">
<Image
src="/Fintech Logo.svg"
alt="Fintech Society Logo"
width={50}
height={50}
/>
<nav className="ml-8">
<a href="/" className="mr-4">Home</a>
<a href="/search-roles" className="mr-4">Search Roles</a>
<a href="/apply" className="mr-4">Apply</a>
<a href="/about-us">About Us</a>
</nav>
</div>
<div>Welcome Back Shawn!</div>
</header>

{/* Job Role Title */}
<section className="text-center mb-8">
<h1 className="text-4xl font-bold">UI/UX Designer</h1>
<p className="text-lg">Software Development - Semester 1</p>
<p className="text-lg">1-5 Positions Available</p>
</section>

{/* Overview and Application Tabs */}
<div className="flex justify-center mb-8">
<button
className={`px-4 py-2 border-b-2 ${activeTab === "overview" ? "border-orange-500 text-orange-500" : "border-transparent hover:border-gray-300"}`}
onClick={() => setActiveTab("overview")}
<NavBar/>
<div className="font-bold text-center">
<h1 className="text-3xl">(Temporarily used)</h1>
<p className="text-xl">NUS Fintech Society Recruitment for AY 2024/2025</p>
</div>
<div className="text-2xl font-bold">Open roles</div>
{/*This is not the actual implementation. It's just some random placeholder*/}
<div>
{
availableRoutes.slice(0, rolePerPage).map((jobPosition) => (
<JobCard route={jobPosition}/>
))
}
</div>
{/*see more / see less */}
{(rolePerPage < maxRole) && <div className="text-left text-black mt-8">
<button
className="px-4 py-2 bg-gray-200 rounded"
onClick={() => rolePerPage < maxRole && setRolePerPage(rolePerPage + MIN_ROLE_PER_PAGE)}
>
Overview
Show more
</button>
<button
className={`px-4 py-2 border-b-2 ${activeTab === "application" ? "border-orange-500 text-orange-500" : "border-transparent hover:border-gray-300"}`}
onClick={() => setActiveTab("application")}
</div>}
{(rolePerPage >= maxRole) && <div className="text-left text-black mt-8">
<button
className="px-4 py-2 bg-gray-200 rounded"
onClick={() => setRolePerPage(MIN_ROLE_PER_PAGE)}
>
Application
Show less
</button>
</div>
</div>}
<Footer/>
</div>
);
}

{/* Conditional Rendering */}
{activeTab === "overview" ? (
<div className="max-w-lg mx-auto mb-8 p-4 bg-blue-100 rounded">
<h2 className="text-xl font-bold">What you will do</h2>
<p className="text-gray-700">Role Description</p>
</div>
) : (
<form className="max-w-lg mx-auto">
<div className="mb-4">
<label className="block mb-2">Full Name</label>
<input type="text" placeholder="e.g. Shawn Tan" className="w-full p-2 border border-gray-300 rounded" />
</div>
<div className="mb-4">
<label className="block mb-2">Faculty / Major</label>
<input type="text" placeholder="e.g. SoC / CS" className="w-full p-2 border border-gray-300 rounded" />
</div>
<div className="mb-4">
<label className="block mb-2">Year of Study</label>
<input type="text" placeholder="e.g. Year 1" className="w-full p-2 border border-gray-300 rounded" />
</div>
</form>
)}
function JobCard(props: any) {
const route = props.route;
const jobData: JobDataType = JobData[route];
const position = 0; // FIX: replace this value
return (
<div key={route} className="bg-blue-200 text-black rounded-md px-3 py-3 my-2">
<Link href = {`/positions/${route}`}>
<div className="text-xl font-bold">{jobData.title}</div>
<div>{jobData.department} - {jobData.semester}</div>
<div>{position} positions available</div>
</Link>
</div>
)
}

{/* Back to All Roles Button */}
<div className="text-right mt-8">
<button className="px-4 py-2 bg-gray-200 rounded">Back to all roles</button>
</div>
function GoBack() {
return (
<div className="text-right text-black mt-8">
<Link href = {`/positions`}>
<button className="px-4 py-2 bg-gray-200 rounded">Back to all roles</button>
</Link>
</div>
);
}
)
}

8 changes: 8 additions & 0 deletions src/components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export default function Footer() {
return (
<div className="flex justify-between items-center mb-8">
Footer (merge with howen)
</div>
);
}

7 changes: 7 additions & 0 deletions src/components/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function Navbar() {
return (
<div className="flex justify-between items-center mb-8">
Navbar (merge with howen)
</div>
);
}
Loading