diff --git a/src/components/todolist/Modal.jsx b/src/components/todolist/Modal.jsx index 880bcc39091a2c30a600a3113f875df0c7eee7bf..6eb49fe2b3ccd7f28d8bc8114c1d22d160af9156 100644 --- a/src/components/todolist/Modal.jsx +++ b/src/components/todolist/Modal.jsx @@ -2,49 +2,88 @@ import { useState } from "react"; import DatePicker from "react-datepicker"; import "react-datepicker/dist/react-datepicker.css"; -export default function Modal({ isOpen, closeModal, saveTask }) { +export default function Modal({task, isOpen, closeModal, saveTask }) { if (!isOpen) return null; - const [taskName, setTaskName] = useState(""); - const [dueDate, setDueDate] = useState(new Date()); + const [editedTask, setEditedTask] = useState({...task}); - const createTask = () => { - return { - id: crypto.randomUUID(), - name: taskName, - isCompleted: false, - dueDate: dueDate - } + const handleSave = () => { + saveTask(editedTask) + closeModal() } - const handleSaveTask = () => { - const task = createTask(); - saveTask(task); - closeModal(); + const handleChange = (e) => { + const { name, value, type, checked } = e.target; + setEditedTask({ + ...editedTask, + [name]: type === 'checkbox' ? checked : value + }); }; - return ( - <div className="absolute top-0 left-0 right-0 bottom-0 flex justify-center items-center z-50"> - <div className="absolute inset-0 bg-gray-500 dark:bg-gray-900 bg-opacity-50"></div> - - <div className="relative bg-white dark:bg-gray-800 p-6 rounded-lg shadow-lg w-1/3 z-10"> - <h2 className="text-xl mb-4 dark:text-white">Add a New Task</h2> + return ( + <div className="fixed inset-0 bg-black bg-opacity-25 flex items-center justify-center z-50"> + <div + className="bg-white rounded-lg shadow-xl p-6 w-full max-w-md mx-4" + > + <div className="flex justify-between items-center mb-4"> + <h3 className="text-lg font-medium">Edit Task</h3> + <button + onClick={closeModal} + className="text-gray-400 hover:text-gray-500" + > + <svg className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> + <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" /> + </svg> + </button> + </div> + + <div className="space-y-4"> + <div> + <label htmlFor="name" className="block text-sm font-medium text-gray-700 mb-1"> + Task Name + </label> <input - type="text" - className="w-full p-2 mb-4 border border-gray-300 dark:border-gray-600 bg-gray-50 dark:bg-gray-700 text-gray-900 dark:text-white rounded-md" - placeholder="Task Name" - value={taskName} - onChange={(e) => setTaskName(e.target.value)} + id="name" + name="name" + className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500" + value={editedTask.name} + onChange={handleChange} /> - - <DatePicker className="dark:text-white" selected={dueDate} onChange={(date) => setDueDate(date)} /> - - <div className="flex justify-between mt-4"> - <button onClick={closeModal} className="px-4 py-2 bg-red-500 dark:bg-red-700 text-white rounded-md">Close</button> - <button onClick={handleSaveTask} className="px-4 py-2 bg-blue-500 dark:bg-blue-700 text-white rounded-md">Save Task</button> - </div> + </div> + + <div> + <label htmlFor="dueDate" className="block text-sm font-medium text-gray-700 mb-1"> + Due Date + </label> + <input + id="dueDate" + name="dueDate" + type="date" + className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500" + value={editedTask.dueDate} + onChange={handleChange} + /> + </div> + </div> + + <div className="mt-6 flex justify-end space-x-3"> + <button + type="button" + className="px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" + onClick={closeModal} + > + Cancel + </button> + <button + type="button" + className="px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" + onClick={handleSave} + > + Save + </button> </div> + </div> </div> - ); + ); } \ No newline at end of file diff --git a/src/components/todolist/TaskItem.jsx b/src/components/todolist/TaskItem.jsx index a6db15ea39080ecac9f53cfd9b1ff8fbb2cf855c..23ffc82034c7ae7c5f3e69128c52d565d35e4a29 100644 --- a/src/components/todolist/TaskItem.jsx +++ b/src/components/todolist/TaskItem.jsx @@ -22,6 +22,28 @@ export default function TaskItem({ task }) { ? new Date(task.dueDate).toLocaleDateString() : "No due date"; + const getDateTextColor = (task) => { + if (task.isCompleted) { + return 'text-gray-400'; + } + + const now = new Date(); + const due = new Date(task.dueDate); + + const diffTime = due - now; + const diffDays = diffTime / (1000 * 60 * 60 * 24); + + if (diffDays >= 0 && diffDays < 1) { + return 'text-orange-500'; + } + + if (now > due) { + return 'text-red-500'; + } + + return 'text-gray-500'; + }; + return ( <li> <div className="flex items-start p-4 border rounded-lg shadow-sm bg-white dark:bg-gray-700 dark:border-gray-600 my-2 hover:shadow-md transition-shadow"> @@ -39,9 +61,15 @@ export default function TaskItem({ task }) { <h3 className={`text-base font-medium ${task.isCompleted ? 'text-gray-400 line-through' : 'text-gray-900 dark:text-white'}`}> {task.name} </h3> - <p className={`text-sm mt-1 ${task.isCompleted ? 'text-gray-400' : 'text-gray-500 dark:text-gray-300'}`}> - Due: {formattedDate} - </p> + <p className={`text-sm mt-1 flex items-center gap-1 ${getDateTextColor(task)}`}> + <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"> + <rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect> + <line x1="16" y1="2" x2="16" y2="6"></line> + <line x1="8" y1="2" x2="8" y2="6"></line> + <line x1="3" y1="10" x2="21" y2="10"></line> + </svg> + {formattedDate} +</p> </div> <button onClick={() => onDelete(task.id)} diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx index 2bf73ea5e9a8ec2a90ee73d192b876d963f3b36d..8449f36752d6ccc63c51e4ca8666a1db86f94877 100644 --- a/src/pages/Home.jsx +++ b/src/pages/Home.jsx @@ -15,6 +15,15 @@ const Home = () => { const openModal = () => setIsModalOpen(true); const closeModal = () => setIsModalOpen(false); + const newTask = () => { + return { + id: crypto.randomUUID(), + name: "", + isCompleted: false, + dueDate: "" + } + } + // Fonction pour ajouter une nouvelle tâche const saveTask = (task) => { const newTask = { @@ -66,7 +75,7 @@ const Home = () => { </div> - <Modal isOpen={isModalOpen} closeModal={closeModal} saveTask={saveTask} /> + <Modal task={newTask()} isOpen={isModalOpen} closeModal={closeModal} saveTask={saveTask} /> </div> ); }; diff --git a/src/pages/Todolist.jsx b/src/pages/Todolist.jsx index 1ff6338ece5e2e124d61c800817e5d03c84aa427..c423a069d951099ffdcfedf07fb4bc9086995ba9 100644 --- a/src/pages/Todolist.jsx +++ b/src/pages/Todolist.jsx @@ -6,6 +6,16 @@ import { useTasks } from "@context/TasksContext"; export default function Todolist() { const { tasks, setTasks } = useTasks() + + const newTask = () => { + return { + id: crypto.randomUUID(), + name: "", + isCompleted: false, + dueDate: "" + } + } + const saveTask = (task) => { const newTask = { ...task, @@ -38,7 +48,7 @@ export default function Todolist() { </div> </div> - <Modal isOpen={isModalOpen} closeModal={closeModal} saveTask={saveTask} /> - </div> - ); + <Modal task={newTask()} isOpen={isModalOpen} closeModal={closeModal} saveTask={saveTask}/> + </div> + ) } \ No newline at end of file