apps/web: add form-context to provide pageUrlParams

This commit is contained in:
vchikalkin 2023-11-16 19:51:54 +03:00
parent 7b58d76f9e
commit 1e29f598f8
8 changed files with 68 additions and 31 deletions

View File

@ -1,10 +1,10 @@
import * as apiIUS from '@/api/ius/query';
import * as Form from '@/components/Form';
import { Form } from '@/components/Form';
import type { PageProps } from '@/types/page';
import { withError } from '@/utils/error';
import { getPageUrlParams, makeCreateUrl } from '@/utils/url';
import type { Metadata } from 'next';
import { Background, Divider } from 'ui';
import { Background } from 'ui';
export async function generateMetadata(pageProps: PageProps): Promise<Metadata> {
const pageUrlParams = getPageUrlParams(pageProps);
@ -28,22 +28,17 @@ export default async function Page(pageProps: PageProps) {
const pageUrlParams = getPageUrlParams(pageProps);
const createUrl = makeCreateUrl(pageUrlParams);
return Promise.all([
apiIUS.getData({ createUrl }),
apiIUS.getMetaData({ createUrl }),
apiIUS.getConfig({ createUrl }),
]).then(([data, metaData, { title }]) => {
const props = { data, metaData, pageUrlParams };
return Promise.all([apiIUS.getData({ createUrl }), apiIUS.getMetaData({ createUrl })]).then(
([data, metaData]) => {
const props = { data, metaData, pageUrlParams };
return (
<Background>
<Form.Header {...props} url={'/ius' + createUrl('/conditions')} title={title} />
<Form.Elements {...props} />
<Divider />
<Form.Buttons {...props} />
</Background>
);
});
return (
<Background>
<Form {...props} />
</Background>
);
}
);
},
});
}

View File

@ -1,12 +1,12 @@
'use client';
import { FormContext } from './context/form-context';
import * as apiIus from '@/api/ius/query';
import { useFormStore } from '@/store/ius/form';
import { makeCreateUrl, type PageUrlParams } from '@/utils/url';
import { useContext } from 'react';
import { Button } from 'ui';
export function Buttons({ pageUrlParams }: { readonly pageUrlParams: PageUrlParams }) {
export function Buttons() {
const { reset, setValidation, values } = useFormStore();
const createUrl = makeCreateUrl(pageUrlParams);
const { createUrl } = useContext(FormContext);
return (
<div className="grid grid-cols-1 gap-2 gap-x-4 md:grid-cols-3">

View File

@ -1,5 +1,3 @@
'use client';
import type { Props } from './types';
import { mapFieldTypeElement } from '@/config/elements';
import { useFormStore } from '@/store/ius/form';

View File

@ -1,15 +1,23 @@
/* eslint-disable react/forbid-component-props */
import type { Props } from './types';
import { FormContext } from './context/form-context';
import * as apiIUS from '@/api/ius/query';
import Link from 'next/link';
import { useContext } from 'react';
import { Heading } from 'ui';
export function Header({ title, url }: Props & { readonly title: string; readonly url: string }) {
return (
export function Header() {
const { createUrl } = useContext(FormContext);
return apiIUS.getConfig({ createUrl }).then(({ title }) => (
<div className="flex justify-between">
<Heading size={2}>{title}</Heading>
<Link href={url} className="text-primary-600 text-sm font-medium hover:underline" prefetch>
<Link
href={'/ius' + createUrl('/conditions')}
className="text-primary-600 text-sm font-medium hover:underline"
prefetch
>
Посмотреть условия
</Link>
</div>
);
));
}

View File

@ -0,0 +1,16 @@
import type { CreateUrl, PageUrlParams } from '@/utils/url';
import type { PropsWithChildren } from 'react';
import { createContext, useMemo } from 'react';
type ContextType = {
readonly createUrl: CreateUrl;
readonly pageUrlParams: PageUrlParams | undefined;
};
export const FormContext = createContext<ContextType>({} as ContextType);
export function FormContextProvider({ children, ...initialData }: PropsWithChildren & ContextType) {
const value = useMemo(() => initialData, [initialData]);
return <FormContext.Provider value={value}>{children}</FormContext.Provider>;
}

View File

@ -1,3 +0,0 @@
export * from './Buttons';
export * from './Elements';
export * from './Header';

View File

@ -0,0 +1,21 @@
'use client';
import { Buttons } from './Buttons';
import { FormContextProvider } from './context/form-context';
import { Elements } from './Elements';
import { Header } from './Header';
import type { Props } from './types';
import { makeCreateUrl } from '@/utils/url';
import { Divider } from 'ui';
export function Form(props: Props) {
const { pageUrlParams } = props;
return (
<FormContextProvider pageUrlParams={pageUrlParams} createUrl={makeCreateUrl(pageUrlParams)}>
<Header />
<Elements {...props} />
<Divider />
<Buttons />
</FormContextProvider>
);
}

View File

@ -1,6 +1,8 @@
import type { ResponseGetData, ResponseMetaData } from '@/api/ius/types';
import type { PageUrlParams } from '@/utils/url';
export type Props = {
readonly data: ResponseGetData;
readonly metaData: ResponseMetaData;
readonly pageUrlParams: PageUrlParams;
};