import { get as _get } from "lodash-es"; import { set as _set } from "lodash-es"; import { PageData } from "."; import { useForm } from "react-hook-form"; import { snakeCase as _snakeCase } from "lodash-es"; import { startCase as _startCase } from "lodash-es"; import XIcon from "./components/icons/x-icon"; import { useCallback, useContext } from "react"; import ImagePicker from "./components/image-picker"; import { CMSContext } from "./cms-provider"; import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, Trash2, } from "lucide-react"; import URLPicker from "./components/url-picker.tsx"; import { RichTextEditor } from "./rich-text-editor"; // import "./cms.css"; import Checkbox from "./components/checkbox"; type FieldValue = PageData[keyof PageData]; export default function ContentifyForm({ onClose }: { onClose: () => void }) { const { editing, pageData, setPageData } = useContext(CMSContext); if (!editing.id) throw new Error("No content to edit"); const { register, handleSubmit, watch, setValue } = useForm({ mode: "onChange", defaultValues: _get( pageData, editing.id // TODO: avoid as ) as FieldValue, }); const isCreatingNew = /\.-1$/.test(editing.id); const path = editing.id.replace(/\.-?\d+$/, ""); const isExistingRepeatable = !isCreatingNew && /\.\d+$/.test(editing.id); const onSubmit = useCallback( (data: FieldValue) => { if (editing.id) { if (isCreatingNew) { const array = (_get(pageData, path, []) as FieldValue[]) || []; array.push(data); _set(pageData, path, array); } else { _set(pageData, editing.id, data); } setPageData(structuredClone(pageData) as PageData); onClose(); } }, [setPageData, pageData, isCreatingNew, onClose, path, editing] ); const onRemove = useCallback(() => { if (editing.id) { const array = (_get(pageData, path, []) as FieldValue[]) || []; const index = Number(editing.id.match(/\d+$/)?.[0]); array.splice(index, 1); _set(pageData, path, array); setPageData(structuredClone(pageData) as PageData); onClose(); } }, [editing.id, onClose, pageData, setPageData, path]); const moveUp = useCallback(() => { const array = (_get(pageData, path, []) as FieldValue[]) || []; const index = Number(editing.id?.match(/\d+$/)?.[0]); if (index > 0) { const item = array.splice(index, 1)[0]; array.splice(index - 1, 0, item); _set(pageData, path, array); setPageData(structuredClone(pageData) as PageData); } onClose(); }, [editing.id, pageData, setPageData, path, onClose]); const moveDown = useCallback(() => { const array = (_get(pageData, path, []) as FieldValue[]) || []; const index = Number(editing.id?.match(/\d+$/)?.[0]); if (index < array.length - 1) { const item = array.splice(index, 1)[0]; array.splice(index + 1, 0, item); _set(pageData, path, array); setPageData(structuredClone(pageData) as PageData); } onClose(); }, [editing.id, pageData, setPageData, path, onClose]); const moveToEnd = useCallback(() => { const array = (_get(pageData, path, []) as FieldValue[]) || []; const index = Number(editing.id?.match(/\d+$/)?.[0]); if (index < array.length - 1) { const item = array.splice(index, 1)[0]; array.push(item); _set(pageData, path, array); setPageData(structuredClone(pageData) as PageData); } onClose(); }, [editing.id, pageData, setPageData, path, onClose]); const moveToFirst = useCallback(() => { const array = (_get(pageData, path, []) as FieldValue[]) || []; const index = Number(editing.id?.match(/\d+$/)?.[0]); if (index > 0) { const item = array.splice(index, 1)[0]; array.unshift(item); _set(pageData, path, array); setPageData(structuredClone(pageData) as PageData); } onClose(); }, [editing.id, pageData, setPageData, path, onClose]); return (

{isCreatingNew ? "Add" : "Edit"}{" "} {_startCase(editing.id.replace(/\.-?\d+$/, ""))}

{isExistingRepeatable && ( )}
{editing.inputs.map((input) => { const id = _snakeCase(input?.label); return ["image", "video"].includes(input.type) ? (
{ setValue(input.id, _); }} />
) : input.type === "boolean" ? ( setValue(input.id, checked ? "_blank" : "_self") } /> ) : input.type === "url" ? ( setValue(input.id, url)} onChangeOpenInNewTab={() => {}} /> ) : input.type === "rich-text" ? (
{ setValue(input.id, value); }} />
) : (
); })}
{!isCreatingNew && /\.\d+$/.test(editing.id) && (
)}
); }