mirror of
https://github.com/yangshun/tech-interview-handbook.git
synced 2025-07-28 04:33:42 +08:00
[resumes][feat] update submit form to be more compact (#414)
This commit is contained in:
@ -60,7 +60,7 @@ export const SORT_OPTIONS: Record<string, string> = {
|
|||||||
topComments: 'Most Comments',
|
topComments: 'Most Comments',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ROLE: Array<FilterOption<RoleFilter>> = [
|
export const ROLES: Array<FilterOption<RoleFilter>> = [
|
||||||
{
|
{
|
||||||
label: 'Full-Stack Engineer',
|
label: 'Full-Stack Engineer',
|
||||||
value: 'Full-Stack Engineer',
|
value: 'Full-Stack Engineer',
|
||||||
@ -72,7 +72,7 @@ export const ROLE: Array<FilterOption<RoleFilter>> = [
|
|||||||
{ label: 'Android Engineer', value: 'Android Engineer' },
|
{ label: 'Android Engineer', value: 'Android Engineer' },
|
||||||
];
|
];
|
||||||
|
|
||||||
export const EXPERIENCE: Array<FilterOption<ExperienceFilter>> = [
|
export const EXPERIENCES: Array<FilterOption<ExperienceFilter>> = [
|
||||||
{ label: 'Freshman', value: 'Freshman' },
|
{ label: 'Freshman', value: 'Freshman' },
|
||||||
{ label: 'Sophomore', value: 'Sophomore' },
|
{ label: 'Sophomore', value: 'Sophomore' },
|
||||||
{ label: 'Junior', value: 'Junior' },
|
{ label: 'Junior', value: 'Junior' },
|
||||||
@ -91,16 +91,16 @@ export const EXPERIENCE: Array<FilterOption<ExperienceFilter>> = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const LOCATION: Array<FilterOption<LocationFilter>> = [
|
export const LOCATIONS: Array<FilterOption<LocationFilter>> = [
|
||||||
{ label: 'Singapore', value: 'Singapore' },
|
{ label: 'Singapore', value: 'Singapore' },
|
||||||
{ label: 'United States', value: 'United States' },
|
{ label: 'United States', value: 'United States' },
|
||||||
{ label: 'India', value: 'India' },
|
{ label: 'India', value: 'India' },
|
||||||
];
|
];
|
||||||
|
|
||||||
export const INITIAL_FILTER_STATE: FilterState = {
|
export const INITIAL_FILTER_STATE: FilterState = {
|
||||||
experience: Object.values(EXPERIENCE).map(({ value }) => value),
|
experience: Object.values(EXPERIENCES).map(({ value }) => value),
|
||||||
location: Object.values(LOCATION).map(({ value }) => value),
|
location: Object.values(LOCATIONS).map(({ value }) => value),
|
||||||
role: Object.values(ROLE).map(({ value }) => value),
|
role: Object.values(ROLES).map(({ value }) => value),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SHORTCUTS: Array<Shortcut> = [
|
export const SHORTCUTS: Array<Shortcut> = [
|
||||||
|
@ -27,11 +27,11 @@ import type {
|
|||||||
} from '~/components/resumes/browse/resumeFilters';
|
} from '~/components/resumes/browse/resumeFilters';
|
||||||
import {
|
import {
|
||||||
BROWSE_TABS_VALUES,
|
BROWSE_TABS_VALUES,
|
||||||
EXPERIENCE,
|
EXPERIENCES,
|
||||||
INITIAL_FILTER_STATE,
|
INITIAL_FILTER_STATE,
|
||||||
isInitialFilterState,
|
isInitialFilterState,
|
||||||
LOCATION,
|
LOCATIONS,
|
||||||
ROLE,
|
ROLES,
|
||||||
SHORTCUTS,
|
SHORTCUTS,
|
||||||
SORT_OPTIONS,
|
SORT_OPTIONS,
|
||||||
} from '~/components/resumes/browse/resumeFilters';
|
} from '~/components/resumes/browse/resumeFilters';
|
||||||
@ -51,17 +51,17 @@ const filters: Array<Filter> = [
|
|||||||
{
|
{
|
||||||
id: 'role',
|
id: 'role',
|
||||||
label: 'Role',
|
label: 'Role',
|
||||||
options: ROLE,
|
options: ROLES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'experience',
|
id: 'experience',
|
||||||
label: 'Experience',
|
label: 'Experience',
|
||||||
options: EXPERIENCE,
|
options: EXPERIENCES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'location',
|
id: 'location',
|
||||||
label: 'Location',
|
label: 'Location',
|
||||||
options: LOCATION,
|
options: LOCATIONS,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -18,11 +18,10 @@ import {
|
|||||||
TextInput,
|
TextInput,
|
||||||
} from '@tih/ui';
|
} from '@tih/ui';
|
||||||
|
|
||||||
import type { Filter } from '~/components/resumes/browse/resumeFilters';
|
|
||||||
import {
|
import {
|
||||||
EXPERIENCE,
|
EXPERIENCES,
|
||||||
LOCATION,
|
LOCATIONS,
|
||||||
ROLE,
|
ROLES,
|
||||||
} from '~/components/resumes/browse/resumeFilters';
|
} from '~/components/resumes/browse/resumeFilters';
|
||||||
import SubmissionGuidelines from '~/components/resumes/submit-form/SubmissionGuidelines';
|
import SubmissionGuidelines from '~/components/resumes/submit-form/SubmissionGuidelines';
|
||||||
|
|
||||||
@ -47,12 +46,6 @@ type IFormInput = {
|
|||||||
title: string;
|
title: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const selectors: Array<Filter> = [
|
|
||||||
{ id: 'role', label: 'Role', options: ROLE },
|
|
||||||
{ id: 'experience', label: 'Experience Level', options: EXPERIENCE },
|
|
||||||
{ id: 'location', label: 'Location', options: LOCATION },
|
|
||||||
];
|
|
||||||
|
|
||||||
type InitFormDetails = {
|
type InitFormDetails = {
|
||||||
additionalInfo?: string;
|
additionalInfo?: string;
|
||||||
experience: string;
|
experience: string;
|
||||||
@ -261,11 +254,13 @@ export default function SubmitResumeForm({
|
|||||||
onClose={() => setIsDialogShown(false)}>
|
onClose={() => setIsDialogShown(false)}>
|
||||||
Note that your current input will not be saved!
|
Note that your current input will not be saved!
|
||||||
</Dialog>
|
</Dialog>
|
||||||
<div className="mx-20 space-y-4 py-8">
|
<form
|
||||||
<form onSubmit={handleSubmit(onSubmit)}>
|
className="mt-8 w-full max-w-screen-lg space-y-6 self-center rounded-lg bg-white p-10 shadow-lg"
|
||||||
<h1 className="mb-4 text-2xl font-bold">Upload a resume</h1>
|
onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<h1 className="mb-4 text-center text-2xl font-semibold">
|
||||||
|
{isNewForm ? 'Upload a resume' : 'Update details'}
|
||||||
|
</h1>
|
||||||
{/* Title Section */}
|
{/* Title Section */}
|
||||||
<div className="mb-4">
|
|
||||||
<TextInput
|
<TextInput
|
||||||
{...register('title', { required: true })}
|
{...register('title', { required: true })}
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
@ -274,20 +269,36 @@ export default function SubmitResumeForm({
|
|||||||
required={true}
|
required={true}
|
||||||
onChange={(val) => setValue('title', val)}
|
onChange={(val) => setValue('title', val)}
|
||||||
/>
|
/>
|
||||||
</div>
|
<div className="flex gap-12">
|
||||||
{/* Selectors */}
|
|
||||||
{selectors.map((item) => (
|
|
||||||
<div key={item.id} className="mb-4">
|
|
||||||
<Select
|
<Select
|
||||||
{...register(item.id, { required: true })}
|
{...register('role', { required: true })}
|
||||||
|
defaultValue={undefined}
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
label={item.label}
|
label="Role"
|
||||||
options={item.options}
|
options={ROLES}
|
||||||
|
placeholder=" "
|
||||||
required={true}
|
required={true}
|
||||||
onChange={(val) => setValue(item.id, val)}
|
onChange={(val) => setValue('role', val)}
|
||||||
|
/>
|
||||||
|
<Select
|
||||||
|
{...register('experience', { required: true })}
|
||||||
|
disabled={isLoading}
|
||||||
|
label="Experience Level"
|
||||||
|
options={EXPERIENCES}
|
||||||
|
placeholder=" "
|
||||||
|
required={true}
|
||||||
|
onChange={(val) => setValue('experience', val)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
))}
|
<Select
|
||||||
|
{...register('location', { required: true })}
|
||||||
|
disabled={isLoading}
|
||||||
|
label="Location"
|
||||||
|
options={LOCATIONS}
|
||||||
|
placeholder=" "
|
||||||
|
required={true}
|
||||||
|
onChange={(val) => setValue('location', val)}
|
||||||
|
/>
|
||||||
{/* Upload resume form */}
|
{/* Upload resume form */}
|
||||||
{isNewForm && (
|
{isNewForm && (
|
||||||
<>
|
<>
|
||||||
@ -302,9 +313,7 @@ export default function SubmitResumeForm({
|
|||||||
<div
|
<div
|
||||||
{...getRootProps()}
|
{...getRootProps()}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
fileUploadError
|
fileUploadError ? 'border-danger-600' : 'border-gray-300',
|
||||||
? 'border-danger-600'
|
|
||||||
: 'border-gray-300',
|
|
||||||
'mt-2 flex cursor-pointer justify-center rounded-md border-2 border-dashed bg-gray-100 px-6 pt-5 pb-6',
|
'mt-2 flex cursor-pointer justify-center rounded-md border-2 border-dashed bg-gray-100 px-6 pt-5 pb-6',
|
||||||
)}>
|
)}>
|
||||||
<div className="space-y-1 text-center">
|
<div className="space-y-1 text-center">
|
||||||
@ -348,15 +357,12 @@ export default function SubmitResumeForm({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{fileUploadError && (
|
{fileUploadError && (
|
||||||
<p className="text-danger-600 text-sm">
|
<p className="text-danger-600 text-sm">{fileUploadError}</p>
|
||||||
{fileUploadError}
|
|
||||||
</p>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{/* Additional Info Section */}
|
{/* Additional Info Section */}
|
||||||
<div className="mb-8">
|
|
||||||
<TextArea
|
<TextArea
|
||||||
{...register('additionalInfo')}
|
{...register('additionalInfo')}
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
@ -364,8 +370,9 @@ export default function SubmitResumeForm({
|
|||||||
placeholder={ADDITIONAL_INFO_PLACEHOLDER}
|
placeholder={ADDITIONAL_INFO_PLACEHOLDER}
|
||||||
onChange={(val) => setValue('additionalInfo', val)}
|
onChange={(val) => setValue('additionalInfo', val)}
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
{/* Submission Guidelines */}
|
{/* Submission Guidelines */}
|
||||||
|
{isNewForm && (
|
||||||
|
<>
|
||||||
<SubmissionGuidelines />
|
<SubmissionGuidelines />
|
||||||
<CheckboxInput
|
<CheckboxInput
|
||||||
{...register('isChecked', { required: true })}
|
{...register('isChecked', { required: true })}
|
||||||
@ -373,8 +380,10 @@ export default function SubmitResumeForm({
|
|||||||
label="I have read and will follow the guidelines stated."
|
label="I have read and will follow the guidelines stated."
|
||||||
onChange={(val) => setValue('isChecked', val)}
|
onChange={(val) => setValue('isChecked', val)}
|
||||||
/>
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
{/* Clear and Submit Buttons */}
|
{/* Clear and Submit Buttons */}
|
||||||
<div className="mt-4 flex justify-end gap-4">
|
<div className="flex justify-end gap-4">
|
||||||
<Button
|
<Button
|
||||||
addonPosition="start"
|
addonPosition="start"
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
@ -392,7 +401,6 @@ export default function SubmitResumeForm({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
</>
|
</>
|
||||||
|
@ -10,7 +10,7 @@ module.exports = {
|
|||||||
sans: ['Inter var', ...defaultTheme.fontFamily.sans],
|
sans: ['Inter var', ...defaultTheme.fontFamily.sans],
|
||||||
},
|
},
|
||||||
colors: {
|
colors: {
|
||||||
primary: colors.purple,
|
primary: colors.indigo,
|
||||||
danger: colors.rose,
|
danger: colors.rose,
|
||||||
info: colors.sky,
|
info: colors.sky,
|
||||||
success: colors.emerald,
|
success: colors.emerald,
|
||||||
|
Reference in New Issue
Block a user