Skip to content

Commit

Permalink
feat: refactor and id support
Browse files Browse the repository at this point in the history
  • Loading branch information
r1skz3ro committed Jul 15, 2024
1 parent f347fb7 commit 641a0ac
Show file tree
Hide file tree
Showing 20 changed files with 196 additions and 178 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { EmployeeSideStepper } from '@app/components/modules/EmployeeSideStepper';
import { WorkflowTopbar } from '@app/components/modules/WorkflowTopbar';
import { AddEmployeeFormProvider } from '@app/components/pages/addEmployee/AddEmployeeFormProvider';

export default function PeopleLayout({ children }: Readonly<{ children: React.ReactNode }>) {
return (
Expand All @@ -9,7 +10,9 @@ export default function PeopleLayout({ children }: Readonly<{ children: React.Re
<main className="p-8">
<div className="grid grid-cols-workflow">
<EmployeeSideStepper />
<div className="col-span-1 px-8">{children}</div>
<div className="col-span-1 px-8">
<AddEmployeeFormProvider>{children}</AddEmployeeFormProvider>
</div>
</div>
</main>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { MainLadder } from '@app/components/pages/addEmployee/MainLadder';

export default MainLadder;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { PersonalDetails } from '@app/components/pages/addEmployee/PersonalDetails';

export default PersonalDetails;

This file was deleted.

This file was deleted.

14 changes: 11 additions & 3 deletions frontend/src/components/modules/SideStepper/SideStepper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,32 @@ import { SideStepperProps } from './SideStepper.interface';
import { Fragment } from 'react';
import { Typography } from '@app/components/common/Typography';
import { stepComponentsMap } from './SideStepper.utils';
import { Button } from '@app/components/common/Button';
import { useRouter } from 'next/navigation';

export const SideStepper = <T extends string>({ steps }: SideStepperProps<T>) => {
const router = useRouter();
return (
<div className="flex">
<div className="flex flex-col">
{steps.map(({ label, state, active }, i) => {
{steps.map(({ label, state, active, href }, i) => {
const last = i === steps.length - 1;
return (
<Fragment key={label}>
<div className="flex items-center gap-x-3">
<Button
className="flex items-center justify-start gap-x-3"
variant="link"
disabled={state === 'notStarted'}
onClick={() => router.push(href)}
>
{stepComponentsMap[state]}
<Typography
variant="body-m/semibold"
className={generateClassNames(active ? 'text-navy-900' : 'text-navy-600')}
>
{label}
</Typography>
</div>
</Button>
{!last && (
<div className="flex w-7 justify-center py-2">
<div className="flex h-[16px] w-[1.5px] border border-navy-300" />
Expand Down
38 changes: 0 additions & 38 deletions frontend/src/components/pages/MainLadder/MainLadder.hooks.ts

This file was deleted.

11 changes: 0 additions & 11 deletions frontend/src/components/pages/MainLadder/MainLadder.interface.ts

This file was deleted.

88 changes: 0 additions & 88 deletions frontend/src/components/pages/MainLadder/MainLadder.tsx

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Option } from '@app/components/common/Combobox';

export const addEmployeeFormNames = {
firstName: 'firstName',
lastName: 'lastName',
email: 'email',
ladder: 'ladder',
technology: 'technology',
} as const;

export interface AddEmployeeForm {
[addEmployeeFormNames.firstName]: string;
[addEmployeeFormNames.lastName]: string;
[addEmployeeFormNames.email]: string;
[addEmployeeFormNames.ladder]: Option;
[addEmployeeFormNames.technology]: Option[];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { FC, PropsWithChildren } from 'react';
import { useForm } from 'react-hook-form';

import { FormProvider } from '@app/components/common/FormProvider';
import { AddEmployeeForm, addEmployeeFormNames } from './AddEmployeeForm.interface';

export const AddEmployeeFormProvider: FC<PropsWithChildren> = ({ children }) => {
const form = useForm<AddEmployeeForm>({
mode: 'onChange',
defaultValues: {
[addEmployeeFormNames.firstName]: '',
[addEmployeeFormNames.lastName]: '',
[addEmployeeFormNames.email]: '',
[addEmployeeFormNames.ladder]: {},
[addEmployeeFormNames.technology]: [],
},
});
return <FormProvider<AddEmployeeForm> form={form}>{children}</FormProvider>;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { AddEmployeeFormProvider } from './AddEmployeeForm';
export type { AddEmployeeForm } from './AddEmployeeForm.interface';
export { addEmployeeFormNames } from './AddEmployeeForm.interface';
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useFieldArray, useFormContext } from 'react-hook-form';
import { useEffect, useState } from 'react';
import { AddEmployeeForm, addEmployeeFormNames } from '../AddEmployeeFormProvider';
import { usePeopleStore } from '@app/store/people';
import { routes } from '@app/constants';

export const useMainLadder = () => {
const form = useFormContext<AddEmployeeForm>();
const updateProgress = usePeopleStore((state) => state.updateProgress);

const technologyFields = useFieldArray({
name: addEmployeeFormNames.technology,
control: form.control,
});

const [open, setOpen] = useState(true);
const [formValid, setFormValid] = useState(false);

const handleSubmit = form.handleSubmit((data) => console.log('data', data));
const values = form.watch();
const ladderSelected = values?.[addEmployeeFormNames.ladder]?.name?.length > 0;
const firstTechnology = values?.[addEmployeeFormNames.technology]?.[0];

useEffect(() => {
const technologySelected = firstTechnology && firstTechnology.name?.length > 0;

setFormValid(ladderSelected && technologySelected);
}, [values, ladderSelected, firstTechnology]);

// INFO: update progress in sidebar stepper
useEffect(() => {
if (formValid) updateProgress({ [routes.people.addNew.mainLadder]: 'completed' });
else updateProgress({ [routes.people.addNew.mainLadder]: 'inProgress' });
}, [formValid, updateProgress]);

return { firstTechnology, form, handleSubmit, technologyFields, open, setOpen, ladderSelected, formValid };
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
'use client';
import { Button } from '@app/components/common/Button';
import { Combobox } from '@app/components/common/Combobox';
import { Typography } from '@app/components/common/Typography';
import { stepComponentsMap } from '@app/components/modules/SideStepper';
import { useMainLadder } from './MainLadder.hooks';
import { DeleteIcon } from '@app/static/icons/DeleteIcon';
import { generateClassNames } from '@app/utils';
import { ChevronUpIcon } from '@app/static/icons/ChevronUpIcon';
import { Spacer, ladders, technologies } from './MainLadder.utils';
import { addEmployeeFormNames } from '../AddEmployeeFormProvider';

export const MainLadder = () => {
const { form, technologyFields, open, setOpen, ladderSelected, formValid, firstTechnology } = useMainLadder();
const values = form.watch();

return (
<div className="flex flex-col gap-y-10 rounded-[20px] border-navy-200 bg-white p-8">
<div className="flex items-center justify-between">
<div className="flex items-center gap-x-4">
<div>{formValid ? stepComponentsMap.completed : stepComponentsMap.inProgress}</div>
<Typography variant="head-s/medium">1. Select Ladder</Typography>
</div>
<Button
variant="link"
className={generateClassNames(`flex h-8 w-8 duration-150 ${open ? 'rotate-0' : 'rotate-180'} items-center`)}
onClick={() => setOpen((prev) => !prev)}
>
{<ChevronUpIcon className="text-navy-600" />}
</Button>
</div>
{open && (
<div className="flex flex-col gap-y-6">
<div className="flex w-1/2 flex-col gap-y-6">
<Combobox
label="Ladder"
options={ladders}
name={addEmployeeFormNames.ladder}
renderRightContent={() => <Spacer />}
/>
{values?.[addEmployeeFormNames.technology].map((tech, i) => {
return (
<Combobox
label="Technology"
key={`${tech.id}-${i}`}
options={technologies}
name={`${addEmployeeFormNames.technology}.${i}`}
renderRightContent={() =>
i !== 0 ? (
<Button
variant="link"
styleType="natural"
className="flex h-8 w-8 items-center"
onClick={() => technologyFields.remove(i)}
>
<DeleteIcon />
</Button>
) : (
<Spacer />
)
}
/>
);
})}
{ladderSelected && (
<Button
styleType="primary"
variant="link"
className="w-fit"
onClick={() => technologyFields.append({ id: '', name: '' })}
disabled={firstTechnology && !firstTechnology.name}
>
+ Technology
</Button>
)}
</div>
<div className="self-end">
<Button styleType="primary" variant="solid" disabled={!formValid}>
Confirm and continue
</Button>
</div>
</div>
)}
</div>
);
};
Loading

0 comments on commit 641a0ac

Please sign in to comment.