feat: Implement task addition modal with escape key handling and z-index adjustments

This commit is contained in:
Chop
2025-06-19 21:50:13 +02:00
parent aaa08a3504
commit 78b2474a9f

View File

@@ -12,6 +12,7 @@ export default function ProjectTasksSection({ projectId }) {
const [taskNotes, setTaskNotes] = useState({});
const [newNote, setNewNote] = useState({});
const [loadingNotes, setLoadingNotes] = useState({});
const [showAddTaskModal, setShowAddTaskModal] = useState(false);
useEffect(() => {
const fetchProjectTasks = async () => {
try {
@@ -46,6 +47,67 @@ export default function ProjectTasksSection({ projectId }) {
fetchProjectTasks();
}, [projectId]);
// Handle escape key to close modal
useEffect(() => {
const handleEscape = (e) => {
if (e.key === "Escape" && showAddTaskModal) {
setShowAddTaskModal(false);
}
};
document.addEventListener("keydown", handleEscape);
return () => document.removeEventListener("keydown", handleEscape);
}, [showAddTaskModal]);
// Prevent body scroll when modal is open and handle map z-index
useEffect(() => {
if (showAddTaskModal) {
// Prevent body scroll
document.body.style.overflow = "hidden";
// Find and temporarily lower z-index of leaflet containers
const leafletContainers = document.querySelectorAll(".leaflet-container");
leafletContainers.forEach((container) => {
container.style.zIndex = "1";
});
// Also handle navigation and other potential high z-index elements
const navElements = document.querySelectorAll("nav");
navElements.forEach((nav) => {
nav.style.position = "relative";
nav.style.zIndex = "1";
});
} else {
// Restore body scroll
document.body.style.overflow = "unset";
// Restore leaflet container z-index
const leafletContainers = document.querySelectorAll(".leaflet-container");
leafletContainers.forEach((container) => {
container.style.zIndex = "";
});
// Restore navigation z-index
const navElements = document.querySelectorAll("nav");
navElements.forEach((nav) => {
nav.style.position = "";
nav.style.zIndex = "";
});
}
// Cleanup function
return () => {
document.body.style.overflow = "unset";
const leafletContainers = document.querySelectorAll(".leaflet-container");
leafletContainers.forEach((container) => {
container.style.zIndex = "";
});
const navElements = document.querySelectorAll("nav");
navElements.forEach((nav) => {
nav.style.position = "";
nav.style.zIndex = "";
});
};
}, [showAddTaskModal]);
const refetchTasks = async () => {
try {
const res = await fetch(`/api/project-tasks?project_id=${projectId}`);
@@ -76,6 +138,7 @@ export default function ProjectTasksSection({ projectId }) {
};
const handleTaskAdded = () => {
refetchTasks(); // Refresh the list
setShowAddTaskModal(false); // Close the modal
};
const handleStatusChange = async (taskId, newStatus) => {
@@ -197,24 +260,79 @@ export default function ProjectTasksSection({ projectId }) {
<div className="space-y-6">
<div className="flex items-center justify-between">
<h2 className="text-xl font-semibold text-gray-900">Project Tasks</h2>
<div className="flex items-center gap-3">
<Badge variant="default" className="text-sm">
{projectTasks.length} {projectTasks.length === 1 ? "task" : "tasks"}
</Badge>
<Button
variant="primary"
size="sm"
onClick={() => setShowAddTaskModal(true)}
>
<svg
className="w-4 h-4 mr-2"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M12 4v16m8-8H4"
/>
</svg>
Add Task
</Button>
</div>
{/* Add New Task Card */}
<Card>
<CardHeader>
<h3 className="text-lg font-medium text-gray-900">Add New Task</h3>
</CardHeader>
<CardContent>
</div>{" "}
{/* Add Task Modal */}
{showAddTaskModal && (
<div
className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center"
style={{ zIndex: 99999 }}
onClick={(e) => {
if (e.target === e.currentTarget) {
setShowAddTaskModal(false);
}
}}
>
<div
className="bg-white rounded-lg shadow-xl max-w-2xl w-full mx-4 max-h-[90vh] overflow-y-auto"
style={{ zIndex: 100000 }}
>
<div className="flex items-center justify-between p-6 border-b">
<h3 className="text-lg font-semibold text-gray-900">
Add New Task
</h3>
<button
onClick={() => setShowAddTaskModal(false)}
className="text-gray-400 hover:text-gray-600 transition-colors"
>
<svg
className="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
</div>
<div className="p-6">
<ProjectTaskForm
projectId={projectId}
onTaskAdded={handleTaskAdded}
/>
</CardContent>
</Card>
</div>
</div>
</div>
)}
{/* Current Tasks */}
<Card>
<CardHeader>