apps/web: add form store

api/ius: add validate function
This commit is contained in:
vchikalkin 2023-11-15 13:39:26 +03:00
parent 2418afb335
commit 05990f028b
7 changed files with 94 additions and 10 deletions

View File

@ -1,5 +1,6 @@
import type * as t from './types';
import { urls } from '@/config/urls';
import type { WretchError } from 'wretch';
import wretch from 'wretch';
const api = wretch(urls.URL_UIS).errorType('json');
@ -41,3 +42,13 @@ export async function getConditions(createUrl: CreateUrl) {
.res<t.ResponseConditions>((res) => res.text())
.then((res) => res);
}
export async function validate(createUrl: CreateUrl) {
const url = createUrl('/validate');
return api
.post(url)
.res<boolean>((res) => res.ok)
.then((res) => res)
.catch((error: WretchError) => error.json as t.HttpValidationError);
}

View File

@ -9,8 +9,9 @@ export type MetaObject = {
visible: boolean;
};
export type Request = { searchParams: any; slug: string };
export type ResponseGetData = Record<string, any>;
type Value = string | number | string[] | undefined;
export type ResponseGetData = Record<string, Value>;
export type ResponseMetaData = Record<string, MetaObject>;
export type ResponseConfig = { title: string };
export type ResponseConditions = string;
@ -20,3 +21,7 @@ export type HttpError = {
status: number;
title: string;
};
export type HttpValidationError = Omit<HttpError, 'errors'> & {
errors: Record<string, string[]>;
};

View File

@ -1,9 +1,21 @@
'use client';
import { useFormStore } from '@/store/ius/form';
import { Button } from 'ui';
export function Buttons() {
const { reset } = useFormStore();
return (
<div className="grid grid-cols-1 gap-2 gap-x-4 md:grid-cols-3">
<Button intent="outline-danger">Отмена</Button>
<Button
intent="outline-danger"
onClick={() => {
reset();
}}
>
Отмена
</Button>
<Button intent="secondary">Возврат на доработку</Button>
<Button>Сохранить</Button>
</div>

View File

@ -1,8 +1,18 @@
'use client';
import type { Props } from './types';
import { mapFieldTypeElement } from '@/config/elements';
import { useFormStore } from '@/store/ius/form';
import { useEffect } from 'react';
import { ElementContainer } from 'ui';
export function Elements({ data, metaData }: Props) {
const { init, setValue, values } = useFormStore();
useEffect(() => {
init(data);
}, [data, init]);
return (
<div className="mt-2 grid auto-rows-auto grid-cols-1 gap-2 gap-x-4 md:grid-cols-2 lg:grid-cols-3">
{Object.keys(metaData).map((name) => {
@ -13,17 +23,16 @@ export function Elements({ data, metaData }: Props) {
const Element = mapFieldTypeElement[fieldType];
return (
<ElementContainer
key={name}
id={name}
title={fieldType === 'CHECKBOX' ? '' : metaData[name].label}
>
<ElementContainer key={name} id={name} title={fieldType === 'CHECKBOX' ? '' : label}>
<Element
id={name}
defaultValue={data[name]}
value={values[name]}
title={label}
min={min}
max={max}
onChange={(e) => {
setValue({ name, value: e.target.value });
}}
{...props}
/>
</ElementContainer>

View File

@ -15,7 +15,8 @@
"tsconfig": "*",
"ui": "*",
"wretch": "^2.7.0",
"zod": "^3.22.4"
"zod": "^3.22.4",
"zustand": "^4.4.6"
},
"devDependencies": {
"@tailwindcss/forms": "^0.5.6",

View File

@ -0,0 +1,34 @@
import type { ResponseGetData } from '@/api/ius/types';
import { create } from 'zustand';
type Values = ResponseGetData;
type FormState = {
defaultValues: Values;
init: (values: Values) => void;
reset: () => void;
setValue: ({ name, value }: { name: string; value: Values[number] }) => void;
values: Values;
};
export const useFormStore = create<FormState>((set) => ({
defaultValues: {},
init: (values) =>
set(() => ({
defaultValues: values,
values,
})),
reset: () => {
set((state) => ({
values: state.defaultValues,
}));
},
setValue: ({ name, value }) =>
set((state) => ({
values: {
...state.values,
[name]: value,
},
})),
values: {},
}));

View File

@ -5732,6 +5732,11 @@ urlpattern-polyfill@^8.0.0:
resolved "https://registry.yarnpkg.com/urlpattern-polyfill/-/urlpattern-polyfill-8.0.2.tgz#99f096e35eff8bf4b5a2aa7d58a1523d6ebc7ce5"
integrity sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==
use-sync-external-store@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
util-deprecate@^1.0.1, util-deprecate@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
@ -5967,3 +5972,10 @@ zod@^3.22.4:
version "3.22.4"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff"
integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==
zustand@^4.4.6:
version "4.4.6"
resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.4.6.tgz#03c78e3e2686c47095c93714c0c600b72a6512bd"
integrity sha512-Rb16eW55gqL4W2XZpJh0fnrATxYEG3Apl2gfHTyDSE965x/zxslTikpNch0JgNjJA9zK6gEFW8Fl6d1rTZaqgg==
dependencies:
use-sync-external-store "1.2.0"