CreateUpdateModel (Subscription Unlimited Design)
unknown
javascript
6 months ago
14 kB
2
Indexable
'use client'; import Button from '@/components/Formik/Button'; import DragAndDropUpload from '@/components/Formik/DragAndDropUpload'; import InputField from '@/components/Formik/InputField'; import { SerializedError } from '@/features/api/apiSlice'; import { useUpdateSubscriptionMutation } from '@/features/super-admin/subscription/subscriptionApi'; import getSubDetailsObject from '@/utils/get-subscription-details-object'; import objectToFormData from '@/utils/objectToFormData'; import { FieldArray, Form, Formik } from 'formik'; import { useEffect, useState } from 'react'; import toast from 'react-hot-toast'; import { BsCheck2Circle, BsPatchCheck } from 'react-icons/bs'; import { IoCloseOutline, IoStorefrontOutline } from 'react-icons/io5'; import { LuCalendarDays, LuCircleDollarSign } from 'react-icons/lu'; import { RiTeamLine } from 'react-icons/ri'; import { TbInfinity, TbInfinityOff } from 'react-icons/tb'; import { ActionIcon, Modal, Title } from 'rizzui'; import * as Yup from 'yup'; export default function CreateUpdateModel({ setFormData, formData, modalState, setModalState, }: { formData: any; modalState: boolean; setFormData: (data: any) => void; setModalState: (state: boolean) => void; }) { const [isSubmitting, setIsSubmitting] = useState(false); const [updateSubscription, { isSuccess: updateSuccess, error: updateError }] = useUpdateSubscriptionMutation(); const initialValues = { title: formData?.title || '', price: formData?.price || 0, image: formData?.image || null, allowTotalBranch: formData?.allowTotalBranch || null, allowTotalTeamMember: formData?.allowTotalTeamMember || null, allowTotalStamp: formData?.allowTotalStamp || null, limit: formData?.limit || null, descriptions: formData?.descriptions || getSubDetailsObject(false), type: formData?.type || 'subscription', slug: formData?.slug || '', duration: formData?.duration || 0, }; const validationSchema = Yup.object({ title: Yup.string().trim().required('Required!'), price: Yup.mixed().required('Required!'), slug: Yup.string().trim().required('Required!'), type: Yup.mixed().oneOf(['subscription', 'addon']).required('Required!'), allowTotalBranch: Yup.string().when('type', { is: 'subscription', then: () => Yup.string().required('Required!').notOneOf(['0'], 'The value 0 is not allowed!'), otherwise: () => Yup.number().nullable(), }), allowTotalTeamMember: Yup.string().when('type', { is: 'subscription', then: () => Yup.string().required('Required!').notOneOf(['0'], 'The value 0 is not allowed!'), otherwise: () => Yup.number().nullable(), }), allowTotalStamp: Yup.string().when('type', { is: 'subscription', then: () => Yup.string().required('Required!').notOneOf(['0'], 'The value 0 is not allowed!'), otherwise: () => Yup.number().nullable(), }), limit: Yup.string().when('type', { is: 'addon', then: () => Yup.number().required('Required!'), otherwise: () => Yup.number().nullable(), }), descriptions: Yup.string().when('type', { is: 'subscription', then: () => Yup.array() .of(Yup.string().required('Array must contain a string')) .min(1, 'Array must contain at least one string') .required('Required!'), otherwise: () => Yup.array().nullable(), }), }); // Submit Handler const submitHandler = async (values: any) => { setIsSubmitting(true); const isFile = (obj: any): obj is File => obj instanceof File; let objToFormData: FormData; console.log({ values }); if (formData?._id) { const ignoreList = []; if (values?.type === 'subscription') { ignoreList.push('limit'); } else { ignoreList.push('allowTotalBranch', 'allowTotalTeamMember', 'allowTotalStamp'); } if (!isFile(values?.image)) ignoreList.push('image'); objToFormData = objectToFormData(values, ignoreList); updateSubscription({ id: formData._id, data: objToFormData }); } }; // Handle Update Response useEffect(() => { if (updateError) { const myError = updateError as SerializedError; toast.error(myError?.data?.message || 'Something went wrong. Please try again!.'); setIsSubmitting(false); } if (updateSuccess) { toast.success('Subscription updated successfully!'); setFormData({}); setIsSubmitting(false); setModalState(false); } }, [setFormData, setModalState, updateError, updateSuccess]); return ( <Modal isOpen={modalState} onClose={() => setModalState(true)} customSize="650px"> <div className="m-auto px-7 pb-8 pt-6"> <div className="mb-7 flex items-center justify-between"> {formData?._id ? <Title as="h4">Update A Subscription</Title> : <Title as="h4">Add New Subscription</Title>} <ActionIcon size="sm" variant="text" onClick={() => { setModalState(false); setFormData({}); }} > <IoCloseOutline className="text-2xl text-danger" /> </ActionIcon> </div> <div> <Formik initialValues={initialValues} validationSchema={validationSchema} onSubmit={submitHandler}> {({ values, setFieldValue }) => { return ( <Form className="mt-5"> {formData?._id && formData?.type === 'subscription' && ( <div className="my-5 flex justify-center"> <DragAndDropUpload value={{ name: 'image', image: values.image }} onChange={(image: any) => setFieldValue('image', image)} className="mt-2" size={1024 * 1000} sizeText="1MB" isRounded={true} uploadText="Upload Image" /> </div> )} <div className="flex gap-3"> <InputField name="title" label="Title" placeholder="Title" /> <InputField name="price" disabled={formData?.slug === 'trial' ? true : false} label="Price (CAD)" type="number" placeholder="9.99" prefix={<LuCircleDollarSign className="text-xl" />} /> {formData?.slug === 'trial' && ( <InputField name="duration" label="Duration (Days)" type="number" placeholder="7" prefix={<LuCalendarDays className="text-xl" />} /> )} </div> <div className="my-3 flex gap-3"> {formData?.type === 'subscription' && ( <InputField name="allowTotalBranch" label="Total Branch" type="number" placeholder="1" prefix={<IoStorefrontOutline className="text-xl" />} suffix={ values.allowTotalBranch < 0 ? ( <TbInfinity className="cursor-pointer text-xl" title="Infinite" onClick={() => setFieldValue('allowTotalBranch', '')} /> ) : ( <TbInfinityOff className="cursor-pointer text-xl" title="Non-Infinite" onClick={() => setFieldValue('allowTotalBranch', '-1')} /> ) } disabled={values.allowTotalBranch < 0} /> )} {formData?.type === 'subscription' && ( <InputField name="allowTotalTeamMember" label="Total Team Member" type="number" placeholder="1" prefix={<RiTeamLine className="text-xl" />} suffix={ values.allowTotalTeamMember < 0 ? ( <TbInfinity className="cursor-pointer text-xl" title="Infinite" onClick={() => setFieldValue('allowTotalTeamMember', '')} /> ) : ( <TbInfinityOff className="cursor-pointer text-xl" title="Non-Infinite" onClick={() => setFieldValue('allowTotalTeamMember', '-1')} /> ) } disabled={values.allowTotalTeamMember < 0} /> )} {formData?.type === 'subscription' && ( <InputField name="allowTotalStamp" label="Total Stamp" type="number" placeholder="1" prefix={<BsPatchCheck className="text-xl" />} suffix={ values.allowTotalStamp < 0 ? ( <TbInfinity className="cursor-pointer text-xl" title="Infinite" onClick={() => setFieldValue('allowTotalStamp', '')} /> ) : ( <TbInfinityOff className="cursor-pointer text-xl" title="Non-Infinite" onClick={() => setFieldValue('allowTotalStamp', '-1')} /> ) } disabled={values.allowTotalStamp < 0} /> )} {formData?.type !== 'subscription' && <InputField name="limit" type="number" label="Limit" placeholder="0" />} </div> <div className="relative mt-4 grid grid-cols-1 gap-4"> <FieldArray name="descriptions" render={(arrayHelpers) => ( <div> {values?.descriptions?.map((des: any, index: number) => ( <div key={des.id} className="z-1 relative mb-4 flex items-center gap-2"> {index !== 0 && ( <div className="absolute right-0 top-0 flex h-4 w-4 cursor-pointer items-center justify-center rounded-full bg-red-500 text-white" onClick={() => arrayHelpers.remove(index)} > - </div> )} <div className="flex-grow"> <div className="flex flex-col"> <InputField label={`Description (${index + 1})`} name={`descriptions[${index}]`} placeholder="Write here..." required={true} /> </div> </div> </div> ))} <button type="button" className="flex cursor-pointer items-center justify-center rounded-lg bg-danger px-3 py-1 text-white" onClick={() => arrayHelpers.push('')} > + Add </button> </div> )} /> </div> <p className="mt-3 text-end text-xs font-semibold"> Fields marked with <span className="text-danger">*</span> are mandatory! </p> <p className="mt-1 text-end text-xs font-semibold"> <span className="text-danger">-1</span> indicates an <span className="text-danger">infinite</span>! </p> <p className="mt-1 flex items-center justify-end gap-x-1 text-xs font-semibold"> <TbInfinity className="text-base text-danger" /> <span>indicates an </span> <span className="text-danger"> infinite sign!</span> </p> <p className="mt-1 flex items-center justify-end gap-x-1 text-xs font-semibold"> <TbInfinityOff className="text-base text-danger" /> <span>indicates a </span> <span className="text-danger"> non-infinite sign!</span> </p> <div className="mt-6 flex justify-end"> <Button color="danger" type="submit" text={formData?._id ? 'Update' : 'Submit'} postIcon={<BsCheck2Circle className="text-base" />} isSubmitting={isSubmitting} /> </div> </Form> ); }} </Formik> </div> </div> </Modal> ); }
Editor is loading...
Leave a Comment