import { useEffect, useRef, useState } from "react"; import InputText, { RefInputText } from "~/components/ui/input/InputText"; import StringUtils from "~/utils/shared/StringUtils"; import TableSimple from "~/components/ui/tables/TableSimple"; import { useTranslation } from "react-i18next"; import ButtonSecondary from "~/components/ui/buttons/ButtonSecondary"; import ButtonPrimary from "~/components/ui/buttons/ButtonPrimary"; import InputSelect from "~/components/ui/input/InputSelect"; import { Form, useFetcher } from "react-router"; import { JsonPropertyDto, JsonPropertyType, JsonPropertyTypes } from "~/modules/jsonProperties/dtos/JsonPropertyTypeDto"; import InputCheckbox from "~/components/ui/input/InputCheckbox"; // import {toast} from "sonner"; import toast from "react-hot-toast"; import SlideOverWideEmpty from "~/components/ui/slideOvers/SlideOverWideEmpty"; import { Button } from "~/components/ui/button"; import TrashIcon from "~/components/ui/icons/TrashIcon"; import PencilIcon from "~/components/ui/icons/PencilIcon"; import ConfirmModal, { RefConfirmModal } from "~/components/ui/modals/ConfirmModal"; interface Props { item: JsonPropertyDto | null; // onUpdate?: (item: JsonPropertyDto) => void; // onAdd?: (item: JsonPropertyDto) => void; onClose: () => void; } export default function JsonPropertyForm({ item, onClose }: Props) { const { t } = useTranslation(); const fetcher = useFetcher<{ error?: string; success?: string }>(); const confirmDelete = useRef(null); const [selectedOption, setSelectedOption] = useState<{ value: string; name: string } | null>(); const [name, setName] = useState(item ? item.name : ""); const [title, setTitle] = useState(item ? item.title : ""); const [type, setType] = useState(item ? (item.type as any) : "string"); const [options, setOptions] = useState<{ value: string; name: string }[]>(item?.options || []); const [isRequired, setIsRequired] = useState(item ? item.required : false); useEffect(() => { if (fetcher.data?.success) { toast.success(fetcher.data.success); onClose(); } else if (fetcher.data?.error) { toast.error(fetcher.data.error); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [fetcher.data]); const mainInput = useRef(null); useEffect(() => { setTimeout(() => { mainInput.current?.input.current?.focus(); }, 100); }, []); useEffect(() => { if (!item) { if (title.includes(".")) { const keys = title.split("."); setName(StringUtils.toCamelCase(keys[keys.length - 1].toLowerCase())); } else { setName(StringUtils.toCamelCase(title.toLowerCase())); } } }, [item, title, type]); function onAccept() { if (item === null) { const form = new FormData(); form.append("action", "properties-add"); form.set( "property", JSON.stringify({ name, title, type, required: isRequired, options: type === "select" || type === "multiselect" ? options : null, }) ); fetcher.submit(form, { method: "post", }); // if (onAdd) { // onAdd({ // name, // title, // type, // required: isRequired, // options: type === "select" || type === "multiselect" ? options : null, // }); // } } else { const form = new FormData(); form.append("action", "properties-edit"); form.set("name", item.name); form.set( "property", JSON.stringify({ ...item, name, title, type, options: type === "select" || type === "multiselect" ? options : null, required: isRequired, }) ); fetcher.submit(form, { method: "post", }); // if (onUpdate) { // onUpdate({ // ...item, // name, // title, // type, // options: type === "select" || type === "multiselect" ? options : null, // required: isRequired, // }); // } } } function onSubmit(e: React.FormEvent) { e.preventDefault(); onAccept(); } function onDelete(item: JsonPropertyDto) { confirmDelete.current?.setValue(item); confirmDelete.current?.show(t("shared.confirmDelete"), t("shared.delete"), t("shared.cancel"), t("shared.warningCannotUndo")); } function onDeleteConfirmed(item: JsonPropertyDto) { const form = new FormData(); form.set("action", "properties-delete"); form.set("name", item.name); fetcher.submit(form, { method: "post", }); } return (
setType(e as JsonPropertyType)} options={JsonPropertyTypes.map((property) => ({ name: t(`models.jsonProperty.types.${property.value}`), value: property.value, }))} required />
{(type === "select" || type === "multiselect") && (
{/* Caption for an options table, not a single form control. */}
{t("models.jsonProperty.options")}
setSelectedOption(i), renderTitle: (_) => , }, { title: t("shared.remove"), onClick: (_, i) => setOptions((prev) => prev.filter((o) => o.value !== i.value)), renderTitle: (_) => , }, ]} headers={[ { name: "name", title: t("shared.name"), value: (item) => item.name, }, { name: "value", title: t("shared.value"), className: "w-full", value: (item) => item.value, }, ]} />
)}
{item && ( onDelete(item)}> {t("shared.delete")} )}
{t("shared.back")} {t("shared.accept")}
setSelectedOption(undefined)} size="sm" > {selectedOption !== undefined && ( setSelectedOption(undefined)} onUpdate={(option) => { if (selectedOption) { // onChange(items.map((item) => (item === selectedProperty ? property : item))); setOptions(options.map((o) => (o === selectedOption ? option : o))); } else { setOptions([...options, option]); } setSelectedOption(undefined); }} onAdd={(option) => { setOptions([...options, option]); setSelectedOption(undefined); }} /> )}
); } function PropertyOptionForm({ item, onUpdate, onAdd, onClose, }: { item: { name: string; value: string } | null; onUpdate: (option: { name: string; value: string }) => void; onAdd: (option: { name: string; value: string }) => void; onClose: () => void; }) { const { t } = useTranslation(); const [name, setName] = useState(item ? item.name : ""); const [value, setValue] = useState(item ? item.value : ""); const mainInput = useRef(null); useEffect(() => { setTimeout(() => { mainInput.current?.input.current?.focus(); }, 100); }, []); useEffect(() => { if (!item) { if (name.includes(".")) { const keys = name.split("."); setValue(StringUtils.toCamelCase(keys[keys.length - 1].toLowerCase())); } else { setValue(StringUtils.toCamelCase(name.toLowerCase())); } } }, [item, name]); function onAccept() { if (item === null) { onAdd({ name, value, }); } else { onUpdate({ ...item, name, value, }); } } function onSubmit(e: React.FormEvent) { e.preventDefault(); onAccept(); } return (
{t("shared.back")}
{t("shared.accept")}
); }