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

Added resume field in Application Page #103

Merged
merged 18 commits into from
Dec 17, 2023
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/site/src/app/apply/sections/Form/AgeInformation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default function AgeInformation() {
</div>

<SimpleRadio
name="minor-check"
name="minor_check"
samderanova marked this conversation as resolved.
Show resolved Hide resolved
values={yesNoOptions}
title="Will you be 18 years or older by January 26th, 2024?"
titleClass="text-xl font-bold m-0 text-center"
Expand Down
8 changes: 4 additions & 4 deletions apps/site/src/app/apply/sections/Form/BasicInformation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default function BasicInformation() {

<div className="flex gap-5 w-full max-[1000px]:flex-col max-[1000px]:items-center">
<TextInput
name="first-name"
name="first_name"
labelClass={styles.label}
labelText="First Name"
inputClass={styles.input}
Expand All @@ -40,7 +40,7 @@ export default function BasicInformation() {
placeholder=""
/>
<TextInput
name="last-name"
name="last_name"
labelClass={styles.label}
labelText="Last Name"
inputClass={styles.input}
Expand All @@ -53,14 +53,14 @@ export default function BasicInformation() {

<div className="flex gap-5 w-full max-[1000px]:flex-col max-[1000px]:items-center">
<RadioSelect
IdentifierId="pronouns-identifier"
IdentifierId="pronouns_identifier"
name="pronouns"
labelText="Pronouns"
values={pronouns}
containerClass="flex flex-col w-6/12 max-[1000px]:w-full"
/>
<RadioSelect
IdentifierId="ethnicity-identifier"
IdentifierId="ethnicity_identifier"
name="ethnicity"
labelText="Race / Ethnicity"
values={ethnicity}
Expand Down
10 changes: 10 additions & 0 deletions apps/site/src/app/apply/sections/Form/Form.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,13 @@
.image {
z-index: -1;
}

.upload {
& > * {
// prevents child elements from interfering with drag & drop
pointer-events: none;
}
background-color: #e1e1e1;
border-radius: 12px;
padding: 1rem 2rem;
}
4 changes: 3 additions & 1 deletion apps/site/src/app/apply/sections/Form/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import BasicInformation from "./BasicInformation";
import AgeInformation from "./AgeInformation";
import SchoolInformation from "./SchoolInformation";
import ProfileInformation from "./ProfileInformation";
import ResumeInformation from "./ResumeInformation";
import Button from "@/lib/components/Button/Button";
import koiLeft from "@/assets/images/koi-swim-left.png";
import koiRight from "@/assets/images/koi-swim-right.png";
Expand Down Expand Up @@ -38,11 +39,12 @@ export default function Form() {
<form
method="post"
className={`${styles.form} text-[#000000] w-8/12 flex flex-col items-center py-12 gap-10 z-1 max-[800px]:w-9/12 max-[400px]:w-11/12`}
action="/api/user/apply"
encType="multipart/form-data"
IanWearsHat marked this conversation as resolved.
Show resolved Hide resolved
>
<BasicInformation />
<SchoolInformation />
<ProfileInformation />
<ResumeInformation />
<AgeInformation />
<Button text="Submit Application" />
</form>
Expand Down
4 changes: 2 additions & 2 deletions apps/site/src/app/apply/sections/Form/ProfileInformation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default function ProfileInformation() {
</div>

<Textfield
name="collaboration-answer"
name="collaboration_answer"
labelClass={`${styles.label} mt-7`}
labelText="Why is collaboration important to being a programmer or technologist, and what does it mean to you? (150 words)"
inputClass={`bg-[#E1E1E1] p-3 h-48 resize-none rounded-xl`}
Expand All @@ -42,7 +42,7 @@ export default function ProfileInformation() {
/>

<Textfield
name="job-answer"
name="job_answer"
labelClass={`${styles.label} mt-7`}
labelText="If you could have any job in the world, what would it be? (ex. YouTuber, Body Builder, etc.) (100 words)"
inputClass={`bg-[#E1E1E1] p-3 h-48 resize-none rounded-xl`}
Expand Down
91 changes: 91 additions & 0 deletions apps/site/src/app/apply/sections/Form/ResumeInformation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
"use client";

import { ChangeEvent, useEffect, useState, useRef } from "react";

import RequiredAsterisk from "@/app/apply/sections/Components/RequiredAsterisk";
import OutputFeedBack from "./ResumeOutputFeedback";

import uploadImage from "@/assets/icons/upload-resume-icon.svg";
import Image from "next/image";

import styles from "./Form.module.scss";

class InvalidFile extends Error {
constructor(message: string) {
super(message);
this.name = "InvalidFile";
}
}

export default function ResumeInformation() {
const inputRef = useRef<HTMLInputElement>(null);
const [resumePath, setResumePath] = useState("");
const [errorMessage, setErrorMessage] = useState("");

useEffect(() => {
if (inputRef.current) {
inputRef.current.value = "";
}
}, []);

const handleFileUpload = (event: ChangeEvent<HTMLInputElement>) => {
event.preventDefault();

setErrorMessage("");
setResumePath("");

let file = event.target.files ? event.target.files[0] : null;
try {
handleFile(file);
} catch (error) {
event.target.value = "";
}
};

const handleFile = (file: File | null) => {
if (!file) throw TypeError;

let path = file.name;

let extension = path.split(".").pop();
if (extension != "pdf") {
setErrorMessage("Invalid file format");
throw new InvalidFile("Invalid file format");
}

if (file.size > 500000) {
setErrorMessage("Invalid file size (file size exceeds 0.5 MB)");
throw new InvalidFile("Invalid file size");
}
setResumePath(path);
};

return (
<div className="flex flex-col items-start w-11/12">
<label className={styles.label}>
Resume (PDF, 0.5 MB max) <RequiredAsterisk />
</label>
<label
htmlFor="resume_upload"
className={`${styles.upload} cursor-pointer mb-3`}
>
<Image src={uploadImage} width="100" alt="Upload resume icon" />
<h2 className="text-center">Upload file</h2>
</label>
<input
ref={inputRef}
className="opacity-0 absolute"
name="resume_upload"
id="resume_upload"
type="file"
accept="application/pdf"
onChange={handleFileUpload}
required
></input>
<OutputFeedBack
errorMessage={errorMessage}
resumePath={resumePath}
/>
</div>
);
}
20 changes: 20 additions & 0 deletions apps/site/src/app/apply/sections/Form/ResumeOutputFeedback.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
interface outputFeedbackProps {
IanWearsHat marked this conversation as resolved.
Show resolved Hide resolved
errorMessage: string;
resumePath: string;
}

export default function OutputFeedBack(props: outputFeedbackProps) {
IanWearsHat marked this conversation as resolved.
Show resolved Hide resolved
if (props.errorMessage) {
return (
<span className="text-[#FF2222] text-xl">{props.errorMessage}</span>
);
}

return (
<span className="text-xl">
{props.resumePath
? "Successfully uploaded " + props.resumePath
: ""}
</span>
);
}
6 changes: 3 additions & 3 deletions apps/site/src/app/apply/sections/Form/SchoolInformation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export default function SchoolInformation() {
<DropdownSelect
labelStyle={styles.label}
inputStyle={styles.input}
name="education-level"
name="education_level"
labelText="Current Education Level"
values={educationLevels}
containerClass="flex flex-col w-6/12 max-[1000px]:w-full"
Expand All @@ -79,7 +79,7 @@ export default function SchoolInformation() {
<DropdownSelect
labelStyle={styles.label}
inputStyle={styles.input}
name="school-name"
name="school_name"
labelText="School Name"
values={universityOptions}
containerClass="flex flex-col w-6/12 max-[1000px]:w-full"
Expand All @@ -97,7 +97,7 @@ export default function SchoolInformation() {
/>

<SimpleRadio
name="hack-check"
name="hack_check"
values={yesNoOptions}
title="Is this your first Hackathon?"
titleClass="text-lg mb-0 p-0"
Expand Down
10 changes: 10 additions & 0 deletions apps/site/src/assets/icons/upload-resume-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.