import { format } from 'date-fns/esm'; import React, { useEffect, useState } from 'react'; import toast from 'react-hot-toast'; import { MdDelete, MdEdit } from 'react-icons/md'; import { useDispatch } from 'react-redux'; import { motion } from 'framer-motion'; import { deleteTodo, updateTodo } from '../slices/todoSlice'; import styles from '../styles/modules/todoItem.module.scss'; import { getClasses } from '../utils/getClasses'; import CheckButton from './CheckButton'; import ClassModal from './ClassModal'; const child = { hidden: { y: 20, opacity: 0 }, visible: { y: 0, opacity: 1 }, }; async function getResponse(text) { const url = 'https://api.openai.com/v1/completions'; try { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${process.env.REACT_APP_API_KEY}`, }, body: JSON.stringify({ model: 'davinci', prompt: `I need advice on how to ${text}.`, temperature: 1.2, max_tokens: 100, n: 1, stop: '\n', }), }); const data = await response.json(); return data.choices[0].text.trim(); } catch (error) { console.log(error); const advice = 'Let me think about it and get back to you...sorry about that! Good luck!'; return advice; } } async function getAdvice({ text, setAdvice }) { try { const advice = await getResponse(text); setAdvice(advice); } catch (error) { console.log(error); const advice = 'Let me think about it and get back to you...sorry about that! Good luck!'; setAdvice(advice); } } function TodoItem({ todo }) { const dispatch = useDispatch(); const [checked, setChecked] = useState(false); const [updateModalOpen, setUpdateModalOpen] = useState(false); const [advice, setAdvice] = useState(''); useEffect(() => { if (todo.status === 'complete') { setChecked(true); } else { setChecked(false); } }, [todo.status, todo.title]); const handleDelete = () => { dispatch(deleteTodo(todo.id)); toast.success('Todo has been deleted.'); }; const handleUpdate = () => { setUpdateModalOpen(true); }; const handleCheck = () => { dispatch( updateTodo({ ...todo, status: checked ? 'incomplete' : 'complete', }) ); }; useEffect(() => { if (todo.status === 'help') { getAdvice({ text: todo.title, setAdvice }); } else { setAdvice(''); } }, [todo.status, todo.title, setAdvice]); useEffect(() => { if (todo.status === 'help') { getAdvice({ text: todo.title, setAdvice }); } else { setAdvice(''); } }, [todo.status, todo.title]); return ( <> <motion.div className={styles.item} variants={child}> <div className={styles.todoDetails}> <CheckButton checked={checked} handleCheck={handleCheck} /> <div className={styles.text}> <p className={getClasses([ styles.todoText, todo.status === 'complete' && styles['todoText--completed'], ])} > {todo.title} ({todo.tasktype}) </p> {todo.status === 'help' && advice && <p>{advice}</p>} <p className={styles.time}> {format(new Date(todo.time), 'p, MM/dd/yyyy')} </p> </div> </div> <div className={styles.todoActions}> <div className={styles.icon} onClick={handleDelete} onKeyDown={handleDelete} role="button" tabIndex={0} > <MdDelete /> </div> <div className={styles.icon} onClick={handleUpdate} onKeyDown={handleUpdate} role="button" tabIndex={0} > <MdEdit /> </div> </div> </motion.div> <ClassModal type="update" todo={todo} modalOpen={updateModalOpen} setModalOpen={setUpdateModalOpen} /> </> ); } export default TodoItem;