mirror of
https://github.com/yangshun/tech-interview-handbook.git
synced 2025-08-01 06:33:52 +08:00
[offers][fix] Fix offer submission form (#372)
* [offers][fix] Fix breadcrumbs alignment * [offers][fix] Fix field array
This commit is contained in:
@ -7,7 +7,7 @@ export function Breadcrumbs({ stepLabels, currentStep }: BreadcrumbsProps) {
|
|||||||
return (
|
return (
|
||||||
<div className="flex space-x-1">
|
<div className="flex space-x-1">
|
||||||
{stepLabels.map((label, index) => (
|
{stepLabels.map((label, index) => (
|
||||||
<div key={label}>
|
<div key={label} className="flex space-x-1">
|
||||||
{index === currentStep ? (
|
{index === currentStep ? (
|
||||||
<p className="text-sm text-purple-700">{label}</p>
|
<p className="text-sm text-purple-700">{label}</p>
|
||||||
) : (
|
) : (
|
||||||
|
@ -7,6 +7,11 @@ import { PlusIcon } from '@heroicons/react/20/solid';
|
|||||||
import { TrashIcon } from '@heroicons/react/24/outline';
|
import { TrashIcon } from '@heroicons/react/24/outline';
|
||||||
import { Button, Dialog } from '@tih/ui';
|
import { Button, Dialog } from '@tih/ui';
|
||||||
|
|
||||||
|
import {
|
||||||
|
defaultFullTimeOfferValues,
|
||||||
|
defaultInternshipOfferValues,
|
||||||
|
} from '~/pages/offers/submit';
|
||||||
|
|
||||||
import FormMonthYearPicker from './components/FormMonthYearPicker';
|
import FormMonthYearPicker from './components/FormMonthYearPicker';
|
||||||
import FormSelect from './components/FormSelect';
|
import FormSelect from './components/FormSelect';
|
||||||
import FormTextArea from './components/FormTextArea';
|
import FormTextArea from './components/FormTextArea';
|
||||||
@ -479,7 +484,13 @@ function OfferDetailsFormArray({
|
|||||||
label="Add another offer"
|
label="Add another offer"
|
||||||
size="lg"
|
size="lg"
|
||||||
variant="tertiary"
|
variant="tertiary"
|
||||||
onClick={() => append({})}
|
onClick={() =>
|
||||||
|
append(
|
||||||
|
jobType === JobType.FullTime
|
||||||
|
? defaultFullTimeOfferValues
|
||||||
|
: defaultInternshipOfferValues,
|
||||||
|
)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -488,16 +499,18 @@ function OfferDetailsFormArray({
|
|||||||
export default function OfferDetailsForm() {
|
export default function OfferDetailsForm() {
|
||||||
const [jobType, setJobType] = useState(JobType.FullTime);
|
const [jobType, setJobType] = useState(JobType.FullTime);
|
||||||
const [isDialogOpen, setDialogOpen] = useState(false);
|
const [isDialogOpen, setDialogOpen] = useState(false);
|
||||||
const { control, register } = useFormContext();
|
const { control } = useFormContext();
|
||||||
const fieldArrayValues = useFieldArray({ control, name: 'offers' });
|
const fieldArrayValues = useFieldArray({ control, name: 'offers' });
|
||||||
|
|
||||||
const toggleJobType = () => {
|
const toggleJobType = () => {
|
||||||
|
fieldArrayValues.remove();
|
||||||
if (jobType === JobType.FullTime) {
|
if (jobType === JobType.FullTime) {
|
||||||
setJobType(JobType.Internship);
|
setJobType(JobType.Internship);
|
||||||
|
fieldArrayValues.append(defaultInternshipOfferValues);
|
||||||
} else {
|
} else {
|
||||||
setJobType(JobType.FullTime);
|
setJobType(JobType.FullTime);
|
||||||
|
fieldArrayValues.append(defaultFullTimeOfferValues);
|
||||||
}
|
}
|
||||||
fieldArrayValues.remove();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const switchJobTypeLabel = () =>
|
const switchJobTypeLabel = () =>
|
||||||
@ -523,7 +536,6 @@ export default function OfferDetailsForm() {
|
|||||||
}
|
}
|
||||||
setDialogOpen(true);
|
setDialogOpen(true);
|
||||||
}}
|
}}
|
||||||
{...register(`offers.${0}.jobType`)}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx-5 w-1/3">
|
<div className="mx-5 w-1/3">
|
||||||
@ -538,7 +550,6 @@ export default function OfferDetailsForm() {
|
|||||||
}
|
}
|
||||||
setDialogOpen(true);
|
setDialogOpen(true);
|
||||||
}}
|
}}
|
||||||
{...register(`offers.${0}.jobType`)}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -21,25 +21,35 @@ import { getCurrentMonth, getCurrentYear } from '~/utils/offers/time';
|
|||||||
import { trpc } from '~/utils/trpc';
|
import { trpc } from '~/utils/trpc';
|
||||||
|
|
||||||
const defaultOfferValues = {
|
const defaultOfferValues = {
|
||||||
|
comments: '',
|
||||||
|
companyId: '',
|
||||||
|
job: {},
|
||||||
|
jobType: JobType.FullTime,
|
||||||
|
location: '',
|
||||||
|
monthYearReceived: {
|
||||||
|
month: getCurrentMonth() as Month,
|
||||||
|
year: getCurrentYear(),
|
||||||
|
},
|
||||||
|
negotiationStrategy: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const defaultFullTimeOfferValues = {
|
||||||
|
...defaultOfferValues,
|
||||||
|
jobType: JobType.FullTime,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const defaultInternshipOfferValues = {
|
||||||
|
...defaultOfferValues,
|
||||||
|
jobType: JobType.Internship,
|
||||||
|
};
|
||||||
|
|
||||||
|
const defaultOfferProfileValues = {
|
||||||
background: {
|
background: {
|
||||||
educations: [],
|
educations: [],
|
||||||
experiences: [{ jobType: JobType.FullTime }],
|
experiences: [{ jobType: JobType.FullTime }],
|
||||||
specificYoes: [],
|
specificYoes: [],
|
||||||
},
|
},
|
||||||
offers: [
|
offers: [defaultOfferValues],
|
||||||
{
|
|
||||||
comments: '',
|
|
||||||
companyId: '',
|
|
||||||
job: {},
|
|
||||||
jobType: JobType.FullTime,
|
|
||||||
location: '',
|
|
||||||
monthYearReceived: {
|
|
||||||
month: getCurrentMonth() as Month,
|
|
||||||
year: getCurrentYear(),
|
|
||||||
},
|
|
||||||
negotiationStrategy: '',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
type FormStep = {
|
type FormStep = {
|
||||||
@ -55,7 +65,7 @@ export default function OffersSubmissionPage() {
|
|||||||
const scrollToTop = () =>
|
const scrollToTop = () =>
|
||||||
pageRef.current?.scrollTo({ behavior: 'smooth', top: 0 });
|
pageRef.current?.scrollTo({ behavior: 'smooth', top: 0 });
|
||||||
const formMethods = useForm<OfferProfileFormData>({
|
const formMethods = useForm<OfferProfileFormData>({
|
||||||
defaultValues: defaultOfferValues,
|
defaultValues: defaultOfferProfileValues,
|
||||||
mode: 'all',
|
mode: 'all',
|
||||||
});
|
});
|
||||||
const { handleSubmit, trigger } = formMethods;
|
const { handleSubmit, trigger } = formMethods;
|
||||||
@ -121,8 +131,17 @@ export default function OffersSubmissionPage() {
|
|||||||
if (!result) {
|
if (!result) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = removeInvalidMoneyData(data);
|
data = removeInvalidMoneyData(data);
|
||||||
|
|
||||||
const background = cleanObject(data.background);
|
const background = cleanObject(data.background);
|
||||||
|
background.specificYoes = data.background.specificYoes.filter(
|
||||||
|
(specificYoe) => specificYoe.domain && specificYoe.yoe > 0,
|
||||||
|
);
|
||||||
|
if (Object.entries(background.experiences[0]).length === 1) {
|
||||||
|
background.experiences = [];
|
||||||
|
}
|
||||||
|
|
||||||
const offers = data.offers.map((offer: OfferDetailsFormData) => ({
|
const offers = data.offers.map((offer: OfferDetailsFormData) => ({
|
||||||
...offer,
|
...offer,
|
||||||
monthYearReceived: new Date(
|
monthYearReceived: new Date(
|
||||||
@ -130,15 +149,9 @@ export default function OffersSubmissionPage() {
|
|||||||
offer.monthYearReceived.month,
|
offer.monthYearReceived.month,
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const postData = { background, offers };
|
const postData = { background, offers };
|
||||||
|
|
||||||
postData.background.specificYoes = data.background.specificYoes.filter(
|
|
||||||
(specificYoe) => specificYoe.domain && specificYoe.yoe > 0,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (Object.entries(postData.background.experiences[0]).length === 1) {
|
|
||||||
postData.background.experiences = [];
|
|
||||||
}
|
|
||||||
createMutation.mutate(postData);
|
createMutation.mutate(postData);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user