ldc-groupe/resources/ts/back/Components/DynamicPages/DynamicInputs.tsx

423 lines
19 KiB
TypeScript
Raw Permalink Normal View History

2025-09-16 16:44:49 +02:00
// * Packages
import { usePage } from "@inertiajs/react";
// * Other
import SimpleString from "@/back/Components/Inputs/SimpleString";
import SimpleNumber from "@/back/Components/Inputs/SimpleNumber";
import SimpleSwitch from "@/back/Components/Inputs/SimpleSwitch";
import SimpleWysiwyg from "@/back/Components/Inputs/Wysiwyg/SimpleWysiwyg";
import CompleteInputFile from "@/back/Components/Inputs/CompleteInputFile";
import DynamicList from "@/back/Components/DynamicPages/DynamicList";
import SimpleTextarea from "@/back/Components/Inputs/SimpleTextarea";
import SimpleDatePicker from "@/back/Components/Inputs/SimpleDatePicker";
import SimpleColorPicker from "@/back/Components/Inputs/SimpleColorPicker";
import SimpleYoutubeId from "@/back/Components/Inputs/SimpleYoutubeId";
import SimpleVimeoId from "@/back/Components/Inputs/SimpleVimeoId";
import EnumSelect from "@/back/Components/Inputs/EnumSelect";
2026-02-10 15:52:48 +01:00
import StaticRouteSelect from "@/back/Components/Inputs/StaticRouteSelect";
2026-02-12 15:42:22 +01:00
import DynamicWrapperModelSelect from "@/back/Components/DynamicPages/DynamicWrapperModelSelect";
import { LaravelEnum } from "@/back/types/global";
import {
ConfigField,
DynamicFieldTypes,
DynamicInternalField,
2026-02-12 15:42:22 +01:00
} from "@/back/types/dynamic-pages";
2025-09-16 16:44:49 +02:00
import str from "@/hooks/use-string";
import useTrans from "@/hooks/use-translations";
import {
extractLaravelValidationValue,
extractMinMaxFromValidation,
extractRequiredValidation,
} from "@/hooks/use-laravel-validation";
import VideoInput from "../Inputs/VideoInput";
import { VideoAttributes } from "../Inputs/Video/VideoButton";
2025-09-16 16:44:49 +02:00
2026-02-12 15:42:22 +01:00
/* eslint-disable no-unused-vars */
2025-09-16 16:44:49 +02:00
type DynamicInputsProps = {
name: string;
config: ConfigField[];
content: DynamicInternalField | null;
isChildren?: boolean;
setData: (
name: string,
value: string | number | boolean | File | object | null,
) => void;
reset: (name?: string) => void;
parentErrors?: Record<string, string> | null;
2025-09-16 16:44:49 +02:00
};
2026-02-12 15:42:22 +01:00
/* eslint-enable no-unused-vars */
2025-09-16 16:44:49 +02:00
// Allows to get specific input from enum value.
2025-09-16 16:44:49 +02:00
export default function DynamicInputs({
name,
config,
content = null,
isChildren = false,
2025-09-16 16:44:49 +02:00
setData,
reset,
parentErrors,
2025-09-16 16:44:49 +02:00
}: DynamicInputsProps) {
// Enums.
2026-02-10 15:52:48 +01:00
const enumDynamicFieldTypes = usePage().props
.enumDynamicFieldTypes as DynamicFieldTypes;
const enumElementPosition = usePage().props
.enumElementPosition as LaravelEnum;
2026-02-19 14:06:28 +01:00
const enumContactFormType = usePage().props.enumContactFormType as LaravelEnum
const videoProviderEnum = usePage().props.videoProviderEnum as LaravelEnum;
// Translations.
2025-09-16 16:44:49 +02:00
const transAssociateTo = useTrans("back.form_associate_to");
const transUnsupportedType = useTrans("back.unsupported_type");
/**
* Get a translation for a specific field label.
* Need to recreate useTrans hook to avoid hook error.
* @param fieldLabel string
* @returns string
*/
const getTrans = (fieldLabel: string): string => {
return str(
`${transAssociateTo.split("|")[0].replace(":attribute", fieldLabel)}`,
)
.ucFirst()
.value();
2025-09-16 16:44:49 +02:00
};
return (
<div className="grid grid-cols-1 md:grid-cols-2 items-start gap-4">
{/* Loop on all config elements. */}
2025-09-16 16:44:49 +02:00
{Object.entries(config).map(([id, field]) => {
// Get the enum value from the element type value.
2025-09-16 16:44:49 +02:00
const typeEnum = Object.values(enumDynamicFieldTypes).find(
(def) => def.value === field.type,
);
// Set the name of the current field.
2025-09-16 16:44:49 +02:00
const fieldName = `${name}.${field.key}`;
// Set the content value from the config key.
2026-02-10 15:52:48 +01:00
const fieldValue =
content?.[field.key as keyof typeof content] ?? "";
2025-09-16 16:44:49 +02:00
switch (field.type) {
// String input.
case enumDynamicFieldTypes.string.value:
return (
<SimpleString
key={id}
name={fieldName}
label={getTrans(field.label)}
required={extractRequiredValidation(
field.validation,
)}
2025-09-16 16:44:49 +02:00
value={String(fieldValue)}
setData={setData}
parentErrors={parentErrors}
2025-09-16 16:44:49 +02:00
/>
);
// Textarea input.
case enumDynamicFieldTypes.textarea.value:
return (
<SimpleTextarea
key={id}
name={fieldName}
label={getTrans(field.label)}
required={extractRequiredValidation(
field.validation,
)}
value={String(fieldValue)}
setData={setData}
parentErrors={parentErrors}
/>
);
2025-09-16 16:44:49 +02:00
// Wysiwyg input.
case enumDynamicFieldTypes.wysiwyg.value:
2025-09-16 16:44:49 +02:00
return (
<div key={id} className="col-span-1 md:col-span-2">
<SimpleWysiwyg
name={fieldName}
model="DynamicPage"
required={extractRequiredValidation(
field.validation,
)}
2025-09-16 16:44:49 +02:00
label={getTrans(field.label)}
value={String(fieldValue)}
setData={setData}
parentErrors={parentErrors}
2025-09-16 16:44:49 +02:00
/>
</div>
);
// Numbers input.
case enumDynamicFieldTypes.number.value:
return (
<SimpleNumber
key={id}
name={fieldName}
label={getTrans(field.label)}
limits={extractMinMaxFromValidation(
field.validation,
)}
required={extractRequiredValidation(
field.validation,
)}
2025-09-16 16:44:49 +02:00
value={Number(fieldValue)}
setData={setData}
/>
);
// Switch input.
case enumDynamicFieldTypes.boolean.value:
return (
<div key={id} className="grid grid-cols-1 gap-1.5">
<SimpleSwitch
label={`${getTrans(field.label)} ${extractRequiredValidation(field.validation) ? " *" : ""}`}
2025-09-16 16:44:49 +02:00
name={fieldName}
checked={Boolean(fieldValue)}
setData={setData}
/>
</div>
);
// Url input.
case enumDynamicFieldTypes.url.value:
return (
<SimpleString
key={id}
name={fieldName}
label={getTrans(field.label)}
type="url"
placeholder="ex: https://..."
required={extractRequiredValidation(
field.validation,
)}
2025-09-16 16:44:49 +02:00
value={String(fieldValue)}
setData={setData}
/>
);
// Image input.
case enumDynamicFieldTypes.image.value:
return (
<CompleteInputFile
key={id}
fileName="fichier"
name={fieldName}
label={getTrans(field.label)}
setData={setData}
reset={reset}
value={fieldValue as string | File | null}
required={extractRequiredValidation(
field.validation,
)}
maxFileSize={extractLaravelValidationValue(
field.validation,
"max",
)}
allowedFormats={extractLaravelValidationValue(
field.validation,
"mimes",
)}
validationRules={{
width: extractLaravelValidationValue(
field.validation,
"dimensions",
"width",
),
height: extractLaravelValidationValue(
field.validation,
"dimensions",
"height",
),
}}
/>
);
2025-09-16 16:44:49 +02:00
// Email input.
case enumDynamicFieldTypes.email.value:
return (
<SimpleString
key={id}
name={fieldName}
label={getTrans(field.label)}
type="email"
placeholder="ex: john.doe@ldc.fr"
required={extractRequiredValidation(
field.validation,
)}
2025-09-16 16:44:49 +02:00
value={String(fieldValue)}
setData={setData}
/>
);
// List input.
case enumDynamicFieldTypes.list.value:
return (
<DynamicList
key={id}
name={fieldName}
parentName={name}
content={content}
field={field}
value={
Array.isArray(fieldValue) ? fieldValue : []
}
enumLabel={enumDynamicFieldTypes.list.label}
setData={setData}
reset={reset}
isChildren={isChildren}
/>
);
// File input.
case enumDynamicFieldTypes.file.value:
return (
<CompleteInputFile
key={id}
name={fieldName}
label={getTrans(field.label)}
setData={setData}
reset={reset}
value={fieldValue as string | File | null}
required={extractRequiredValidation(
field.validation,
)}
maxFileSize={extractLaravelValidationValue(
field.validation,
"max",
)}
allowedFormats={extractLaravelValidationValue(
field.validation,
"mimes",
)}
inputType={enumDynamicFieldTypes.file.value}
/>
);
// VimeoId input
case enumDynamicFieldTypes.vimeoid.value:
return (
<VideoInput
name={fieldName}
forcedProvider={videoProviderEnum.vimeo.value}
label={getTrans(field.label)}
value={fieldValue as VideoAttributes}
reset={reset}
setData={setData}
required={extractRequiredValidation(
field.validation,
)}
/>
);
// YoutubeId input
case enumDynamicFieldTypes.youtubeid.value:
return (
<VideoInput
name={fieldName}
forcedProvider={videoProviderEnum.youtube.value}
label={getTrans(field.label)}
value={fieldValue as VideoAttributes}
reset={reset}
setData={setData}
required={extractRequiredValidation(
field.validation,
)}
/>
);
// Date picker.
case enumDynamicFieldTypes.date.value:
return (
<SimpleDatePicker
name={fieldName}
setData={setData}
date={fieldValue as Date}
2026-02-10 15:52:48 +01:00
hasTime
label={getTrans(field.label)}
/>
);
// Color picker.
case enumDynamicFieldTypes.color.value:
return (
<SimpleColorPicker
name={fieldName}
setData={setData}
value={String(fieldValue)}
label={getTrans(field.label)}
2026-02-10 15:52:48 +01:00
required={extractRequiredValidation(
field.validation,
)}
/>
);
// Model select.
case enumDynamicFieldTypes.model.value:
return (
2026-02-12 15:42:22 +01:00
<DynamicWrapperModelSelect
field={field}
fieldName={fieldName}
fieldValue={fieldValue}
content={content}
setData={setData}
2026-02-12 15:42:22 +01:00
getTrans={getTrans}
/>
);
2026-02-10 15:52:48 +01:00
// Static route select.
case enumDynamicFieldTypes.staticroute.value:
return (
<StaticRouteSelect
name={fieldName}
label={getTrans(field.label)}
selected={fieldValue as number}
setData={setData}
2026-02-10 15:52:48 +01:00
required={extractRequiredValidation(
field.validation,
)}
/>
);
// Position select.
case enumDynamicFieldTypes.position.value:
return (
<EnumSelect
name={fieldName}
label={getTrans(field.label)}
placeholder="Positionnement de l'élement"
selected={fieldValue as number}
options={enumElementPosition}
setData={setData}
2026-02-10 15:52:48 +01:00
required={extractRequiredValidation(
field.validation,
)}
/>
);
2026-02-19 14:06:28 +01:00
case enumDynamicFieldTypes.contactform.value:
return (
<EnumSelect
name={fieldName}
label={getTrans(field.label)}
placeholder="Formulaire de contact à associer"
2026-02-19 14:06:28 +01:00
selected={fieldValue as number}
options={enumContactFormType}
setData={setData}
required={extractRequiredValidation(
field.validation,
)}
/>
)
case enumDynamicFieldTypes.video.value:
return (
<VideoInput
name={fieldName}
label={getTrans(field.label)}
value={fieldValue as VideoAttributes}
reset={reset}
setData={setData}
required={extractRequiredValidation(
field.validation,
)}
/>
)
2025-09-16 16:44:49 +02:00
default:
return (
<p
key={id}
className="text-muted-foreground text-sm"
>
{transUnsupportedType}{" "}
{typeEnum?.label ?? field.type}
2025-09-16 16:44:49 +02:00
</p>
);
}
})}
</div>
);
}