Skip to content
Snippets Groups Projects
Commit 8bd62ba6 authored by Kevin Portable's avatar Kevin Portable
Browse files

Merge remote-tracking branch 'origin/main' into Light/DarkMode-Feature

parents 68871889 1c913339
No related branches found
No related tags found
No related merge requests found
......@@ -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));
......
......@@ -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"
......
......@@ -18,26 +18,38 @@ export default function TaskItem({ task }) {
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">
<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
type="checkbox"
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}
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' : ''}`}>
</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" />
</button>
</div>
</li>
)
}
\ No newline at end of file
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();
const { tasks, setTasks } = useTasks();
const [selectedDate, setSelectedDate] = useState(new Date());
const [isModalOpen, setIsModalOpen] = useState(false);
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">
......@@ -13,7 +39,18 @@ const Home = () => {
<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]">
......@@ -26,9 +63,11 @@ const Home = () => {
<div className="bg-white dark:bg-gray-700 rounded-lg shadow-md p-6 min-h-[300px]">
<TasksStatPercent />
</div>
</div>
</div>
<Modal isOpen={isModalOpen} closeModal={closeModal} saveTask={saveTask} />
</div>
);
};
......
......@@ -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);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment