|
|
@ -1,14 +1,10 @@
|
|
|
|
import { useState } from 'react';
|
|
|
|
import { useState } from 'react';
|
|
|
|
import type {
|
|
|
|
import type { FieldValues, UseFieldArrayReturn } from 'react-hook-form';
|
|
|
|
FieldValues,
|
|
|
|
|
|
|
|
UseFieldArrayRemove,
|
|
|
|
|
|
|
|
UseFieldArrayReturn,
|
|
|
|
|
|
|
|
} from 'react-hook-form';
|
|
|
|
|
|
|
|
import { useFormContext } from 'react-hook-form';
|
|
|
|
import { useFormContext } from 'react-hook-form';
|
|
|
|
import { useFieldArray } from 'react-hook-form';
|
|
|
|
import { useFieldArray } from 'react-hook-form';
|
|
|
|
import { PlusIcon } from '@heroicons/react/20/solid';
|
|
|
|
import { PlusIcon } from '@heroicons/react/20/solid';
|
|
|
|
import { TrashIcon } from '@heroicons/react/24/outline';
|
|
|
|
import { TrashIcon } from '@heroicons/react/24/outline';
|
|
|
|
import { Button } from '@tih/ui';
|
|
|
|
import { Button, Dialog } from '@tih/ui';
|
|
|
|
|
|
|
|
|
|
|
|
import FormMonthYearPicker from './components/FormMonthYearPicker';
|
|
|
|
import FormMonthYearPicker from './components/FormMonthYearPicker';
|
|
|
|
import FormSelect from './components/FormSelect';
|
|
|
|
import FormSelect from './components/FormSelect';
|
|
|
@ -26,17 +22,18 @@ import type {
|
|
|
|
FullTimeOfferDetailsFormData,
|
|
|
|
FullTimeOfferDetailsFormData,
|
|
|
|
InternshipOfferDetailsFormData,
|
|
|
|
InternshipOfferDetailsFormData,
|
|
|
|
} from '../types';
|
|
|
|
} from '../types';
|
|
|
|
|
|
|
|
import { JobTypeLabel } from '../types';
|
|
|
|
import { JobType } from '../types';
|
|
|
|
import { JobType } from '../types';
|
|
|
|
import { CURRENCY_OPTIONS } from '../../../utils/offers/currency/CurrencyEnum';
|
|
|
|
import { CURRENCY_OPTIONS } from '../../../utils/offers/currency/CurrencyEnum';
|
|
|
|
|
|
|
|
|
|
|
|
type FullTimeOfferDetailsFormProps = Readonly<{
|
|
|
|
type FullTimeOfferDetailsFormProps = Readonly<{
|
|
|
|
index: number;
|
|
|
|
index: number;
|
|
|
|
remove: UseFieldArrayRemove;
|
|
|
|
setDialogOpen: (isOpen: boolean) => void;
|
|
|
|
}>;
|
|
|
|
}>;
|
|
|
|
|
|
|
|
|
|
|
|
function FullTimeOfferDetailsForm({
|
|
|
|
function FullTimeOfferDetailsForm({
|
|
|
|
index,
|
|
|
|
index,
|
|
|
|
remove,
|
|
|
|
setDialogOpen,
|
|
|
|
}: FullTimeOfferDetailsFormProps) {
|
|
|
|
}: FullTimeOfferDetailsFormProps) {
|
|
|
|
const { register, formState } = useFormContext<{
|
|
|
|
const { register, formState } = useFormContext<{
|
|
|
|
offers: Array<FullTimeOfferDetailsFormData>;
|
|
|
|
offers: Array<FullTimeOfferDetailsFormData>;
|
|
|
@ -228,7 +225,7 @@ function FullTimeOfferDetailsForm({
|
|
|
|
icon={TrashIcon}
|
|
|
|
icon={TrashIcon}
|
|
|
|
label="Delete"
|
|
|
|
label="Delete"
|
|
|
|
variant="secondary"
|
|
|
|
variant="secondary"
|
|
|
|
onClick={() => remove(index)}
|
|
|
|
onClick={() => setDialogOpen(true)}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
@ -236,53 +233,14 @@ function FullTimeOfferDetailsForm({
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type OfferDetailsFormArrayProps = Readonly<{
|
|
|
|
|
|
|
|
fieldArrayValues: UseFieldArrayReturn<FieldValues, 'offers', 'id'>;
|
|
|
|
|
|
|
|
jobType: JobType;
|
|
|
|
|
|
|
|
}>;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function OfferDetailsFormArray({
|
|
|
|
|
|
|
|
fieldArrayValues,
|
|
|
|
|
|
|
|
jobType,
|
|
|
|
|
|
|
|
}: OfferDetailsFormArrayProps) {
|
|
|
|
|
|
|
|
const { append, remove, fields } = fieldArrayValues;
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
|
|
|
{fields.map((item, index) =>
|
|
|
|
|
|
|
|
jobType === JobType.FullTime ? (
|
|
|
|
|
|
|
|
<FullTimeOfferDetailsForm
|
|
|
|
|
|
|
|
key={`offer.${item.id}`}
|
|
|
|
|
|
|
|
index={index}
|
|
|
|
|
|
|
|
remove={remove}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
) : (
|
|
|
|
|
|
|
|
<InternshipOfferDetailsForm
|
|
|
|
|
|
|
|
key={`offer.${item.id}`}
|
|
|
|
|
|
|
|
index={index}
|
|
|
|
|
|
|
|
remove={remove}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
|
|
|
display="block"
|
|
|
|
|
|
|
|
icon={PlusIcon}
|
|
|
|
|
|
|
|
label="Add another offer"
|
|
|
|
|
|
|
|
size="lg"
|
|
|
|
|
|
|
|
variant="tertiary"
|
|
|
|
|
|
|
|
onClick={() => append({})}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type InternshipOfferDetailsFormProps = Readonly<{
|
|
|
|
type InternshipOfferDetailsFormProps = Readonly<{
|
|
|
|
index: number;
|
|
|
|
index: number;
|
|
|
|
remove: UseFieldArrayRemove;
|
|
|
|
setDialogOpen: (isOpen: boolean) => void;
|
|
|
|
}>;
|
|
|
|
}>;
|
|
|
|
|
|
|
|
|
|
|
|
function InternshipOfferDetailsForm({
|
|
|
|
function InternshipOfferDetailsForm({
|
|
|
|
index,
|
|
|
|
index,
|
|
|
|
remove,
|
|
|
|
setDialogOpen,
|
|
|
|
}: InternshipOfferDetailsFormProps) {
|
|
|
|
}: InternshipOfferDetailsFormProps) {
|
|
|
|
const { register, formState } = useFormContext<{
|
|
|
|
const { register, formState } = useFormContext<{
|
|
|
|
offers: Array<InternshipOfferDetailsFormData>;
|
|
|
|
offers: Array<InternshipOfferDetailsFormData>;
|
|
|
@ -409,7 +367,9 @@ function InternshipOfferDetailsForm({
|
|
|
|
icon={TrashIcon}
|
|
|
|
icon={TrashIcon}
|
|
|
|
label="Delete"
|
|
|
|
label="Delete"
|
|
|
|
variant="secondary"
|
|
|
|
variant="secondary"
|
|
|
|
onClick={() => remove(index)}
|
|
|
|
onClick={() => {
|
|
|
|
|
|
|
|
setDialogOpen(true);
|
|
|
|
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
@ -417,20 +377,99 @@ function InternshipOfferDetailsForm({
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type OfferDetailsFormArrayProps = Readonly<{
|
|
|
|
|
|
|
|
fieldArrayValues: UseFieldArrayReturn<FieldValues, 'offers', 'id'>;
|
|
|
|
|
|
|
|
jobType: JobType;
|
|
|
|
|
|
|
|
}>;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function OfferDetailsFormArray({
|
|
|
|
|
|
|
|
fieldArrayValues,
|
|
|
|
|
|
|
|
jobType,
|
|
|
|
|
|
|
|
}: OfferDetailsFormArrayProps) {
|
|
|
|
|
|
|
|
const { append, remove, fields } = fieldArrayValues;
|
|
|
|
|
|
|
|
const [isDialogOpen, setDialogOpen] = useState(false);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
|
|
|
{fields.map((item, index) => {
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<>
|
|
|
|
|
|
|
|
{jobType === JobType.FullTime ? (
|
|
|
|
|
|
|
|
<FullTimeOfferDetailsForm
|
|
|
|
|
|
|
|
key={`offer.${item.id}`}
|
|
|
|
|
|
|
|
index={index}
|
|
|
|
|
|
|
|
setDialogOpen={setDialogOpen}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
) : (
|
|
|
|
|
|
|
|
<InternshipOfferDetailsForm
|
|
|
|
|
|
|
|
key={`offer.${item.id}`}
|
|
|
|
|
|
|
|
index={index}
|
|
|
|
|
|
|
|
setDialogOpen={setDialogOpen}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
<Dialog
|
|
|
|
|
|
|
|
isShown={isDialogOpen}
|
|
|
|
|
|
|
|
primaryButton={
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
|
|
|
display="block"
|
|
|
|
|
|
|
|
label="OK"
|
|
|
|
|
|
|
|
variant="primary"
|
|
|
|
|
|
|
|
onClick={() => {
|
|
|
|
|
|
|
|
remove(index);
|
|
|
|
|
|
|
|
setDialogOpen(false);
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
secondaryButton={
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
|
|
|
display="block"
|
|
|
|
|
|
|
|
label="Cancel"
|
|
|
|
|
|
|
|
variant="tertiary"
|
|
|
|
|
|
|
|
onClick={() => setDialogOpen(false)}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
title="Remove this offer"
|
|
|
|
|
|
|
|
onClose={() => setDialogOpen(false)}>
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
|
|
|
Are you sure you want to remove this offer? This action cannot
|
|
|
|
|
|
|
|
be reversed.
|
|
|
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
</Dialog>
|
|
|
|
|
|
|
|
</>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
})}
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
|
|
|
display="block"
|
|
|
|
|
|
|
|
icon={PlusIcon}
|
|
|
|
|
|
|
|
label="Add another offer"
|
|
|
|
|
|
|
|
size="lg"
|
|
|
|
|
|
|
|
variant="tertiary"
|
|
|
|
|
|
|
|
onClick={() => append({})}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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 { control, register } = useFormContext();
|
|
|
|
const { control, register } = useFormContext();
|
|
|
|
const fieldArrayValues = useFieldArray({ control, name: 'offers' });
|
|
|
|
const fieldArrayValues = useFieldArray({ control, name: 'offers' });
|
|
|
|
|
|
|
|
|
|
|
|
const changeJobType = (jobTypeChosen: JobType) => () => {
|
|
|
|
const toggleJobType = () => {
|
|
|
|
if (jobType === jobTypeChosen) {
|
|
|
|
if (jobType === JobType.FullTime) {
|
|
|
|
return;
|
|
|
|
setJobType(JobType.Internship);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
setJobType(JobType.FullTime);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
setJobType(jobTypeChosen);
|
|
|
|
|
|
|
|
fieldArrayValues.remove();
|
|
|
|
fieldArrayValues.remove();
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const switchJobTypeLabel = () =>
|
|
|
|
|
|
|
|
jobType === JobType.FullTime
|
|
|
|
|
|
|
|
? JobTypeLabel.INTERNSHIP
|
|
|
|
|
|
|
|
: JobTypeLabel.FULLTIME;
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<div className="mb-5">
|
|
|
|
<div className="mb-5">
|
|
|
|
<h5 className="mb-8 text-center text-4xl font-bold text-gray-900">
|
|
|
|
<h5 className="mb-8 text-center text-4xl font-bold text-gray-900">
|
|
|
@ -440,20 +479,30 @@ export default function OfferDetailsForm() {
|
|
|
|
<div className="mx-5 w-1/3">
|
|
|
|
<div className="mx-5 w-1/3">
|
|
|
|
<Button
|
|
|
|
<Button
|
|
|
|
display="block"
|
|
|
|
display="block"
|
|
|
|
label="Full-time"
|
|
|
|
label={JobTypeLabel.FULLTIME}
|
|
|
|
size="md"
|
|
|
|
size="md"
|
|
|
|
variant={jobType === JobType.FullTime ? 'secondary' : 'tertiary'}
|
|
|
|
variant={jobType === JobType.FullTime ? 'secondary' : 'tertiary'}
|
|
|
|
onClick={changeJobType(JobType.FullTime)}
|
|
|
|
onClick={() => {
|
|
|
|
|
|
|
|
if (jobType === JobType.FullTime) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
setDialogOpen(true);
|
|
|
|
|
|
|
|
}}
|
|
|
|
{...register(`offers.${0}.jobType`)}
|
|
|
|
{...register(`offers.${0}.jobType`)}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className="mx-5 w-1/3">
|
|
|
|
<div className="mx-5 w-1/3">
|
|
|
|
<Button
|
|
|
|
<Button
|
|
|
|
display="block"
|
|
|
|
display="block"
|
|
|
|
label="Internship"
|
|
|
|
label={JobTypeLabel.INTERNSHIP}
|
|
|
|
size="md"
|
|
|
|
size="md"
|
|
|
|
variant={jobType === JobType.Internship ? 'secondary' : 'tertiary'}
|
|
|
|
variant={jobType === JobType.Internship ? 'secondary' : 'tertiary'}
|
|
|
|
onClick={changeJobType(JobType.Internship)}
|
|
|
|
onClick={() => {
|
|
|
|
|
|
|
|
if (jobType === JobType.Internship) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
setDialogOpen(true);
|
|
|
|
|
|
|
|
}}
|
|
|
|
{...register(`offers.${0}.jobType`)}
|
|
|
|
{...register(`offers.${0}.jobType`)}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
@ -462,6 +511,32 @@ export default function OfferDetailsForm() {
|
|
|
|
fieldArrayValues={fieldArrayValues}
|
|
|
|
fieldArrayValues={fieldArrayValues}
|
|
|
|
jobType={jobType}
|
|
|
|
jobType={jobType}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
|
|
|
|
<Dialog
|
|
|
|
|
|
|
|
isShown={isDialogOpen}
|
|
|
|
|
|
|
|
primaryButton={
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
|
|
|
display="block"
|
|
|
|
|
|
|
|
label="Switch"
|
|
|
|
|
|
|
|
variant="primary"
|
|
|
|
|
|
|
|
onClick={() => {
|
|
|
|
|
|
|
|
toggleJobType();
|
|
|
|
|
|
|
|
setDialogOpen(false);
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
secondaryButton={
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
|
|
|
display="block"
|
|
|
|
|
|
|
|
label="Cancel"
|
|
|
|
|
|
|
|
variant="tertiary"
|
|
|
|
|
|
|
|
onClick={() => setDialogOpen(false)}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
title={`Switch to ${switchJobTypeLabel()}`}
|
|
|
|
|
|
|
|
onClose={() => setDialogOpen(false)}>
|
|
|
|
|
|
|
|
{`Are you sure you want to switch to ${switchJobTypeLabel()}? The data you
|
|
|
|
|
|
|
|
entered in the ${JobTypeLabel[jobType]} section will disappear.`}
|
|
|
|
|
|
|
|
</Dialog>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|