diff --git a/apps/portal/package.json b/apps/portal/package.json index 3889db21..0c8bddcf 100644 --- a/apps/portal/package.json +++ b/apps/portal/package.json @@ -25,6 +25,7 @@ "next-auth": "~4.10.3", "react": "18.2.0", "react-dom": "18.2.0", + "react-hook-form": "^7.36.1", "react-query": "^3.39.2", "superjson": "^1.10.0", "zod": "^3.18.0" diff --git a/apps/portal/src/pages/_app.tsx b/apps/portal/src/pages/_app.tsx index e3b9a8ba..bd05dbec 100644 --- a/apps/portal/src/pages/_app.tsx +++ b/apps/portal/src/pages/_app.tsx @@ -11,8 +11,8 @@ import AppShell from '~/components/global/AppShell'; import type { AppRouter } from '~/server/router'; -import '~/styles/globals.css'; import '@tih/ui/styles.css'; +import '~/styles/globals.css'; const MyApp: AppType<{ session: Session | null }> = ({ Component, diff --git a/apps/portal/src/pages/resumes/submit.tsx b/apps/portal/src/pages/resumes/submit.tsx new file mode 100644 index 00000000..c10bf2f1 --- /dev/null +++ b/apps/portal/src/pages/resumes/submit.tsx @@ -0,0 +1,240 @@ +import Head from 'next/head'; +import { useMemo, useState } from 'react'; +import type { SubmitHandler } from 'react-hook-form'; +import { useForm } from 'react-hook-form'; +import { PaperClipIcon } from '@heroicons/react/24/outline'; +import { Button, Select, TextInput } from '@tih/ui'; + +const TITLE_PLACEHOLDER = + 'e.g. Applying for Company XYZ, please help me to review!'; +const ADDITIONAL_INFO_PLACEHOLDER = `e.g. I’m applying for company XYZ. I have been resume-rejected by N companies that I have applied for. Please help me to review so company XYZ gives me an interview!`; +const FILE_UPLOAD_ERROR = 'Please upload a PDF file that is less than 10MB.'; + +const MAX_FILE_SIZE_LIMIT = 10485760; + +type IFormInput = { + additionalInformation?: string; + experience: string; + file: File; + location: string; + role: string; + title: string; +}; + +export default function SubmitResumeForm() { + // TODO: Use enums instead + const roleItems = [ + { + label: 'Frontend Engineer', + value: 'Frontend Engineer', + }, + { + label: 'Full-Stack Engineer', + value: 'Full-Stack Engineer', + }, + { + label: 'Backend Engineer', + value: 'Backend Engineer', + }, + ]; + + const experienceItems = [ + { + label: 'Fresh Graduate (0 - 1 years)', + value: 'Fresh Graduate (0 - 1 years)', + }, + { + label: 'Mid', + value: 'Mid', + }, + { + label: 'Senior', + value: 'Senior', + }, + ]; + + const locationItems = [ + { + label: 'United States', + value: 'United States', + }, + { + label: 'Singapore', + value: 'Singapore', + }, + { + label: 'India', + value: 'India', + }, + ]; + + const [title, setTitle] = useState(''); + const [role, setRole] = useState(roleItems[0].label); + const [experience, setExperience] = useState(experienceItems[0].label); + const [location, setLocation] = useState(locationItems[0].label); + const [resumeFile, setResumeFile] = useState(null); + const [invalidFileUploadError, setInvalidFileUploadError] = useState< + string | null + >(null); + const [additionalInfo, setAdditionalInfo] = useState(''); + + const { + register, + handleSubmit, + formState: { errors }, + } = useForm(); + + // TODO: Add Create resume mutation + const onSubmit: SubmitHandler = (data) => { + alert(JSON.stringify(data)); + }; + + const onUploadFile = (event: React.ChangeEvent) => { + const file = event.target.files?.item(0); + if (file == null) { + return; + } + if (file.type !== 'application/pdf' || file.size > MAX_FILE_SIZE_LIMIT) { + setInvalidFileUploadError(FILE_UPLOAD_ERROR); + return; + } + setInvalidFileUploadError(''); + setResumeFile(file); + }; + + const fileUploadError = useMemo(() => { + if (invalidFileUploadError != null) { + return invalidFileUploadError; + } + if (errors?.file != null) { + return 'Resume cannot be empty!'; + } + }, [errors?.file, invalidFileUploadError]); + + const onReset = () => { + setTitle(''); + setLocation(locationItems[0].label); + setExperience(experienceItems[0].label); + setRole(roleItems[0].label); + setResumeFile(null); + setAdditionalInfo(''); + }; + + return ( + <> + + Upload a resume + +
+
+
+
+

Upload a resume

+
+ +
+
+ +
+
+ + +

or drag and drop

+
+

PDF up to 10MB

+
+ + {fileUploadError && ( +

{fileUploadError}

+ )} + +
+ {/* TODO: Use TextInputArea instead */} + +
+
+
+ + +
+
+ + ); +} diff --git a/yarn.lock b/yarn.lock index c5877431..4f75a546 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11923,6 +11923,11 @@ react-helmet-async@*, react-helmet-async@^1.3.0: react-fast-compare "^3.2.0" shallowequal "^1.1.0" +react-hook-form@^7.36.1: + version "7.36.1" + resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.36.1.tgz#82a311fe8cbe75e689fd4529f083b7c983da6520" + integrity sha512-EbYYkCG2p8ywe7ikOH2l02lAFMrrrslZi1I8fqd8ifDGNAkhomHZQzQsP6ksvzrWBKntRe8b5L5L7Zsd+Gm02Q== + react-inspector@^5.1.0: version "5.1.1" resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-5.1.1.tgz#58476c78fde05d5055646ed8ec02030af42953c8"