ldc-groupe/resources/ts/back/Pages/Document/Form.tsx
2026-02-25 16:15:16 +01:00

390 lines
15 KiB
TypeScript

// * Packages
import { useForm, usePage } from "@inertiajs/react";
import { BookTextIcon, CogIcon, RefreshCwIcon } from "lucide-react";
import { useState } from "react";
// * Other
import FieldsetWrapper from "@/back/Components/FieldsetWrapper";
import InputError from "@/back/Components/InputError";
import SimpleString from "@/back/Components/Inputs/SimpleString";
import EnumSelect from "@/back/Components/Inputs/EnumSelect";
import SimpleDatePicker from "@/back/Components/Inputs/SimpleDatePicker";
import CompleteInputFile from "@/back/Components/Inputs/CompleteInputFile";
import SubmitButton from "@/back/Components/SubmitButton";
import SimpleSwitch from "@/back/Components/Inputs/SimpleSwitch";
import BtnOptionnalLinkWithTooltip from "@/back/Components/BtnOptionnalLinkWithTooltip";
import { ModelSelect } from "@/back/Components/Inputs/ModelSelect";
import { AppEnv, LaravelEnum } from "@/back/types/global";
import { DynamicFieldTypes } from "@/back/types/dynamic-pages";
import { DocumentModel } from "@/back/types/others";
import useTrans from "@/hooks/use-translations";
import str from "@/hooks/use-string";
import { extractIdsFromDatabasePivotRelation } from "@/lib/mapPivotOptions";
import useCrudSubmit from "@/hooks/use-crud-submit";
import SimpleVideoUpload from "@/back/Components/Inputs/SimpleVideoUpload";
export default function Form({
model,
modelName,
modelRoute,
action,
method,
}: {
model?: DocumentModel;
modelName: string;
modelRoute: string;
action: string;
method: number;
}) {
const { locale, url } = usePage().props.appEnv as AppEnv;
const enumDynamicFieldTypes = usePage().props
.enumDynamicFieldTypes as DynamicFieldTypes;
const enumDocStatus = usePage().props.enumDocumentStatus as LaravelEnum;
const enumYears = usePage().props.enumYears as LaravelEnum;
const [dynamicKey, setDynamicKey] = useState<number | null>(null);
const defaultCategoriesOptions = extractIdsFromDatabasePivotRelation(
model?.categories,
);
const defaultTagsOptions = extractIdsFromDatabasePivotRelation(model?.tags);
/** Form section */
const { post, setData, data, reset } = useForm({
name: model?.name ? model?.name[locale] : "",
exercice: model?.exercice ? model?.exercice : "",
status: model?.status ?? enumDocStatus.unpublished.value,
path: model?.path ? model?.path[locale] : null,
tags: model?.tags ? defaultTagsOptions : [],
is_issuu: model?.is_issuu ?? false,
issuu_path: model?.issuu_path ? model?.issuu_path[locale] : "",
categories: model?.categories ? defaultCategoriesOptions : [],
published_at: model?.published_at ? model?.published_at : null,
unpublished_at: model?.unpublished_at ? model?.unpublished_at : null,
});
const submitCrud = useCrudSubmit({
method,
modelRoute,
modelName,
action,
model,
post,
data,
});
const originalDataPath =
model && model.path && model.path[locale]
? model.path[locale]
: undefined;
const refreshFileFromDb = () => {
if (model && model.path) {
setData("issuu_path", "");
setData("is_issuu", false);
setData("path", model.path[locale]);
setDynamicKey(Date.now());
}
if (model && model.is_issuu) {
setData(
"issuu_path",
model?.issuu_path ? model.issuu_path[locale] : "",
);
setData("is_issuu", true);
setData("path", null);
setDynamicKey(Date.now());
}
};
//* TRANSLATIONS
const transAssociatedIssuPathLabel = useTrans("back.form_associate_to", {
params: {
attribute: useTrans("validation.custom.issuu_path"),
},
choice: 1,
});
const transAssociatedIssuPathPlaceholder = useTrans(
"back.issuu.issuu_path.placeholder",
);
const transAssociatePathLabel = useTrans("back.form_associate_to", {
params: {
attribute: useTrans("validation.custom.file"),
},
choice: 1,
});
const transRefreshOriginal = useTrans("back.refresh_original");
return (
<form onSubmit={submitCrud}>
<InputError all />
<FieldsetWrapper
title={useTrans("back.form_title_global")}
icon={<BookTextIcon className="mr-1" />}
description={useTrans("back.form_subtitle_global")}
className="sm:grid-cols-2 gap-4"
>
<SimpleString
name="name"
label={str(
useTrans("back.form_associate_to", {
params: {
attribute: useTrans(
"validation.attributes.name",
),
},
choice: 1,
}),
)
.ucFirst()
.value()}
required
placeholder="ex: John Doe"
value={data.name ?? ""}
setData={setData}
/>
</FieldsetWrapper>
<FieldsetWrapper
title={useTrans("back.form_title_configuration")}
icon={<CogIcon className="mr-1" />}
description={useTrans("back.form_subtitle_configuration")}
className="sm:grid-cols-2 gap-4"
>
<SimpleDatePicker
name="published_at"
setData={setData}
date={data.published_at}
hasTime
label={str(
useTrans("back.form_associate_to", {
params: {
attribute: useTrans(
"validation.custom.published_at",
),
},
choice: 1,
}),
)
.ucFirst()
.value()}
/>
<SimpleDatePicker
name="unpublished_at"
setData={setData}
date={data.unpublished_at}
hasTime
label={str(
useTrans("back.form_associate_to", {
params: {
attribute: useTrans(
"validation.custom.unpublished_at",
),
},
choice: 1,
}),
)
.ucFirst()
.value()}
/>
<EnumSelect
name="status"
options={enumDocStatus}
label={str(
useTrans("back.form_associate_to", {
params: {
attribute: useTrans("validation.custom.status"),
},
choice: 1,
}),
)
.ucFirst()
.value()}
placeholder={`ex: ${enumDocStatus.unpublished.label}`}
selected={Number(data.status)}
setData={setData}
/>
</FieldsetWrapper>
<FieldsetWrapper
key={dynamicKey}
title={useTrans("back.form_title_content")}
icon={<BookTextIcon className="mr-1" />}
description={useTrans("back.form_subtitle_content")}
className="sm:grid-cols-2 gap-4"
>
<SimpleSwitch
label={str(useTrans("validation.custom.is_issuu"))
.ucFirst()
.value()}
name="is_issuu"
checked={data.is_issuu}
setData={(_, value) => {
if (data.path || data.issuu_path) {
setData((prev) => ({
...prev,
path: "",
issuu_path: "",
}));
}
setData("is_issuu", value);
setDynamicKey(Date.now());
}}
/>
<div className="flex flex-col w-full gap-1">
<div className="flex items-end gap-1">
{data.is_issuu ? (
<SimpleString
name="issuu_path"
label={str(transAssociatedIssuPathLabel)
.ucFirst()
.value()}
required={false}
placeholder={str(
transAssociatedIssuPathPlaceholder,
)
.ucFirst()
.value()}
value={data.issuu_path ?? ""}
setData={setData}
/>
) : (
// <CompleteInputFile
// originalData={originalDataPath}
// fileName="path"
// modelRoute={modelName}
// name="path"
// label={str(transAssociatePathLabel)
// .ucFirst()
// .value()}
// setData={setData}
// hasRefreshBtn={false}
// // @ts-expect-error Types diff between custom reset and useForm reset.
// reset={reset}
// value={data.path}
// required={false}
// maxFileSize="10240"
// allowedFormats="pdf"
// inputType={enumDynamicFieldTypes.file.value}
// />
<SimpleVideoUpload
width={"100%"}
height={100}
label="Vidéo uploader"
name="path"
setData={setData}
required={true}
/>
)}
{(model?.issuu_path || model?.path) && (
<BtnOptionnalLinkWithTooltip
className={data.is_issuu ? "h-10" : "h-36"}
variant="secondary"
onClick={refreshFileFromDb}
content={<RefreshCwIcon />}
tooltipContent={str(transRefreshOriginal)
.ucFirst()
.value()}
/>
)}
</div>
{!data.is_issuu && model?.path && originalDataPath && (
<a
target="_blank"
className="text-blue-500 underline text-xs"
href={`${url}/${originalDataPath}`}
rel="noreferrer"
>
{`${url}/${originalDataPath}`}
</a>
)}
</div>
<ModelSelect
targetModel="document_tag"
label={str(
useTrans("back.form_associate_to", {
params: {
attribute: useTrans(
"models.classes.document-tag",
{ choice: 2 },
),
},
choice: 2,
}),
)
.ucFirst()
.value()}
multiple
name="tags"
required={false}
variant="inverted"
placeholder={str(useTrans("back.document.tag.placeholder"))
.ucFirst()
.value()}
singleLine
setData={setData}
defaultValues={defaultTagsOptions}
closeButtonVisible
/>
<ModelSelect
targetModel="document_category"
label={str(
useTrans("back.form_associate_to", {
params: {
attribute: useTrans(
"models.classes.document-category",
{ choice: 2 },
),
},
choice: 2,
}),
)
.ucFirst()
.value()}
multiple
name="categories"
required={false}
variant="inverted"
placeholder={str(
useTrans("back.document.category.placeholder"),
)
.ucFirst()
.value()}
singleLine
setData={setData}
defaultValues={defaultCategoriesOptions}
closeButtonVisible
/>
<EnumSelect
name="exercice"
options={enumYears}
label={str(
useTrans("back.form_associate_to", {
params: {
attribute: useTrans(
"models.classes.document-exercice",
{
choice: 2,
},
),
},
choice: 2,
}),
)
.ucFirst()
.value()}
required={false}
placeholder={str(
useTrans("back.document.exercice.placeholder"),
)
.ucFirst()
.value()}
selected={Number(data.exercice)}
setData={setData}
/>
</FieldsetWrapper>
<div className="text-center">
<SubmitButton
modelTrans={useTrans(`models.classes.${modelName}`, {
choice: 1,
})}
/>
</div>
</form>
);
}