From 6fd99055023d1a6040c15b3b23bea0fada2cb383 Mon Sep 17 00:00:00 2001 From: mery Date: Mon, 8 Jul 2024 17:48:07 +0200 Subject: [PATCH] feat(redmine 1301354): add Stepper page --- .changeset/wild-lobsters-switch.md | 5 + .../AddressAutocompleteFields.tsx | 6 +- .../src/Pages/StepperPage/Code.mdx | 13 ++ .../Pages/StepperPage/StepperPage.mock.tsx | 7 + .../Pages/StepperPage/StepperPage.stories.tsx | 18 ++ .../src/Pages/StepperPage/StepperPage.tsx | 160 ++++++++++++++++++ 6 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 .changeset/wild-lobsters-switch.md create mode 100644 packages/storybook-pages/src/Pages/StepperPage/Code.mdx create mode 100644 packages/storybook-pages/src/Pages/StepperPage/StepperPage.mock.tsx create mode 100644 packages/storybook-pages/src/Pages/StepperPage/StepperPage.stories.tsx create mode 100644 packages/storybook-pages/src/Pages/StepperPage/StepperPage.tsx diff --git a/.changeset/wild-lobsters-switch.md b/.changeset/wild-lobsters-switch.md new file mode 100644 index 00000000..ef11152a --- /dev/null +++ b/.changeset/wild-lobsters-switch.md @@ -0,0 +1,5 @@ +--- +'storybook-pages': minor +--- + +Create a Stepper page diff --git a/packages/haring-react/src/Form/AddressAutocompleteFields/AddressAutocompleteFields.tsx b/packages/haring-react/src/Form/AddressAutocompleteFields/AddressAutocompleteFields.tsx index 5a8ae545..aca684bc 100644 --- a/packages/haring-react/src/Form/AddressAutocompleteFields/AddressAutocompleteFields.tsx +++ b/packages/haring-react/src/Form/AddressAutocompleteFields/AddressAutocompleteFields.tsx @@ -7,7 +7,7 @@ import type { import type { TextInputProps } from '@mantine/core'; import type { ElementType, ReactElement } from 'react'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { AddressFields } from '../AddressFields/AddressFields'; import { FetchAutocompleteField } from '../FetchAutocompleteField/FetchAutocompleteField'; @@ -57,7 +57,9 @@ export function AddressAutocompleteFields( setAllFieldsValues(values); onFieldsValuesChange?.(values); } - + useEffect(() => { + setAllFieldsValues(addressFieldsProps ?? {}); + }, [addressFieldsProps]); return (
+ +# Code + +Code of StepperPage page + + diff --git a/packages/storybook-pages/src/Pages/StepperPage/StepperPage.mock.tsx b/packages/storybook-pages/src/Pages/StepperPage/StepperPage.mock.tsx new file mode 100644 index 00000000..c5da8806 --- /dev/null +++ b/packages/storybook-pages/src/Pages/StepperPage/StepperPage.mock.tsx @@ -0,0 +1,7 @@ +export const texts = { + steps: { + step1: 'Step 1: ', + step2: 'Step 2: ', + step3: 'Completed, click back button to get to previous step', + }, +}; diff --git a/packages/storybook-pages/src/Pages/StepperPage/StepperPage.stories.tsx b/packages/storybook-pages/src/Pages/StepperPage/StepperPage.stories.tsx new file mode 100644 index 00000000..d501b457 --- /dev/null +++ b/packages/storybook-pages/src/Pages/StepperPage/StepperPage.stories.tsx @@ -0,0 +1,18 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { StepperPage as Cmp } from './StepperPage'; + +const meta = { + component: Cmp, + parameters: { + layout: 'fullscreen', + }, + title: '3-custom/Pages/StepperPage', +} satisfies Meta; + +export default meta; +type IStory = StoryObj; + +export const StepperPage: IStory = { + args: {}, +}; diff --git a/packages/storybook-pages/src/Pages/StepperPage/StepperPage.tsx b/packages/storybook-pages/src/Pages/StepperPage/StepperPage.tsx new file mode 100644 index 00000000..06fb7855 --- /dev/null +++ b/packages/storybook-pages/src/Pages/StepperPage/StepperPage.tsx @@ -0,0 +1,160 @@ +/* eslint-disable @typescript-eslint/no-unsafe-call */ +'use client'; + +import type { IAddressFieldsValues } from '@smile/haring-react/src/Form/AddressFields/AddressFields'; +import type { IValue } from '@smile/haring-react/src/Form/FetchAutocompleteField/FetchAutocompleteField'; +import type { ReactElement } from 'react'; + +import { Button, Flex, Group, Stepper } from '@mantine/core'; +import { useForm } from '@mantine/form'; +import { + FoldableColumnLayout, + FullNameFields, + SidebarMenu, +} from '@smile/haring-react'; + +// import { AddressAutocompleteFields } from '@smile/haring-react/src/Form/AddressAutocompleteFields/AddressAutocompleteFields'; +import { useEffect, useState } from 'react'; + +import { menuMock } from '../BrowsingPage/BrowsingPage.mock'; + +import { texts } from './StepperPage.mock'; + +export interface IAddressGouvData { + properties: { + city?: string; + housenumber?: string; + label: string; + postcode?: string; + street?: string; + }; +} + +export async function getDataAddressGouvRequest( + value: string, +): Promise[]> { + const response = await fetch( + `https://api-adresse.data.gouv.fr/search/?q=${encodeURIComponent( + value, + )}&autocomplete=1`, + ); + const data: { features: IAddressGouvData[] } = await response.json(); + const result = data.features.map((element) => { + return { label: element.properties.label, value: element }; + }); + + return result; +} + +export function StepperPage(): ReactElement { + const [active, setActive] = useState(0); + const [formData, setFormData] = useState({ + address: { + city: '', + country: '', + number: '', + postCode: '', + street: '', + }, + fullName: '', + }); + + const sidebarMenu = menuMock; + + const form = useForm({ + initialValues: formData, + }); + + const nextStep = (): void => { + if (!form.validate().hasErrors) { + setFormData(form.values); + setActive((current) => (current < 3 ? current + 1 : current)); + } + }; + + const prevStep = (): void => { + setFormData(form.values); + setActive((current) => (current > 0 ? current - 1 : current)); + }; + + useEffect(() => { + form.setValues(formData); + }, [active, form, formData]); + + function onOptionSubmitMock( + value: IValue, + ): IAddressFieldsValues { + const address = value.value.properties; + const newAddress = { + city: address.city ?? '', + country: 'France', + number: address.housenumber ?? '', + postCode: address.postcode ?? '', + street: address.street ?? '', + }; + form.setFieldValue('address', newAddress); + setFormData((prevData) => { + const updatedData = { + ...prevData, + address: newAddress, + }; + return updatedData; + }); + return newAddress; + } + + return ( + + + + } + > + + + {texts.steps.step1} + + + + {texts.steps.step2} + { + form.setFieldValue('address', { + city: values.city ?? '', + country: values.country ?? form.values.address.country, + number: values.number ?? '', + postCode: values.postCode ?? '', + street: values.street ?? '', + }); + setFormData((prevData) => ({ + ...prevData, + address: { + city: values.city ?? '', + country: values.country ?? form.values.address.country, + number: values.number ?? '', + postCode: values.postCode ?? '', + street: values.street ?? '', + }, + })); + }} + onOptionSubmit={onOptionSubmitMock} + /> + + {texts.steps.step3} + + + + {active !== 0 && ( + + )} + {active !== 2 && } + + + ); +}