[offers][feat] Use city typeahead for location field

pull/501/head
Ai Ling 3 years ago committed by Stuart Long Chay Boon
parent 64318ae6d3
commit 2e0f218d28

@ -5,10 +5,84 @@ export const JobTypeLabel = {
INTERN: 'Internship',
};
<<<<<<< HEAD
export const emptyOption = {
label: '',
value: '',
};
=======
export const internshipCycleOptions = [
{
label: 'Summer',
value: 'Summer',
},
{
label: 'Winter',
value: 'Winter',
},
{
label: 'Spring',
value: 'Spring',
},
{
label: 'Fall',
value: 'Fall',
},
{
label: 'Full year',
value: 'Full year',
},
];
export const yearOptions = [
{
label: '2021',
value: 2021,
},
{
label: '2022',
value: 2022,
},
{
label: '2023',
value: 2023,
},
{
label: '2024',
value: 2024,
},
];
export const educationLevelOptions = Object.entries(
EducationBackgroundType,
).map(([, value]) => ({
label: value,
value,
}));
export const educationFieldOptions = [
{
label: 'Computer Science',
value: 'Computer Science',
},
{
label: 'Information Security',
value: 'Information Security',
},
{
label: 'Information Systems',
value: 'Information Systems',
},
{
label: 'Business Analytics',
value: 'Business Analytics',
},
{
label: 'Data Science and Analytics',
value: 'Data Science and Analytics',
},
];
>>>>>>> a31230f7 ([offers][feat] Use city typeahead for location field)
export enum FieldError {
NON_NEGATIVE_NUMBER = 'Please fill in a non-negative number in this field.',

@ -289,6 +289,7 @@ export default function OffersSubmissionForm({
steps={breadcrumbSteps}
/>
</div>
<<<<<<< HEAD
<div className="bg-white p-6 sm:p-10">
<FormProvider {...formMethods}>
<form
@ -349,6 +350,56 @@ export default function OffersSubmissionForm({
</form>
</FormProvider>
</div>
=======
<FormProvider {...formMethods}>
<form className="text-sm" onSubmit={handleSubmit(onSubmit)}>
{steps[step]}
<pre>{JSON.stringify(formMethods.watch(), null, 2)}</pre>
{step === 0 && (
<div className="flex justify-end">
<Button
disabled={false}
icon={ArrowRightIcon}
label="Next"
variant="secondary"
onClick={() => {
goToNextStep(step);
gaEvent({
action: 'offers.profile_submission_navigate_next',
category: 'submission',
label: 'Navigate next',
});
}}
/>
</div>
)}
{step === 1 && (
<div className="flex items-center justify-between">
<Button
icon={ArrowLeftIcon}
label="Previous"
variant="secondary"
onClick={() => {
setStep(step - 1);
gaEvent({
action: 'offers.profile_submission_navigation_back',
category: 'submission',
label: 'Navigate back',
});
}}
/>
<Button
disabled={isSubmitting || isSubmitSuccessful}
isLoading={isSubmitting || isSubmitSuccessful}
label="Submit"
type="submit"
variant="primary"
/>
</div>
)}
</form>
</FormProvider>
>>>>>>> a31230f7 ([offers][feat] Use city typeahead for location field)
</div>
</div>
</div>

@ -2,7 +2,16 @@ import { useFormContext, useWatch } from 'react-hook-form';
import { JobType } from '@prisma/client';
import { Collapsible, RadioList } from '@tih/ui';
<<<<<<< HEAD
import { FieldError } from '~/components/offers/constants';
=======
import {
educationFieldOptions,
educationLevelOptions,
emptyOption,
FieldError,
} from '~/components/offers/constants';
>>>>>>> a31230f7 ([offers][feat] Use city typeahead for location field)
import type { BackgroundPostData } from '~/components/offers/types';
import CitiesTypeahead from '~/components/shared/CitiesTypeahead';
import CompaniesTypeahead from '~/components/shared/CompaniesTypeahead';
@ -255,6 +264,7 @@ function InternshipJobFields() {
}}
/>
</div>
<<<<<<< HEAD
<FormTextInput
endAddOn={
<FormSelect
@ -280,6 +290,10 @@ function InternshipJobFields() {
/>
<Collapsible label="Add more details">
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2">
=======
<Collapsible label="Add more details">
<div className="mb-5 grid grid-cols-2 space-x-3">
>>>>>>> a31230f7 ([offers][feat] Use city typeahead for location field)
<CitiesTypeahead
label="Location"
value={{
@ -296,6 +310,7 @@ function InternshipJobFields() {
setValue('background.experiences.0.cityName', '');
}
}}
<<<<<<< HEAD
/>
<FormTextInput
errorMessage={experiencesField?.durationInMonths?.message}
@ -305,6 +320,8 @@ function InternshipJobFields() {
min: { message: FieldError.NON_NEGATIVE_NUMBER, value: 0 },
valueAsNumber: true,
})}
=======
>>>>>>> a31230f7 ([offers][feat] Use city typeahead for location field)
/>
</div>
</Collapsible>

@ -22,7 +22,16 @@ import {
defaultFullTimeOfferValues,
defaultInternshipOfferValues,
} from '../OffersSubmissionForm';
<<<<<<< HEAD
import { FieldError, JobTypeLabel } from '../../constants';
=======
import {
emptyOption,
FieldError,
internshipCycleOptions,
yearOptions,
} from '../../constants';
>>>>>>> a31230f7 ([offers][feat] Use city typeahead for location field)
import FormMonthYearPicker from '../../forms/FormMonthYearPicker';
import FormSection from '../../forms/FormSection';
import FormSelect from '../../forms/FormSelect';
@ -106,6 +115,7 @@ function FullTimeOfferDetailsForm({
})}
/>
</div>
<<<<<<< HEAD
<div className="grid grid-cols-1 gap-y-4 sm:grid-cols-2 sm:gap-6">
<CompaniesTypeahead
required={true}
@ -148,6 +158,93 @@ function FullTimeOfferDetailsForm({
monthRequired={true}
yearLabel=""
{...register(`offers.${index}.monthYearReceived`, {
=======
<FormTextInput
errorMessage={offerFields?.offersFullTime?.level?.message}
label="Level"
placeholder="e.g. L4, Junior"
required={true}
{...register(`offers.${index}.offersFullTime.level`, {
required: FieldError.REQUIRED,
})}
/>
</div>
<div className="mb-5 flex grid grid-cols-2 space-x-3">
<CompaniesTypeahead
required={true}
value={{
id: watchCompanyId,
label: watchCompanyName,
value: watchCompanyId,
}}
onSelect={(option) => {
if (option) {
setValue(`offers.${index}.companyId`, option.value);
setValue(`offers.${index}.companyName`, option.label);
}
}}
/>
<CitiesTypeahead
label="Location"
required={true}
value={{
id: watchCityId,
label: watchCityName,
value: watchCityId,
}}
onSelect={(option) => {
if (option) {
setValue(`offers.${index}.cityId`, option.value);
setValue(`offers.${index}.cityName`, option.label);
} else {
setValue(`offers.${index}.cityId`, '');
setValue(`offers.${index}.cityName`, '');
}
}}
/>
</div>
<div className="mb-5 flex grid grid-cols-2 items-start space-x-3">
<FormMonthYearPicker
monthLabel="Date Received"
monthRequired={true}
yearLabel=""
{...register(`offers.${index}.monthYearReceived`, {
required: FieldError.REQUIRED,
})}
/>
</div>
<div className="mb-5">
<FormTextInput
endAddOn={
<FormSelect
borderStyle="borderless"
defaultValue={Currency.SGD}
isLabelHidden={true}
label="Currency"
options={CURRENCY_OPTIONS}
{...register(
`offers.${index}.offersFullTime.totalCompensation.currency`,
{
required: FieldError.REQUIRED,
},
)}
/>
}
endAddOnType="element"
errorMessage={
offerFields?.offersFullTime?.totalCompensation?.value?.message
}
label="Total Compensation (Annual)"
placeholder="0"
required={true}
startAddOn="$"
startAddOnType="label"
type="number"
{...register(
`offers.${index}.offersFullTime.totalCompensation.value`,
{
min: { message: FieldError.NON_NEGATIVE_NUMBER, value: 0 },
>>>>>>> a31230f7 ([offers][feat] Use city typeahead for location field)
required: FieldError.REQUIRED,
})}
/>
@ -375,6 +472,7 @@ function InternshipOfferDetailsForm({
}}
/>
</div>
<<<<<<< HEAD
<div className="grid grid-cols-1 gap-y-4 sm:grid-cols-2 sm:gap-6">
<FormSelect
display="block"
@ -444,6 +542,97 @@ function InternshipOfferDetailsForm({
</div>
</FormSection>
<FormSection title="Additional Information">
=======
<CitiesTypeahead
label="Location"
required={true}
value={{
id: watchCityId,
label: watchCityName,
value: watchCityId,
}}
onSelect={(option) => {
if (option) {
setValue(`offers.${index}.cityId`, option.value);
setValue(`offers.${index}.cityName`, option.label);
} else {
setValue(`offers.${index}.cityId`, '');
setValue(`offers.${index}.cityName`, '');
}
}}
/>
</div>
<div className="mb-5 grid grid-cols-2 space-x-3">
<FormSelect
display="block"
errorMessage={offerFields?.offersIntern?.internshipCycle?.message}
label="Internship Cycle"
options={internshipCycleOptions}
placeholder={emptyOption}
required={true}
{...register(`offers.${index}.offersIntern.internshipCycle`, {
required: FieldError.REQUIRED,
})}
/>
<FormSelect
display="block"
errorMessage={offerFields?.offersIntern?.startYear?.message}
label="Internship Year"
options={yearOptions}
placeholder={emptyOption}
required={true}
{...register(`offers.${index}.offersIntern.startYear`, {
required: FieldError.REQUIRED,
valueAsNumber: true,
})}
/>
</div>
<div className="mb-5">
<FormMonthYearPicker
monthLabel="Date Received"
monthRequired={true}
yearLabel=""
{...register(`offers.${index}.monthYearReceived`, {
required: FieldError.REQUIRED,
})}
/>
</div>
<div className="mb-5">
<FormTextInput
endAddOn={
<FormSelect
borderStyle="borderless"
defaultValue={Currency.SGD}
isLabelHidden={true}
label="Currency"
options={CURRENCY_OPTIONS}
{...register(
`offers.${index}.offersIntern.monthlySalary.currency`,
{
required: FieldError.REQUIRED,
},
)}
/>
}
endAddOnType="element"
errorMessage={
offerFields?.offersIntern?.monthlySalary?.value?.message
}
label="Salary (Monthly)"
placeholder="0"
required={true}
startAddOn="$"
startAddOnType="label"
type="number"
{...register(`offers.${index}.offersIntern.monthlySalary.value`, {
min: { message: FieldError.NON_NEGATIVE_NUMBER, value: 0 },
required: FieldError.REQUIRED,
valueAsNumber: true,
})}
/>
</div>
<div className="mb-5">
>>>>>>> a31230f7 ([offers][feat] Use city typeahead for location field)
<FormTextArea
label="Negotiation Strategy / Interview Performance"
placeholder="e.g. Did well in the behavioral interview. Used competing offers to negotiate for a higher salary."

@ -58,9 +58,12 @@ type ExperiencePostData = {
jobType?: string | null;
level?: string | null;
<<<<<<< HEAD
<<<<<<< HEAD
=======
location?: Location | null;
>>>>>>> ac2d047d ([offers][feat] integrate location for offer table and profile)
=======
>>>>>>> a31230f7 ([offers][feat] Use city typeahead for location field)
monthlySalary?: Money | null;
title?: string | null;
totalCompensation?: Money | null;

Loading…
Cancel
Save