Skip to content
Snippets Groups Projects
Commit a8c22cd0 authored by OUKASSOU Anas's avatar OUKASSOU Anas
Browse files

Merge branch 'feature/manage-tasks' into 'main'

Feature/manage tasks

See merge request !16
parents 1c913339 b003f8e5
Branches
No related tags found
1 merge request!16Feature/manage tasks
......@@ -2,76 +2,85 @@ 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 handleSaveTask = () => {
const task = createTask()
saveTask(task)
const handleSave = () => {
saveTask(editedTask)
closeModal()
}
const handleInputChange = (e) => {
setTaskName(e.target.value);
const handleChange = (e) => {
const { name, value, type, checked } = e.target;
setEditedTask({
...editedTask,
[name]: type === 'checkbox' ? checked : value
});
};
return (
<div className="fixed inset-0 bg-black bg-opacity-25 flex items-center justify-center z-50">
<div
className="absolute top-0 left-0 right-0 bottom-0 flex justify-center items-center z-50"
style={{ pointerEvents: 'none' }}
className="bg-white rounded-lg shadow-xl p-6 w-full max-w-md mx-4"
>
<div
className="absolute inset-0 bg-gray-500 bg-opacity-50"
style={{ pointerEvents: 'none' }}
></div>
<div
className="relative bg-white p-6 rounded-lg shadow-lg w-1/3 z-10"
style={{ pointerEvents: 'auto' }}
<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"
>
<h2 className="text-xl mb-4">Add a New Task</h2>
<p className="mb-4">Enter the task details below:</p>
<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 rounded-md"
placeholder="Task Name"
value={taskName}
onChange={handleInputChange}
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}
/>
</div>
<div>
<DatePicker
showIcon
selected={dueDate}
onChange={(date) => setDueDate(date)}
<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="flex justify-between">
<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}
className="px-4 py-2 bg-red-500 text-white rounded-md"
>
Close
Cancel
</button>
<button
className="px-4 py-2 bg-blue-500 text-white rounded-md"
onClick={handleSaveTask}
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 Task
Save
</button>
</div>
</div>
......
......@@ -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 my-2 hover:shadow-md transition-shadow">
......@@ -39,8 +61,14 @@ export default function TaskItem({ task }) {
<h3 className={`text-base font-medium ${task.isCompleted ? 'text-gray-400 line-through' : 'text-gray-900'}`}>
{task.name}
</h3>
<p className={`text-sm mt-1 ${task.isCompleted ? 'text-gray-400' : 'text-gray-500'}`}>
Due: {formattedDate}
<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
......
......@@ -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 = {
......@@ -70,7 +79,7 @@ const Home = () => {
</div>
<Modal isOpen={isModalOpen} closeModal={closeModal} saveTask={saveTask} />
<Modal task={newTask()} isOpen={isModalOpen} closeModal={closeModal} saveTask={saveTask} />
</div>
);
};
......
......@@ -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,
......@@ -36,7 +46,7 @@ export default function Todolist() {
</div>
</div>
<Modal isOpen={isModalOpen} closeModal={closeModal} saveTask={saveTask}/>
<Modal task={newTask()} isOpen={isModalOpen} closeModal={closeModal} saveTask={saveTask}/>
</div>
)
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment