diff --git a/src/components/Calendar.jsx b/src/components/Calendar.jsx index a1dfae4aa06d1d78f26aa6305d5bf6b4b95eea9b..a9cf3ced202d38aef3e4ac358c494152b88c95dc 100644 --- a/src/components/Calendar.jsx +++ b/src/components/Calendar.jsx @@ -3,9 +3,8 @@ import { format, addMonths, subMonths, startOfMonth, endOfMonth, eachDayOfInterv import { enUS } from 'date-fns/locale'; import { ChevronLeft, ChevronRight } from 'lucide-react'; -const Calendar = () => { +const Calendar = ({ selectedDate, setSelectedDate }) => { const [currentDate, setCurrentDate] = useState(new Date()); - const [selectedDate, setSelectedDate] = useState(new Date()); const nextMonth = () => setCurrentDate(addMonths(currentDate, 1)); const prevMonth = () => setCurrentDate(subMonths(currentDate, 1)); @@ -15,7 +14,7 @@ const Calendar = () => { end: endOfMonth(currentDate), }); - const startDay = getDay(startOfMonth(currentDate)); + const startDay = getDay(startOfMonth(currentDate)); return ( <div className="space-y-6"> @@ -61,15 +60,15 @@ const Calendar = () => { : 'text-violet-800 dark:text-gray-300 hover:bg-violet-100 dark:hover:bg-gray-700' } `} - > - {format(day, 'd')} - </button> - ); - })} + > + {format(day, 'd')} + </button> + ); + })} + </div> </div> </div> - </div> ); }; -export default Calendar; \ No newline at end of file +export default Calendar; diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx index dbde8467cb8e4e6aa76891c8f7b50871a78a4e48..88094212419ca5638145c23fcc8c8e893bcd1f68 100644 --- a/src/components/Navbar.jsx +++ b/src/components/Navbar.jsx @@ -9,24 +9,24 @@ const Navbar = () => { const { theme, toggleTheme } = useTheme(); useEffect(() => { - // Écouter les changements sur `localStorage` + const handleStorageChange = () => { setIsAuthenticated(!!localStorage.getItem("user")); }; - // Ajouter un écouteur d'événement sur `storage` + window.addEventListener("storage", handleStorageChange); return () => { - // Nettoyer l'écouteur quand le composant est démonté + window.removeEventListener("storage", handleStorageChange); }; }, []); const handleLogout = () => { - localStorage.removeItem("user"); // Supprimer l'utilisateur + localStorage.removeItem("user"); setIsAuthenticated(false); - navigate("/signin"); // Rediriger vers la page de connexion + navigate("/signin"); }; return ( @@ -61,7 +61,7 @@ const Navbar = () => { <div className="flex items-center gap-2"> {isAuthenticated ? ( - // Bouton Logout si l'utilisateur est connecté + <button onClick={handleLogout} className="bg-red-500 text-white hover:bg-red-600 px-4 py-2 rounded-md text-sm font-medium" @@ -69,7 +69,7 @@ const Navbar = () => { Logout </button> ) : ( - // Boutons Login & Signup si l'utilisateur N'EST PAS connecté + <> <Link to="/signin" diff --git a/src/components/todolist/TaskItem.jsx b/src/components/todolist/TaskItem.jsx index 1305331c046b5a087ae6801671b5c404de49356a..d6fc1df6fc94b4676a97897544814ce990eefa2f 100644 --- a/src/components/todolist/TaskItem.jsx +++ b/src/components/todolist/TaskItem.jsx @@ -8,7 +8,7 @@ export default function TaskItem({ task }) { const onChange = (event) => { const nextTasks = [...tasks] const nextTask = nextTasks.find( - a => a.id === task.id + a => a.id === task.id ) nextTask["isCompleted"] = event.target.checked setTasks(nextTasks) @@ -16,28 +16,40 @@ export default function TaskItem({ task }) { const onDelete = (id) => { setTasks(tasks.filter(task => task.id !== id)); - }; + }; + + const formattedDate = task.dueDate + ? new Date(task.dueDate).toLocaleDateString() + : "No due date"; return ( - <li className="flex items-center space-x-4"> - <input - type="checkbox" - id={task.id} - checked={task.isCompleted} - onChange={onChange} - className="w-5 h-5 text-blue-500 border-gray-300 rounded focus:ring-blue-500" - /> - <label - htmlFor={task.id} - className={`text-lg ${task.isCompleted ? 'line-through text-gray-400' : ''}`}> + <li> + <div className="flex items-start p-4 border rounded-lg shadow-sm bg-white my-2 hover:shadow-md transition-shadow"> + <div className="flex-shrink-0 pt-1"> + <input + id={task.id} + type="checkbox" + className="h-5 w-5 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" + checked={task.isCompleted} + onChange={onChange} + /> + </div> + + <div className="ml-3 flex-1"> + <h3 className={`text-base font-medium ${task.isCompleted ? 'text-gray-400 line-through' : 'text-gray-900'}`}> {task.name} - </label> + </h3> + <p className={`text-sm mt-1 ${task.isCompleted ? 'text-gray-400' : 'text-gray-500'}`}> + Due: {formattedDate} + </p> + </div> <button onClick={() => onDelete(task.id)} className="ml-auto p-1 rounded-full hover:bg-gray-200 focus:outline-none" - > - <TrashIcon className="w-5 h-5 text-red-500 hover:text-red-700" /> + > + <TrashIcon className="w-5 h-5 text-red-500 hover:text-red-700" /> </button> + </div> </li> ) } \ No newline at end of file diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx index e71f17a398fb7e28bf88696052c4d105af7960e4..09415fdbaa794cbebc855cf8f82e82e943ce14f4 100644 --- a/src/pages/Home.jsx +++ b/src/pages/Home.jsx @@ -1,20 +1,57 @@ -import React from "react"; +import React, { useState } from "react"; import TaskStats from "@components/dashboard/TaskStats"; import TasksStatPercent from "@components/dashboard/TasksStatPercent.jsx"; -import { useNavigate } from "react-router-dom"; +import { useTasks } from "@context/TasksContext"; import Calendar from "@components/Calendar"; +import TaskList from "@components/todolist/TaskList"; +import AddTaskButton from "@components/todolist/AddTaskButton"; +import Modal from "@components/todolist/Modal"; + const Home = () => { - const navigate = useNavigate(); - return ( - <div> - <div className="p-6 bg-gray-50 dark:bg-gray-900"> - <TaskStats /> - </div> - <div className="min-h-screen bg-gray-100 dark:bg-gray-800 p-8"> - <div className="grid grid-cols-2 gap-6"> + const { tasks, setTasks } = useTasks(); + const [selectedDate, setSelectedDate] = useState(new Date()); + const [isModalOpen, setIsModalOpen] = useState(false); - <div className="bg-white dark:bg-gray-700 rounded-lg shadow-md p-6 min-h-[300px]"> - </div> + const openModal = () => setIsModalOpen(true); + const closeModal = () => setIsModalOpen(false); + + // Fonction pour ajouter une nouvelle tâche + const saveTask = (task) => { + const newTask = { + ...task, + dueDate: task.dueDate || selectedDate.toISOString().split("T")[0], // Ajouter une dueDate par défaut + }; + setTasks([...tasks, newTask]); + }; + + // Filtrer les tâches en fonction de leur dueDate + const filteredTasks = tasks.filter(task => { + if (!task.dueDate) return false; // Vérifie si une tâche a bien une date + const taskDate = new Date(task.dueDate); // Convertir en objet Date + return taskDate.toDateString() === selectedDate.toDateString(); // Comparer avec la date sélectionnée + }); + + return ( + <div> + <div className="p-6 bg-gray-50 dark:bg-gray-900"> + <TaskStats /> + </div> + <div className="min-h-screen bg-gray-100 dark:bg-gray-800 p-8"> + <div className="grid grid-cols-2 gap-6"> + + + <div className="bg-white dark:bg-gray-700 rounded-lg shadow-md p-6 min-h-[300px]"> + <h3 className="text-lg font-semibold mb-4"> + Tasks for {selectedDate.toDateString()} + </h3> + + <AddTaskButton onClick={openModal} /> + {filteredTasks.length > 0 ? ( + <TaskList tasks={filteredTasks} /> + ) : ( + <p className="text-gray-500 mt-4">No tasks for this day</p> + )} + </div> <div className="bg-white dark:bg-gray-700 rounded-lg shadow-md p-6 min-h-[300px]"> <Calendar /> @@ -23,14 +60,16 @@ const Home = () => { <div className="bg-white dark:bg-gray-700 rounded-lg shadow-md p-6 min-h-[300px]"> </div> - <div className="bg-white dark:bg-gray-700 rounded-lg shadow-md p-6 min-h-[300px]"> - <TasksStatPercent/> - </div> + <div className="bg-white dark:bg-gray-700 rounded-lg shadow-md p-6 min-h-[300px]"> + <TasksStatPercent /> + </div> + </div> + </div> + - </div> - </div> - </div> - ); + <Modal isOpen={isModalOpen} closeModal={closeModal} saveTask={saveTask} /> + </div> + ); }; export default Home; \ No newline at end of file diff --git a/src/pages/Todolist.jsx b/src/pages/Todolist.jsx index 343f0201df39cf4879c173d0f4b5d8860a3cdfbb..1a648e75ca731d5f9830e9ac092bada9106b6082 100644 --- a/src/pages/Todolist.jsx +++ b/src/pages/Todolist.jsx @@ -7,8 +7,13 @@ import { useTasks } from "@context/TasksContext"; export default function Todolist() { const { tasks, setTasks } = useTasks() const saveTask = (task) => { - setTasks([...tasks, task]) - } + const newTask = { + ...task, + dueDate: task.dueDate || new Date().toISOString().split("T")[0], + }; + setTasks([...tasks, newTask]); + }; + const [isModalOpen, setIsModalOpen] = useState(false); const openModal = () => setIsModalOpen(true);