-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FE][CPF-98] Add people - ladder step (#99)
* feat: main ladder basic * feat: ladder step * feat: refactor and id support
- Loading branch information
Showing
28 changed files
with
393 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
frontend/src/app/(app)/(addEmployee)/people/add-new/main-ladder/[[...id]]/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
3 changes: 3 additions & 0 deletions
3
frontend/src/app/(app)/(addEmployee)/people/add-new/personal-details/[[...id]]/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
3 changes: 0 additions & 3 deletions
3
frontend/src/app/(app)/(peopleFlow)/people/add-new/personal-details/page.tsx
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
frontend/src/components/common/Combobox/Combobox.interface.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { ReactNode } from 'react'; | ||
|
||
export interface Option { | ||
id: string; | ||
name: string; | ||
} | ||
|
||
export interface ComboboxProps { | ||
label?: string; | ||
options: Option[]; | ||
name: string; | ||
renderRightContent?: () => ReactNode; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
'use client'; | ||
|
||
import { ChevronRightIcon } from '@app/static/icons/ChevronRightIcon'; | ||
import { | ||
Combobox as HeadlessCombobox, | ||
ComboboxButton, | ||
ComboboxInput, | ||
ComboboxOption, | ||
ComboboxOptions, | ||
Label, | ||
} from '@headlessui/react'; | ||
import { useMemo, useState } from 'react'; | ||
import { ComboboxProps, Option } from './Combobox.interface'; | ||
import { Controller, useFormContext } from 'react-hook-form'; | ||
|
||
export const Combobox: React.FC<ComboboxProps> = ({ label, options, name, renderRightContent }) => { | ||
const [query, setQuery] = useState(''); | ||
const { control } = useFormContext(); | ||
|
||
const filteredOptions = useMemo( | ||
() => | ||
options | ||
.sort((a, b) => a.name.toLocaleLowerCase().localeCompare(b.name.toLocaleLowerCase())) | ||
.filter((option) => option.name.toLowerCase().includes(query.toLowerCase())), | ||
[options, query], | ||
); | ||
|
||
return ( | ||
<Controller | ||
control={control} | ||
name={name} | ||
render={({ field: { onChange, value } }) => ( | ||
<HeadlessCombobox | ||
as="div" | ||
immediate | ||
value={value} | ||
onChange={(person) => { | ||
setQuery(''); | ||
onChange(person); | ||
}} | ||
className="flex flex-1 flex-col gap-y-2" | ||
> | ||
{label && <Label className="font-semibold text-navy-900">{label}</Label>} | ||
<div className="flex flex-1 items-center"> | ||
<div className="relative w-full"> | ||
<ComboboxInput | ||
className="w-full rounded-xl border-0 bg-white px-4 py-3 text-navy-600 shadow-sm outline-none ring-1 ring-inset ring-navy-200 focus:ring-1 focus:ring-inset focus:ring-navy-700" | ||
onChange={(event) => setQuery(event.target.value)} | ||
onBlur={() => setQuery('')} | ||
displayValue={(item: Option) => item?.name} | ||
/> | ||
<ComboboxButton className="absolute inset-y-0 right-0 px-4"> | ||
<ChevronRightIcon className="text-gray-400 h-4 w-4 rotate-90 text-navy-600" aria-hidden="true" /> | ||
</ComboboxButton> | ||
|
||
{filteredOptions?.length > 0 && ( | ||
<ComboboxOptions className="ring-black absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-opacity-5 focus:outline-none sm:text-sm"> | ||
{filteredOptions.map((option) => ( | ||
<ComboboxOption | ||
key={option.id} | ||
value={option} | ||
className="relative cursor-default select-none py-2 pl-3 pr-9 text-navy-900 data-[focus]:cursor-pointer data-[focus]:bg-navy-200 data-[focus]:font-medium" | ||
> | ||
<span className="block truncate">{option.name}</span> | ||
</ComboboxOption> | ||
))} | ||
</ComboboxOptions> | ||
)} | ||
</div> | ||
{renderRightContent?.()} | ||
</div> | ||
</HeadlessCombobox> | ||
)} | ||
/> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export { Combobox } from './Combobox'; | ||
|
||
export type { Option } from './Combobox.interface'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 15 additions & 13 deletions
28
frontend/src/components/modules/SideStepper/SideStepper.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 10 additions & 3 deletions
13
frontend/src/components/modules/SideStepper/SideStepper.utils.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,26 @@ | ||
import { CheckMarkIcon } from '@app/static/icons/CheckMarkIcon'; | ||
import { StepStates } from './SideStepper.interface'; | ||
|
||
export const Completed = () => { | ||
const Completed = () => { | ||
return ( | ||
<div className="flex h-7 w-7 items-center justify-center rounded-full bg-blue-800"> | ||
<CheckMarkIcon /> | ||
</div> | ||
); | ||
}; | ||
export const InProgress = () => { | ||
const InProgress = () => { | ||
return ( | ||
<div className="flex h-7 w-7 items-center justify-center rounded-full border border-blue-800 bg-white"> | ||
<div className="h-[10px] w-[10px] rounded-full bg-blue-800" /> | ||
</div> | ||
); | ||
}; | ||
export const NotStarted = () => { | ||
const NotStarted = () => { | ||
return <div className="flex h-7 w-7 items-center justify-center rounded-full border border-navy-300 bg-white" />; | ||
}; | ||
|
||
export const stepComponentsMap: { [key in StepStates]: JSX.Element } = { | ||
completed: <Completed />, | ||
inProgress: <InProgress />, | ||
notStarted: <NotStarted />, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export { SideStepper } from './SideStepper'; | ||
export { stepComponentsMap } from './SideStepper.utils'; | ||
export type { SideStepperProps, Step, StepStates } from './SideStepper.interface'; |
11 changes: 0 additions & 11 deletions
11
frontend/src/components/pages/PersonalDetails/PersonalDetails.interface.ts
This file was deleted.
Oops, something went wrong.
17 changes: 17 additions & 0 deletions
17
...end/src/components/pages/addEmployee/AddEmployeeFormProvider/AddEmployeeForm.interface.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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[]; | ||
} |
19 changes: 19 additions & 0 deletions
19
frontend/src/components/pages/addEmployee/AddEmployeeFormProvider/AddEmployeeForm.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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>; | ||
}; |
3 changes: 3 additions & 0 deletions
3
frontend/src/components/pages/addEmployee/AddEmployeeFormProvider/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'; |
37 changes: 37 additions & 0 deletions
37
frontend/src/components/pages/addEmployee/MainLadder/MainLadder.hooks.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 }; | ||
}; |
Oops, something went wrong.