From 5619d4327b857b6159822ea7e7f88860c8127111 Mon Sep 17 00:00:00 2001 From: hana-dowe Date: Tue, 26 Dec 2023 14:04:25 -0500 Subject: [PATCH 1/3] resume logic --- api/schema.ts | 12 +- api/useFetch.ts | 12 +- .../RegistrationForms/Experience/index.tsx | 18 ++- .../FormComponents/FormResumeUpload/index.tsx | 110 ++++++++++++++++++ .../RegistrationForms/Review/index.tsx | 20 +++- .../Dashboard/RegistrationForms/helpers.tsx | 14 +-- hooks/Application/useResumeGet.ts | 18 +++ hooks/Application/useResumeUpdate.ts | 10 ++ pages/dashboard/registration/index.tsx | 37 ++++-- types/Application/index.ts | 14 ++- types/Zod/index.ts | 8 +- 11 files changed, 236 insertions(+), 37 deletions(-) create mode 100644 components/Dashboard/RegistrationForms/FormComponents/FormResumeUpload/index.tsx create mode 100644 hooks/Application/useResumeGet.ts create mode 100644 hooks/Application/useResumeUpdate.ts diff --git a/api/schema.ts b/api/schema.ts index e92906d..c58b222 100644 --- a/api/schema.ts +++ b/api/schema.ts @@ -1,6 +1,6 @@ import { APITemplate } from '@/api/types' import { CustomFetch } from '@/api/useFetch' -import { ApplicationGetResp, ApplicationUpdateReq } from '@/types/Application' +import { ApplicationGetResp, ApplicationUpdateReq, ResumeGetResp } from '@/types/Application' import { EmailVerifyReq, EmailVerifyResp } from '@/types/Email' import { EventListResp } from '@/types/Event' import { PhotoListResp } from '@/types/Photo' @@ -28,6 +28,16 @@ const application = (customFetch: CustomFetch) => const res = await customFetch('POST', 'DH_BE', '/application-update', args) return res.data as {} }, + resumeGet: async () => { + const res = await customFetch('GET', 'DH_BE', '/resume-get') + return res.data as ResumeGetResp + }, + resumeUpdate: async (args: FormData) => { + const res = await customFetch('POST', 'DH_BE', '/resume-update', args, { + isForm: true, + }) + return res.data as ResumeGetResp + }, } as const) const email = (customFetch: CustomFetch) => diff --git a/api/useFetch.ts b/api/useFetch.ts index a685264..a1f19f0 100644 --- a/api/useFetch.ts +++ b/api/useFetch.ts @@ -14,7 +14,7 @@ type Props = { base: BaseURL url: string body?: any - isForm?: string + isForm?: boolean } const fetchHelper = async (props: Props): Promise<{ data: any; error: any; statusCode: any }> => { @@ -68,14 +68,20 @@ const fetchHelper = async (props: Props): Promise<{ data: any; error: any; statu /** IMPORTANT: Do not use this directly, use useAPI */ const useFetch = () => { return useCallback( - async (method: Method, base: BaseURL, url: string, body?: Object, isForm?: string) => { + async ( + method: Method, + base: BaseURL, + url: string, + body?: Object, + options?: { isForm: boolean } + ) => { try { return await fetchHelper({ method, base, url, body, - isForm, + isForm: options?.isForm, }) } catch (error) { throw error diff --git a/components/Dashboard/RegistrationForms/Experience/index.tsx b/components/Dashboard/RegistrationForms/Experience/index.tsx index 01382a2..daaf258 100644 --- a/components/Dashboard/RegistrationForms/Experience/index.tsx +++ b/components/Dashboard/RegistrationForms/Experience/index.tsx @@ -8,6 +8,7 @@ import Typography from '@mui/material/Typography' import FormCheckbox from '@/components/Dashboard/RegistrationForms/FormComponents/FormCheckbox' import FormDynamicSelect from '@/components/Dashboard/RegistrationForms/FormComponents/FormDynamicSelect' import FormMultiSelect from '@/components/Dashboard/RegistrationForms/FormComponents/FormMultiSelect' +import FormResumeUpload from '@/components/Dashboard/RegistrationForms/FormComponents/FormResumeUpload' import FormSelect from '@/components/Dashboard/RegistrationForms/FormComponents/FormSelect' import FormTextField from '@/components/Dashboard/RegistrationForms/FormComponents/FormTextField' import { @@ -17,6 +18,7 @@ import { interestsOptions, OTHER_SPECIFY, programOptions, + ResumeGetResp, schoolOptions, teamPreferenceOptions, } from '@/types/Application' @@ -92,7 +94,7 @@ const ExperienceForm = (props: Props) => { options={schoolOptions} errors={errors} setOtherField={(val: string) => { - form.setValue('school_other', val) + setValue('school_other', val, { shouldValidate: true }) }} inputRef={ref} {...field} @@ -124,7 +126,7 @@ const ExperienceForm = (props: Props) => { options={programOptions} errors={errors} setOtherField={(val: string) => { - form.setValue('program_other', val) + setValue('program_other', val, { shouldValidate: true }) }} inputRef={ref} {...field} @@ -148,7 +150,17 @@ const ExperienceForm = (props: Props) => { 🚀 Flex that Hello World python script - --- Resume goes here --- + { + setValue('resume_file_name', resp.resume_file_name, { shouldValidate: true }) + setValue('resume_link', resp.resume_link, { shouldValidate: true }) + setValue('resume_update_count', resp.resume_update_count, { shouldValidate: true }) + }} + /> void +} + +const FormResumeUpload = (props: Props) => { + const { name, link, updateCount = 0, error, onSuccess } = props + const { setToast } = useToast() + + const { isLoading, mutate: updateResume } = useResumeUpdate() + + const inputRef = useRef(null) + + const onFileSelected = async (e: React.FormEvent) => { + if (!e.currentTarget?.files) return + const file = e.currentTarget.files[0] + if (!file) return + + const fileName = file.name + if (fileName.length > 128) { + setToast({ + type: 'error', + message: 'File name must be 128 characters or less', + autoHide: false, + }) + return + } + + if (fileName.split('.').pop() !== 'pdf') { + setToast({ + type: 'error', + message: 'File type must be a pdf', + autoHide: false, + }) + return + } + + if (file.size > MAX_FILE_SIZE) { + setToast({ + type: 'error', + message: 'File size must be less than 2MB', + autoHide: false, + }) + return + } + + const data = new FormData() + data.append('file', file) + updateResume(data, { + onSuccess: (resp) => { + onSuccess(resp) + // want toast on success so it hides any errors that didn't auto-hide + setToast({ + type: 'success', + message: 'Resume successfully uploaded', + }) + }, + onError: () => { + setToast({ + type: 'error', + message: 'something went wrong :(', + autoHide: false, + }) + }, + }) + } + + return ( + + + + { + e.stopPropagation() + inputRef.current?.click() + }} + disabled={updateCount >= MAX_UPDATE_COUNT} + > + Upload Resume + + {MAX_UPDATE_COUNT - updateCount} uploads left + + + {name} + + {error && {error.message}} + + ) +} + +export default FormResumeUpload diff --git a/components/Dashboard/RegistrationForms/Review/index.tsx b/components/Dashboard/RegistrationForms/Review/index.tsx index 815a6b1..dc9dc8a 100644 --- a/components/Dashboard/RegistrationForms/Review/index.tsx +++ b/components/Dashboard/RegistrationForms/Review/index.tsx @@ -1,9 +1,12 @@ +import { ReactNode } from 'react' + import CheckIcon from '@mui/icons-material/Check' import DoDisturbIcon from '@mui/icons-material/DoDisturb' import InfoIcon from '@mui/icons-material/Info' import Box from '@mui/material/Box' import Button from '@mui/material/Button' import Grid from '@mui/material/Grid' +import Link from '@mui/material/Link' import Tooltip from '@mui/material/Tooltip' import Typography from '@mui/material/Typography' @@ -68,7 +71,15 @@ const FormReview = (props: Props) => {
- + + {application.resume_file_name} + + } + /> {application.portfolio && ( )} @@ -133,16 +144,19 @@ const formatList = (values: string[]) => { type FieldReviewProps = { name: string value: string + valueNode?: ReactNode isList?: boolean } const FieldReview = (props: FieldReviewProps) => { - const { name, value, isList = false } = props + const { name, value, valueNode, isList = false } = props return ( {name} - {value && value.trim() ? ( + {valueNode ? ( + valueNode + ) : value && value.trim() ? ( { ...(program == OTHER_SPECIFY && { program_other: application.program }), // Professional Journey - // TODO: - //resume_link: string - //resume_filename: string - //resume_hash: string + resume_link: application.resume_link, + resume_file_name: application.resume_file_name, + resume_update_count: application.resume_update_count, ...(application.portfolio && { portfolio: application.portfolio }), ...(application.github && { github: application.github }), ...(application.linkedin && { linkedin: application.linkedin }), @@ -241,15 +240,14 @@ const expFormToApp = (form: ExperienceZodForm, currApplication: Application): Ap ...currApplication, // Education + resume_link: form.resume_link, + resume_file_name: form.resume_file_name, + resume_update_count: form.resume_update_count, education: form.education == OTHER_SPECIFY ? form.education_other ?? '' : form.education, school: form.school == OTHER_SPECIFY ? form.school_other ?? '' : form.school, program: form.program == OTHER_SPECIFY ? form.program_other ?? '' : form.program, // Professional Journey - // TODO: - //resume_link: string - //resume_filename: string - //resume_hash: string portfolio: form.portfolio, github: form.github, linkedin: form.linkedin, diff --git a/hooks/Application/useResumeGet.ts b/hooks/Application/useResumeGet.ts new file mode 100644 index 0000000..16e76c2 --- /dev/null +++ b/hooks/Application/useResumeGet.ts @@ -0,0 +1,18 @@ +import { useAPI } from '@/contexts/API' + +type Props = { + enabled?: boolean + onSuccess?: () => void + onError?: () => void +} + +export const useResumeGet = (props?: Props) => { + return useAPI().useQuery(['resumeGet', null], { + enabled: props?.enabled, + staleTime: Infinity, + refetchOnMount: false, + refetchOnWindowFocus: false, + onSuccess: props?.onSuccess, + onError: props?.onError, + }) +} diff --git a/hooks/Application/useResumeUpdate.ts b/hooks/Application/useResumeUpdate.ts new file mode 100644 index 0000000..6786610 --- /dev/null +++ b/hooks/Application/useResumeUpdate.ts @@ -0,0 +1,10 @@ +import { useAPI } from '@/contexts/API' + +export const useResumeUpdate = () => { + const api = useAPI() + return api.useMutation('resumeUpdate', { + onSettled: () => { + api.queryClient.invalidateQueries({ queryKey: ['resumeGet'] }) + }, + }) +} diff --git a/pages/dashboard/registration/index.tsx b/pages/dashboard/registration/index.tsx index 009f62b..508030a 100644 --- a/pages/dashboard/registration/index.tsx +++ b/pages/dashboard/registration/index.tsx @@ -28,6 +28,7 @@ import { useFeatureToggle } from '@/contexts/FeatureToggle' import { useToast } from '@/contexts/Toast' import { useApplicationUpdate } from '@/hooks/Application/useApplicationUpdate' import { useApplicationGet } from '@/hooks/Application/userApplicationGet' +import { useResumeGet } from '@/hooks/Application/useResumeGet' import Error401Page from '@/pages/401' import Error418Page from '@/pages/418' import Error500Page from '@/pages/500' @@ -354,17 +355,23 @@ const RegistrationLoader = () => { const allowedStatuses = ['registering', 'applied', 'selected', 'accepted', 'attended', 'rejected'] + const enabled = + authenticated && + user?.status && + allowedStatuses.includes(user.status) && + (toggles.signupHacker || user.status !== 'registering') + const { - data, + data: applicationData, isLoading: applicationLoading, isError: applicationError, - } = useApplicationGet({ - enabled: - authenticated && - user?.status && - allowedStatuses.includes(user.status) && - (toggles.signupHacker || user.status !== 'registering'), - }) + } = useApplicationGet({ enabled }) + + const { + data: resumeData, + isLoading: resumeLoading, + isError: resumeError, + } = useResumeGet({ enabled }) if (!toggles.dashboard && !toggles.bypassPage) return if (!loading && !authenticated) return @@ -393,14 +400,14 @@ const RegistrationLoader = () => { ) } - if (applicationError) return + if (applicationError || resumeError) return return ( <> Registration | DeerHacks - {loading || !authenticated || !user || applicationLoading ? ( + {loading || !authenticated || !user || applicationLoading || resumeLoading ? ( ) : ( @@ -418,9 +425,15 @@ const RegistrationLoader = () => { My Application {user.status === 'registering' ? ( - + ) : ( - + )} diff --git a/types/Application/index.ts b/types/Application/index.ts index e24c4a7..6b51eaf 100644 --- a/types/Application/index.ts +++ b/types/Application/index.ts @@ -1,5 +1,5 @@ export type ApplicationGetResp = { - application: Application + application: Omit is_draft: boolean } @@ -40,9 +40,11 @@ export type Application = { school: string program: (typeof programOptions)[number] | string + // Resume Fields, Outside of Application Endpoint resume_link: string - resume_filename: string - resume_hash: string + resume_file_name: string + resume_update_count: number + portfolio?: string github?: string linkedin?: string @@ -511,3 +513,9 @@ export const deerhacksReachOptions = [ 'Word of Mouth', OTHER_SPECIFY, ] as const + +export type ResumeGetResp = { + resume_file_name: string + resume_link: string + resume_update_count: number +} diff --git a/types/Zod/index.ts b/types/Zod/index.ts index 61ac35b..e697f90 100644 --- a/types/Zod/index.ts +++ b/types/Zod/index.ts @@ -22,6 +22,7 @@ import { infer as inferZod, intersection, literal, + number, object, string, } from 'zod' @@ -230,10 +231,9 @@ const interests = object({ export const experienceZodForm = intersection( education.and(school).and(program).and(interests), object({ - // TODO: Resume Stuff - // resume_link: urlField.min(1, 'Required'), - // resume_filename: textField, - // resume_hash: textField, + resume_file_name: string().min(1, 'Required'), + resume_link: string().min(1, 'Required'), + resume_update_count: number(), portfolio: urlField.or(literal('')).or(literal(undefined)), github: urlField.or(literal('')).or(literal(undefined)), linkedin: urlField.or(literal('')).or(literal(undefined)), From f647097e6cbf8c24f57a1fe2bb8c1a219468b4d3 Mon Sep 17 00:00:00 2001 From: hana-dowe Date: Tue, 26 Dec 2023 22:09:28 -0500 Subject: [PATCH 2/3] Make it actually look nice Co-authored-by: Anthony Tedja --- .vscode/settings.json | 3 +- api/schema.ts | 9 +- .../RegistrationForms/AboutYou/index.tsx | 4 +- .../RegistrationForms/Experience/index.tsx | 4 +- .../FormComponents/FormResumeUpload/index.tsx | 153 ++++++++++++++---- .../RegistrationForms/Review/index.tsx | 19 ++- pages/dashboard/registration/index.tsx | 20 ++- pages/privacy/index.tsx | 8 +- types/Application/index.ts | 14 +- 9 files changed, 178 insertions(+), 56 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 41af139..4c1a9ed 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,7 +3,8 @@ "editor.defaultFormatter": "esbenp.prettier-vscode", // Fix all autofixable errors on file save "editor.codeActionsOnSave": { - "source.fixAll": "explicit" + "source.fixAll": "explicit", + "source.organizeImports": "never" }, // Fix formatting issues on file save "editor.formatOnSave": true, diff --git a/api/schema.ts b/api/schema.ts index c58b222..9aba5ef 100644 --- a/api/schema.ts +++ b/api/schema.ts @@ -1,6 +1,11 @@ import { APITemplate } from '@/api/types' import { CustomFetch } from '@/api/useFetch' -import { ApplicationGetResp, ApplicationUpdateReq, ResumeGetResp } from '@/types/Application' +import { + ApplicationGetResp, + ApplicationUpdateReq, + ResumeGetResp, + ResumeUpdateResp, +} from '@/types/Application' import { EmailVerifyReq, EmailVerifyResp } from '@/types/Email' import { EventListResp } from '@/types/Event' import { PhotoListResp } from '@/types/Photo' @@ -36,7 +41,7 @@ const application = (customFetch: CustomFetch) => const res = await customFetch('POST', 'DH_BE', '/resume-update', args, { isForm: true, }) - return res.data as ResumeGetResp + return res.data as ResumeUpdateResp }, } as const) diff --git a/components/Dashboard/RegistrationForms/AboutYou/index.tsx b/components/Dashboard/RegistrationForms/AboutYou/index.tsx index 1149bd1..9afc6c1 100644 --- a/components/Dashboard/RegistrationForms/AboutYou/index.tsx +++ b/components/Dashboard/RegistrationForms/AboutYou/index.tsx @@ -116,7 +116,7 @@ const AboutYou = (props: Props) => { Profile Details - 💍 Tell me about yourself girlll + 💍 Tell me about yourself girl { Location - 🫣 So I can meet your mama + 😝 Where's the party at? { link={getValues('resume_link')} updateCount={getValues('resume_update_count')} error={errors.resume_link} - onSuccess={(resp: ResumeGetResp) => { + onSuccess={(resp: ResumeUpdateResp) => { setValue('resume_file_name', resp.resume_file_name, { shouldValidate: true }) setValue('resume_link', resp.resume_link, { shouldValidate: true }) setValue('resume_update_count', resp.resume_update_count, { shouldValidate: true }) diff --git a/components/Dashboard/RegistrationForms/FormComponents/FormResumeUpload/index.tsx b/components/Dashboard/RegistrationForms/FormComponents/FormResumeUpload/index.tsx index 136709e..1b34cce 100644 --- a/components/Dashboard/RegistrationForms/FormComponents/FormResumeUpload/index.tsx +++ b/components/Dashboard/RegistrationForms/FormComponents/FormResumeUpload/index.tsx @@ -1,16 +1,26 @@ import { useRef } from 'react' import { FieldError } from 'react-hook-form' -import Box from '@mui/material/Box' -import Link from '@mui/material/Link' +import CloudDownloadIcon from '@mui/icons-material/CloudDownload' +import CloudUploadIcon from '@mui/icons-material/CloudUpload' +import UploadFileIcon from '@mui/icons-material/UploadFile' +import Alert from '@mui/material/Alert' +import Button from '@mui/material/Button' +import CircularProgress from '@mui/material/CircularProgress' +import Collapse from '@mui/material/Collapse' +import Fab from '@mui/material/Fab' +import Grid from '@mui/material/Grid' +import Tooltip from '@mui/material/Tooltip' import Typography from '@mui/material/Typography' +import { APIError } from '@/api/types' import LoadingButton from '@/components/Dashboard/LoadingButton' import { useToast } from '@/contexts/Toast' import { useResumeUpdate } from '@/hooks/Application/useResumeUpdate' -import { ResumeGetResp } from '@/types/Application' +import theme from '@/styles/theme' +import { ResumeUpdateResp } from '@/types/Application' -const MAX_FILE_SIZE = 2000000 // 2MB +const MAX_FILE_SIZE = 2000000 // 2 MB const MAX_UPDATE_COUNT = 3 type Props = { @@ -18,7 +28,7 @@ type Props = { link: string updateCount: number error?: FieldError - onSuccess: (resp: ResumeGetResp) => void + onSuccess: (resp: ResumeUpdateResp) => void } const FormResumeUpload = (props: Props) => { @@ -34,6 +44,11 @@ const FormResumeUpload = (props: Props) => { const file = e.currentTarget.files[0] if (!file) return + // Reset the input field so that the same file can be handled again + if (inputRef.current) { + inputRef.current.value = '' + } + const fileName = file.name if (fileName.length > 128) { setToast({ @@ -47,7 +62,7 @@ const FormResumeUpload = (props: Props) => { if (fileName.split('.').pop() !== 'pdf') { setToast({ type: 'error', - message: 'File type must be a pdf', + message: 'File type must be PDF', autoHide: false, }) return @@ -56,7 +71,7 @@ const FormResumeUpload = (props: Props) => { if (file.size > MAX_FILE_SIZE) { setToast({ type: 'error', - message: 'File size must be less than 2MB', + message: 'Max file size is 2 MB', autoHide: false, }) return @@ -66,17 +81,27 @@ const FormResumeUpload = (props: Props) => { data.append('file', file) updateResume(data, { onSuccess: (resp) => { - onSuccess(resp) // want toast on success so it hides any errors that didn't auto-hide - setToast({ - type: 'success', - message: 'Resume successfully uploaded', - }) + if (updateCount === resp.resume_update_count) { + setToast({ + type: 'info', + message: 'No changes detected in resume', + }) + } else { + setToast({ + type: 'success', + message: 'Resume successfully uploaded', + }) + onSuccess(resp) + } }, - onError: () => { + onError: (err) => { setToast({ type: 'error', - message: 'something went wrong :(', + message: + (err as APIError).apiError.status == 400 + ? 'Bad Request. Please review your resume and try again.' + : 'Oops, something went wrong. Please try again.', autoHide: false, }) }, @@ -84,26 +109,92 @@ const FormResumeUpload = (props: Props) => { } return ( - - + <> + - { - e.stopPropagation() - inputRef.current?.click() + + + + {`${MAX_UPDATE_COUNT - updateCount} update(s) remaining (bc we're broke bois).`} + + ACCEPTED FILE FORMAT: PDF - MAX SIZE 2 MB + + + + + 0} + sx={{ + width: '100%', + '& .MuiCollapse-wrapperInner': { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + gap: '1rem', + }, }} - disabled={updateCount >= MAX_UPDATE_COUNT} > - Upload Resume - - {MAX_UPDATE_COUNT - updateCount} uploads left - - - {name} - - {error && {error.message}} - + + {updateCount < MAX_UPDATE_COUNT && ( + + { + e.stopPropagation() + inputRef.current?.click() + }} + sx={{ minWidth: '56px', zIndex: 1 }} + > + {isLoading ? : } + + + )} + + + = MAX_UPDATE_COUNT} + onClick={(e) => { + e.stopPropagation() + inputRef.current?.click() + }} + sx={{ + border: '1px dashed rgba(255, 255, 255, 0.4)', + ...(error && { border: `1px dashed ${theme.palette.error.main}` }), + flexDirection: 'column', + p: '1rem', + }} + > + + Upload Resume + + {error && {error.message}} + + + ) } diff --git a/components/Dashboard/RegistrationForms/Review/index.tsx b/components/Dashboard/RegistrationForms/Review/index.tsx index dc9dc8a..bebbddd 100644 --- a/components/Dashboard/RegistrationForms/Review/index.tsx +++ b/components/Dashboard/RegistrationForms/Review/index.tsx @@ -2,6 +2,7 @@ import { ReactNode } from 'react' import CheckIcon from '@mui/icons-material/Check' import DoDisturbIcon from '@mui/icons-material/DoDisturb' +import DownloadRoundedIcon from '@mui/icons-material/DownloadRounded' import InfoIcon from '@mui/icons-material/Info' import Box from '@mui/material/Box' import Button from '@mui/material/Button' @@ -75,8 +76,22 @@ const FormReview = (props: Props) => { name="Resume" value={application.resume_file_name} valueNode={ - - {application.resume_file_name} + + {application.resume_file_name} + } /> diff --git a/pages/dashboard/registration/index.tsx b/pages/dashboard/registration/index.tsx index 508030a..bde3df4 100644 --- a/pages/dashboard/registration/index.tsx +++ b/pages/dashboard/registration/index.tsx @@ -284,7 +284,7 @@ const Registration = (props: Props) => { ...(activeStep !== i && { height: 0, paddingY: 0 }), }} > - + {section == 'AboutYou' && ( { data: resumeData, isLoading: resumeLoading, isError: resumeError, - } = useResumeGet({ enabled }) + } = useResumeGet({ enabled: enabled && !!applicationData }) if (!toggles.dashboard && !toggles.bypassPage) return if (!loading && !authenticated) return @@ -427,12 +427,24 @@ const RegistrationLoader = () => { {user.status === 'registering' ? ( ) : ( )} diff --git a/pages/privacy/index.tsx b/pages/privacy/index.tsx index d043add..2658e09 100644 --- a/pages/privacy/index.tsx +++ b/pages/privacy/index.tsx @@ -387,11 +387,7 @@ const Privacy = () => { You can request access, update, or deletion of your personal data at{' '} - + hello@deerhacks.ca . Compliance with your request will occur within 30 days, barring legal or exceptional @@ -452,7 +448,7 @@ const Privacy = () => { We are always open to feedback! For suggestions or questions about this Policy or our Service, please contact us at{' '} - + hello@deerhacks.ca . diff --git a/types/Application/index.ts b/types/Application/index.ts index 6b51eaf..3364437 100644 --- a/types/Application/index.ts +++ b/types/Application/index.ts @@ -8,6 +8,14 @@ export type ApplicationUpdateReq = { is_draft: boolean } +export type ResumeUpdateResp = { + resume_file_name: string + resume_link: string + resume_update_count: number +} + +export type ResumeGetResp = ResumeUpdateResp | {} + export type Application = { /** * User Fields, Outside of Application @@ -513,9 +521,3 @@ export const deerhacksReachOptions = [ 'Word of Mouth', OTHER_SPECIFY, ] as const - -export type ResumeGetResp = { - resume_file_name: string - resume_link: string - resume_update_count: number -} From 95008342f44f19db8cdb2992abf6b3d6aa05a89a Mon Sep 17 00:00:00 2001 From: Anthony Tedja Date: Tue, 26 Dec 2023 22:34:40 -0500 Subject: [PATCH 3/3] Small Fixes --- .../FormComponents/FormDynamicSelect/index.tsx | 2 +- pages/dashboard/registration/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/Dashboard/RegistrationForms/FormComponents/FormDynamicSelect/index.tsx b/components/Dashboard/RegistrationForms/FormComponents/FormDynamicSelect/index.tsx index 39db273..299fa7e 100644 --- a/components/Dashboard/RegistrationForms/FormComponents/FormDynamicSelect/index.tsx +++ b/components/Dashboard/RegistrationForms/FormComponents/FormDynamicSelect/index.tsx @@ -46,7 +46,7 @@ const FormDynamicSelect = (props: Props) => { onInputChange={(e, value, reason) => { if (reason === 'input') setInput(value) }} - value={value} + value={value || null} filterOptions={filterOptions} forcePopupIcon autoComplete diff --git a/pages/dashboard/registration/index.tsx b/pages/dashboard/registration/index.tsx index bde3df4..c37887e 100644 --- a/pages/dashboard/registration/index.tsx +++ b/pages/dashboard/registration/index.tsx @@ -134,7 +134,7 @@ const Registration = (props: Props) => { scrollToTop() setToast({ type: 'success', - message: 'Your Application was Submitted Successfully!', + message: 'Your application was submitted successfully!', }) } },