80 lines
1.9 KiB
TypeScript
80 lines
1.9 KiB
TypeScript
import type { Props } from './types';
|
|
import { mapFieldTypeElement } from '@/config/elements';
|
|
import { useFormStore } from '@/store/ius/form';
|
|
import { useEffect } from 'react';
|
|
import { ElementContainer } from 'ui';
|
|
|
|
function compatMetadata(metaData: Props['metaData']) {
|
|
const { comment, ...meta } = metaData;
|
|
if (comment) {
|
|
comment.fieldType = 'TEXTAREA';
|
|
|
|
return { ...meta, comment };
|
|
}
|
|
|
|
return metaData;
|
|
}
|
|
|
|
function RenderElement({
|
|
fieldType,
|
|
label,
|
|
max,
|
|
min = 0,
|
|
name,
|
|
visible,
|
|
...props
|
|
}: Props['metaData'][number] & { readonly name: string }) {
|
|
const { setValue, validation, values } = useFormStore();
|
|
|
|
if (!visible) return false;
|
|
|
|
const Element = mapFieldTypeElement[fieldType];
|
|
|
|
return (
|
|
<ElementContainer
|
|
intent={validation[name] ? 'danger' : 'default'}
|
|
message={validation[name]?.message}
|
|
key={name}
|
|
id={name}
|
|
title={label}
|
|
>
|
|
<Element
|
|
loading={!Object.keys(values).length}
|
|
checked={fieldType === 'CHECKBOX' ? Boolean(values[name]) || false : false}
|
|
id={name}
|
|
value={values[name] || ''}
|
|
min={min}
|
|
max={max}
|
|
onChange={(e) => {
|
|
setValue({
|
|
name,
|
|
value: fieldType === 'CHECKBOX' ? e.target.checked : e.target.value,
|
|
});
|
|
}}
|
|
{...props}
|
|
/>
|
|
</ElementContainer>
|
|
);
|
|
}
|
|
|
|
export function Elements({ data, metaData }: Props) {
|
|
const { init } = useFormStore();
|
|
|
|
useEffect(() => {
|
|
init(data);
|
|
}, [data, init]);
|
|
|
|
const { comment, ...meta } = compatMetadata(metaData);
|
|
|
|
return (
|
|
<>
|
|
<div className="mt-2 grid gap-2 gap-x-4 md:grid md:grid-cols-2 lg:grid-cols-3">
|
|
{Object.keys(meta).map((name) => (
|
|
<RenderElement key={name} {...metaData[name]} name={name} />
|
|
))}
|
|
</div>
|
|
<RenderElement {...comment} name="comment" />
|
|
</>
|
|
);
|
|
}
|