import { motion, AnimatePresence } from 'framer-motion'; import React, { useEffect, useState } from 'react'; import toast from 'react-hot-toast'; import { MdOutlineClose } from 'react-icons/md'; import { useDispatch } from 'react-redux'; import { v4 as uuid } from 'uuid'; import { addTodo, updateTodo } from '../slices/todoSlice'; import styles from '../styles/modules/modal.module.scss'; import Button from './Button'; const dropIn = { hidden: { opacity: 0, transform: 'scale(0.9)', }, visible: { transform: 'scale(1)', opacity: 1, transition: { duration: 0.1, type: 'spring', damping: 25, stiffness: 500, }, }, exit: { transform: 'scale(0.9)', opacity: 0, }, }; function ClassModal({ type, modalOpen, setModalOpen, todo }) { const [title, setTitle] = useState(''); const [tasktype, setTaskType] = useState(''); const [status, setStatus] = useState('incomplete'); useEffect(() => { if (type === 'update' && todo) { setTitle(todo.title); setTaskType(todo.tasktype); setStatus(todo.status); } else { // default setTitle(''); setTaskType(''); setStatus('incomplete'); } }, [type, todo, modalOpen]); const dispatch = useDispatch(); // handle submission functionality const handleSubmit = (e) => { // for help, want to deal with GPT API eventually e.preventDefault(); if (title === '') { toast.error('Please enter a title.'); return; } if (tasktype === '') { toast.error('Please enter a tasktype.'); return; } if (title && status && tasktype) { if (type === 'add') { dispatch( addTodo({ id: uuid(), title, tasktype, status, time: new Date().toLocaleString(), }) ); toast.success('Task Added Successfully'); } if (type === 'update') { // update if ( todo.title !== title || todo.tasktype !== tasktype || todo.status !== status ) { dispatch(updateTodo({ ...todo, title, tasktype, status })); } else { toast.error('No changes made.'); return; } } setModalOpen(false); } }; return ( <div> <AnimatePresence> {modalOpen && ( <motion.div className={styles.wrapper} initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} > <motion.div className={styles.container} variants={dropIn} initial="hidden" animate="visible" exit="exit" > <motion.div className={styles.closeButton} onClick={() => setModalOpen(false)} onKeyDown={() => setModalOpen(false)} tabIndex={0} role="button" initial={{ top: 40, opacity: 0 }} animate={{ top: -10, opacity: 1 }} exit={{ top: 40, opacity: 0 }} > <MdOutlineClose /> </motion.div> <form className={styles.form} onSubmit={(e) => handleSubmit(e)}> <h1 className={styles.formTitle}> {type === 'update' ? 'Update' : 'Add'} Task </h1> <label htmlFor="taskinfo"> Title <input type="text" id="title" value={title} onChange={(e) => setTitle(e.target.value)} /> </label> <label htmlFor="typeTask"> Type of Task <select name="tasktype" id="tasktype" value={tasktype} onChange={(e) => setTaskType(e.target.value)} > <option value="">SELECT TASK TYPE</option> <option value="Graduation Requirements"> Graduation Requirements </option> <option value="Homework">Homework</option> <option value="Quiz or Unit Test">Quiz or Unit Test</option> <option value="Exam">Midterm or Final</option> <option value="Higher Education">Higher Education</option> <option value="Job Search">Job Search</option> <option value="Student Employment"> Student Employment </option> <option value="Extracurriculars">Extracurriculars</option> <option value="Other">Other</option> </select> </label> <label htmlFor="status"> Status <select name="status" id="status" value={status} onChange={(e) => setStatus(e.target.value)} > <option value="incomplete">Incomplete</option> <option value="help">Need Help - Suggest Next Steps</option> <option value="complete">Complete</option> </select> </label> <div className={styles.buttonContainer}> <Button type="submit" variant="primary"> {type === 'update' ? 'Update' : 'Add'} Task </Button> <Button type="button" variant="secondary" onClick={() => setModalOpen(false)} onKeyDown={() => setModalOpen(false)} tabIndex={0} role="button" > Cancel </Button> </div> </form> </motion.div> </motion.div> )} </AnimatePresence> </div> ); } export default ClassModal;