107 lines
3.8 KiB
TypeScript
107 lines
3.8 KiB
TypeScript
// * Packages
|
|
import { usePage } from "@inertiajs/react";
|
|
import { ReactNode } from "react";
|
|
// * Components shadcn
|
|
import {
|
|
Accordion,
|
|
AccordionContent,
|
|
AccordionItem,
|
|
AccordionTrigger,
|
|
} from "@/components/ui/accordion";
|
|
// * Other
|
|
import str from "@/hooks/use-string";
|
|
import useTrans from "@/hooks/use-translations";
|
|
import { ConfigField, DynamicFieldTypes } from "@/back/types/dynamic-pages";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
type ConfigDetailsProps = {
|
|
config: ConfigField[];
|
|
};
|
|
|
|
export default function ConfigDetails({ config }: ConfigDetailsProps) {
|
|
const enumDynamicFieldTypes = usePage().props
|
|
.enumDynamicFieldTypes as DynamicFieldTypes;
|
|
const getEnumDynamicFieldType = (value: number) => {
|
|
return Object.values(enumDynamicFieldTypes).find(
|
|
(def) => def.value === value,
|
|
);
|
|
};
|
|
|
|
const transType = str(useTrans("validation.custom.type")).ucFirst().value();
|
|
const transLabel = str(useTrans("validation.custom.label"))
|
|
.ucFirst()
|
|
.value();
|
|
const transValidation = str(useTrans("validation.custom.validation"))
|
|
.ucFirst()
|
|
.value();
|
|
|
|
const RenderRows = (
|
|
fields: ConfigField[],
|
|
hasBorders: boolean = false,
|
|
): ReactNode =>
|
|
fields.map((field, index) => {
|
|
const hasChildren = !!field.children?.length;
|
|
const accordionKey = `${field.key}-${index}`;
|
|
|
|
const rowContent = (targetHasChildren: boolean = false) => (
|
|
<div className="grid grid-cols-[1fr_1fr_1fr_auto] items-center w-full gap-4">
|
|
<p className="break-words">
|
|
{getEnumDynamicFieldType(field.type)?.label}
|
|
</p>
|
|
<p className="break-words whitespace-normal">
|
|
{field.label}
|
|
<code className="text-xs ms-1 text-muted-foreground break-words break-all whitespace-normal">{`(${field.key})`}</code>
|
|
</p>
|
|
<div className="text-sm text-muted-foreground break-words">
|
|
{field.validation || "—"}
|
|
</div>
|
|
{!targetHasChildren && <div className="w-[16px]" />}
|
|
</div>
|
|
);
|
|
|
|
return (
|
|
<AccordionItem
|
|
key={accordionKey}
|
|
value={accordionKey}
|
|
className="border-none"
|
|
>
|
|
{hasChildren ? (
|
|
<AccordionTrigger
|
|
className={cn(
|
|
"gap-0 px-4",
|
|
{ "rounded-none border-b mb-2": hasBorders },
|
|
{ "py-2": !hasBorders },
|
|
)}
|
|
>
|
|
{rowContent(hasChildren)}
|
|
</AccordionTrigger>
|
|
) : (
|
|
<div className="px-4 py-2">{rowContent()}</div>
|
|
)}
|
|
|
|
{hasChildren && (
|
|
<AccordionContent>
|
|
<div className="border rounded-md space-y-1">
|
|
{RenderRows(field.children!, false)}
|
|
</div>
|
|
</AccordionContent>
|
|
)}
|
|
</AccordionItem>
|
|
);
|
|
});
|
|
|
|
return (
|
|
<Accordion type="multiple" className="w-full divide-y">
|
|
{/* HEADER */}
|
|
<div className="grid grid-cols-[1fr_1fr_1fr_auto] text-sm font-medium border-b gap-4 px-4 py-2">
|
|
<div>{transType}</div>
|
|
<div>{transLabel}</div>
|
|
<div>{transValidation}</div>
|
|
<div className="w-[16px]" />
|
|
</div>
|
|
|
|
{/* ROWS */}
|
|
{RenderRows(config, true)}
|
|
</Accordion>
|
|
);
|
|
}
|