|
|
import { FormEventHandler, Fragment, PropsWithChildren, useEffect, useState } from 'react'; import { Dialog, Transition } from '@headlessui/react'; import { FileText, Box, XCircle, ArrowRightCircle, CheckCircle, XOctagon, Code } from 'react-feather'; import { useForm } from '@inertiajs/react'; import FormGroup from '@/Components/FormGroup'; import InputLabel from '@/Components/InputLabel'; import TextInput from '@/Components/TextInput'; import InputError from '@/Components/InputError'; import ErrorButton from '@/Components/ErrorButton'; import PrimaryButton from '@/Components/PrimaryButton'; import axios from 'axios'; import Modal from '@/Components/Modal'; import ModalButton from '@/Components/ModalButton';
export default function AddFrameworkModal({ show = false, maxWidth = '2xl', closeable = true, onClose = () => {}, onFrameworkAdded = () => {}, className = '', }: PropsWithChildren<{ show: boolean; maxWidth?: 'sm' | 'md' | 'lg' | 'xl' | '2xl'; closeable?: boolean; onClose: CallableFunction; onFrameworkAdded: CallableFunction; className?: string; }>) { const close = () => { if (closeable) { onClose(); } };
const maxWidthClass = { sm: 'sm:max-w-sm', md: 'sm:max-w-md', lg: 'sm:max-w-lg', xl: 'sm:max-w-xl', '2xl': 'sm:max-w-2xl', }[maxWidth];
const { data, setData, reset, errors } = useForm({ frameworkName: '', version:'', });
useEffect(() => { return () => { reset('frameworkName'); reset('version'); }; }, []);
const [status, setStatus] = useState(''); const [feedback, setFeedback] = useState(''); const [isSuccessModalOpen, setIsSuccessModalOpen] = useState(false); const [isErrorModalOpen, setIsErrorModalOpen] = useState(false);
const handleCloseSuccessModal = () => { setIsSuccessModalOpen(false); onFrameworkAdded(); close(); }
const submit: FormEventHandler = async (e) => { e.preventDefault();
try { const response = await axios.post(route('framework.add'), data); setStatus('Success') setFeedback(response.data.message); setIsSuccessModalOpen(true); } catch (error) { setStatus('Error') if (axios.isAxiosError(error)) { setFeedback(error.response?.data.message || 'An error occurred'); } else { setFeedback('An unexpected error occurred'); } setIsErrorModalOpen(true); } };
return ( <Transition show={show} as={Fragment} leave="duration-200"> <Dialog as="div" id="modal" className="fixed inset-0 flex overflow-y-auto px-4 py-6 sm:px-0 items-center z-50 transform transition-all" onClose={close} > <Transition.Child as={Fragment} enter="ease-out duration-300" enterFrom="opacity-0" enterTo="opacity-100" leave="ease-in duration-200" leaveFrom="opacity-100" leaveTo="opacity-0" > <div className="absolute inset-0 bg-neutral-0 opacity-50" /> </Transition.Child>
<Transition.Child as={Fragment} enter="ease-out duration-300" enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" enterTo="opacity-100 translate-y-0 sm:scale-100" leave="ease-in duration-200" leaveFrom="opacity-100 translate-y-0 sm:scale-100" leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" > <Dialog.Panel className={`mb-6 bg-white border-4 rounded-lg overflow-hidden shadow-xl items-center transform transition-all sm:w-full sm:mx-auto bg-neutral-white ${maxWidthClass} ${className}`} > <div className="p-4 flex flex-col"> <h1 className="font-bold text-xl text-primary-main flex items-center my-2"><FileText className="stroke-primary-main mr-2" />Add New Framework</h1> <div className="divider"></div>
<form id="AddFrameworkForm"> <div> <FormGroup> <InputLabel htmlFor="frameworkName"><Box className='stroke-neutral-10' /></InputLabel> <label htmlFor="frameworkName" className="mx-2 font-semibold">App Framework Name:</label> </FormGroup> <TextInput id='frameworkName' name='frameworkName' value={data.frameworkName} autoComplete='off' required onChange={(e) => setData('frameworkName', e.target.value)} /> <InputError message={errors.frameworkName} className="mt-2" /> </div>
<div> <FormGroup> <InputLabel htmlFor="version"><Code className='stroke-neutral-10' /></InputLabel> <label htmlFor="version" className="mx-2 font-semibold">Version:</label> </FormGroup> <TextInput id='version' name='version' value={data.version} autoComplete='off' required onChange={(e) => setData('version', e.target.value)} /> <InputError message={errors.version} className="mt-2" /> </div>
<div className='flex items-center justify-center mt-3 w-full'> <ErrorButton type="button" className='w-1/2' onClick={close}> <XCircle className='stroke-neutral-10' /> Cancel </ErrorButton> <PrimaryButton type="button" className='w-1/2' onClick={submit}> <ArrowRightCircle className='stroke-neutral-10' /> Save </PrimaryButton> </div> </form> </div>
<Modal show={isSuccessModalOpen} onClose={() => setIsSuccessModalOpen(false)} maxWidth="lg" styling='success'> <div className="p-4 flex flex-col items-center"> <CheckCircle className='stroke-success-main' size={80} /> <h2 className="text-xl font-bold mt-2">{ status }</h2> <p className="mt-4">{ feedback }</p> <ModalButton onClick={handleCloseSuccessModal} className="bg-success-main text-white hover:bg-success-hover active:bg-success-pressed"> Close </ModalButton> </div> </Modal>
<Modal show={isErrorModalOpen} onClose={() => setIsErrorModalOpen(false)} maxWidth="lg" styling='error'> <div className="p-4 flex flex-col items-center"> <XOctagon className='stroke-error-main' size={80} /> <h2 className="text-xl font-bold mt-2">{ status }</h2> <p className="mt-4">{ feedback }</p> <ModalButton onClick={() => setIsErrorModalOpen(false)} className="bg-error-main text-white hover:bg-error-hover active:bg-error-pressed"> Close </ModalButton> </div> </Modal> </Dialog.Panel> </Transition.Child> </Dialog> </Transition> ); }
|