import { OutputData } from "@editorjs/editorjs"; import { ChannelCollectionData } from "@saleor/channels/utils"; import { createChannelsChangeHandler } from "@saleor/collections/utils"; import { COLLECTION_CREATE_FORM_ID } from "@saleor/collections/views/consts"; import { useExitFormDialog } from "@saleor/components/Form/useExitFormDialog"; import { MetadataFormData } from "@saleor/components/Metadata"; import { RichTextEditorChange } from "@saleor/components/RichTextEditor"; import useForm, { CommonUseFormResultWithHandlers, FormChange, SubmitPromise } from "@saleor/hooks/useForm"; import useHandleFormSubmit from "@saleor/hooks/useHandleFormSubmit"; import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger"; import useRichText from "@saleor/utils/richText/useRichText"; import React, { useEffect } from "react"; export interface CollectionCreateFormData extends MetadataFormData { backgroundImage: { url: string; value: string; }; backgroundImageAlt: string; channelListings: ChannelCollectionData[]; name: string; slug: string; seoDescription: string; seoTitle: string; } export interface CollectionCreateData extends CollectionCreateFormData { description: OutputData; } interface CollectionCreateHandlers { changeMetadata: FormChange; changeDescription: RichTextEditorChange; changeChannels: ( id: string, data: Omit ) => void; } export type UseCollectionCreateFormResult = CommonUseFormResultWithHandlers< CollectionCreateData, CollectionCreateHandlers >; export interface CollectionCreateFormProps { currentChannels: ChannelCollectionData[]; setChannels: (data: ChannelCollectionData[]) => void; children: (props: UseCollectionCreateFormResult) => React.ReactNode; onSubmit: (data: CollectionCreateData) => SubmitPromise; } const getInitialData = ( currentChannels: ChannelCollectionData[] ): CollectionCreateFormData => ({ backgroundImage: { url: null, value: null }, backgroundImageAlt: "", channelListings: currentChannels, metadata: [], name: "", privateMetadata: [], seoDescription: "", seoTitle: "", slug: "" }); function useCollectionCreateForm( currentChannels: ChannelCollectionData[], setChannels: (data: ChannelCollectionData[]) => void, onSubmit: (data: CollectionCreateData) => SubmitPromise ): UseCollectionCreateFormResult { const { handleChange, data: formData, triggerChange, setChanged, hasChanged, formId } = useForm(getInitialData(currentChannels), undefined, { confirmLeave: true, formId: COLLECTION_CREATE_FORM_ID }); const handleFormSubmit = useHandleFormSubmit({ formId, onSubmit, setChanged }); const { setExitDialogSubmitRef } = useExitFormDialog({ formId }); const [description, changeDescription] = useRichText({ initial: null, triggerChange }); const { makeChangeHandler: makeMetadataChangeHandler } = useMetadataChangeTrigger(); const changeMetadata = makeMetadataChangeHandler(handleChange); // Need to make it function to always have description.current up to date const getData = (): CollectionCreateData => ({ ...formData, description: description.current }); const handleChannelChange = createChannelsChangeHandler( currentChannels, setChannels, triggerChange ); const submit = () => handleFormSubmit(getData()); useEffect(() => setExitDialogSubmitRef(submit), [submit]); return { change: handleChange, data: getData(), handlers: { changeChannels: handleChannelChange, changeDescription, changeMetadata }, hasChanged, submit }; } const CollectionCreateForm: React.FC = ({ currentChannels, setChannels, children, onSubmit }) => { const props = useCollectionCreateForm(currentChannels, setChannels, onSubmit); return
{children(props)}
; }; CollectionCreateForm.displayName = "CollectionCreateForm"; export default CollectionCreateForm;