From a8f52f6d281865c2a41a5d004b1e722b11ea691d Mon Sep 17 00:00:00 2001
From: Chop <28534054+RChopin@users.noreply.github.com>
Date: Thu, 19 Jun 2025 19:17:22 +0200
Subject: [PATCH] feat: Implement full-screen map view and enhance project
navigation
---
src/app/globals.css | 36 ++++
src/app/projects/map/page.js | 359 +++++++++++++++++++++++++++++++++++
src/app/projects/page.js | 56 ++++--
3 files changed, 433 insertions(+), 18 deletions(-)
create mode 100644 src/app/projects/map/page.js
diff --git a/src/app/globals.css b/src/app/globals.css
index 7edbe08..cfa705c 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -58,3 +58,39 @@ body {
.animate-fade-in {
animation: fadeIn 0.3s ease-out;
}
+
+/* Full-screen map styles */
+.map-fullscreen-container {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ overflow: hidden;
+ z-index: 50;
+}
+
+/* Ensure map takes full container */
+.leaflet-container {
+ height: 100% !important;
+ width: 100% !important;
+}
+
+/* Override any margin/padding that might cause scrollbars */
+.map-page {
+ margin: 0 !important;
+ padding: 0 !important;
+ overflow: hidden !important;
+}
+
+/* Ensure floating panels are above map controls */
+.map-floating-panel {
+ z-index: 1000 !important;
+ backdrop-filter: blur(8px);
+ -webkit-backdrop-filter: blur(8px);
+}
+
+/* Map controls positioning */
+.leaflet-control-container .leaflet-top.leaflet-right {
+ top: 80px !important; /* Account for floating header */
+}
diff --git a/src/app/projects/map/page.js b/src/app/projects/map/page.js
new file mode 100644
index 0000000..1d0491a
--- /dev/null
+++ b/src/app/projects/map/page.js
@@ -0,0 +1,359 @@
+"use client";
+
+import React, { useEffect, useState } from "react";
+import Link from "next/link";
+import dynamic from "next/dynamic";
+import Button from "@/components/ui/Button";
+
+// Dynamically import the map component to avoid SSR issues
+const DynamicMap = dynamic(() => import("@/components/ui/LeafletMap"), {
+ ssr: false,
+ loading: () => (
+
+ Loading map...
+
+ ),
+});
+
+export default function ProjectsMapPage() {
+ const [projects, setProjects] = useState([]);
+ const [loading, setLoading] = useState(true);
+ const [mapCenter, setMapCenter] = useState([50.0614, 19.9366]); // Default to Krakow, Poland
+ // Hide navigation and ensure full-screen layout
+ useEffect(() => {
+ // Hide navigation bar for full-screen experience
+ const nav = document.querySelector("nav");
+ if (nav) {
+ nav.style.display = "none";
+ }
+
+ // Prevent scrolling on body
+ document.body.style.overflow = "hidden";
+ document.documentElement.style.overflow = "hidden";
+
+ // Cleanup when leaving page
+ return () => {
+ if (nav) {
+ nav.style.display = "";
+ }
+ document.body.style.overflow = "";
+ document.documentElement.style.overflow = "";
+ };
+ }, []);
+
+ useEffect(() => {
+ fetch("/api/projects")
+ .then((res) => res.json())
+ .then((data) => {
+ setProjects(data);
+
+ // Calculate center based on projects with coordinates
+ const projectsWithCoords = data.filter((p) => p.coordinates);
+ if (projectsWithCoords.length > 0) {
+ const avgLat =
+ projectsWithCoords.reduce((sum, p) => {
+ const [lat] = p.coordinates
+ .split(",")
+ .map((coord) => parseFloat(coord.trim()));
+ return sum + lat;
+ }, 0) / projectsWithCoords.length;
+
+ const avgLng =
+ projectsWithCoords.reduce((sum, p) => {
+ const [, lng] = p.coordinates
+ .split(",")
+ .map((coord) => parseFloat(coord.trim()));
+ return sum + lng;
+ }, 0) / projectsWithCoords.length;
+
+ setMapCenter([avgLat, avgLng]);
+ }
+
+ setLoading(false);
+ })
+ .catch((error) => {
+ console.error("Error fetching projects:", error);
+ setLoading(false);
+ });
+ }, []);
+
+ // Convert projects to map markers
+ const markers = projects
+ .filter((project) => project.coordinates)
+ .map((project) => {
+ const [lat, lng] = project.coordinates
+ .split(",")
+ .map((coord) => parseFloat(coord.trim()));
+
+ if (isNaN(lat) || isNaN(lng)) {
+ return null;
+ }
+ return {
+ position: [lat, lng],
+ popup: (
+
+
+
+ {project.project_name}
+
+ {project.project_number && (
+
+ {project.project_number}
+
+ )}
+
+
+
+ {project.address && (
+
+
+
+
+ {project.address}
+
+ {project.city && (
+ , {project.city}
+ )}
+
+
+ )}
+
+
+ {project.wp && (
+
+ WP:{" "}
+ {project.wp}
+
+ )}
+ {project.plot && (
+
+ Plot:{" "}
+ {project.plot}
+
+ )}
+
+
+ {project.project_status && (
+
+ Status:
+
+ {project.project_status === "registered"
+ ? "Zarejestr."
+ : project.project_status === "in_progress_design"
+ ? "W real. (P)"
+ : project.project_status === "in_progress_construction"
+ ? "W real. (R)"
+ : project.project_status === "fulfilled"
+ ? "Zakończony"
+ : project.project_status}
+
+
+ )}
+
+
+
+
+
+
+
+
+ ),
+ };
+ })
+ .filter((marker) => marker !== null);
+ if (loading) {
+ return (
+
+
+
+
Loading projects map...
+
+ Preparing your full-screen map experience
+
+
+
+ );
+ }
+ return (
+
+ {/* Floating Header with Controls */}
+
+
+
+
+ Projects Map
+
+
+ {markers.length} of {projects.length} projects with coordinates
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Stats Panel - Bottom Left */}
+ {markers.length > 0 && (
+
+
+
+
+
+ {markers.length} projects shown
+
+
+ {projects.length > markers.length && (
+
+
+
+ {projects.length - markers.length} missing coordinates
+
+
+ )}
+
+
+ )}
+
+ {/* Help Panel - Bottom Right */}
+
+
+ Click markers for details • Use 📚 to switch layers
+
+
+
+ {/* Full Screen Map */}
+ {markers.length === 0 ? (
+
+
+
+
+ No projects with coordinates
+
+
+ Projects need coordinates to appear on the map. Add coordinates
+ when creating or editing projects.
+
+
+
+
+
+
+
+
+
+
+
+ ) : (
+
+
+
+ )}
+
+ );
+}
diff --git a/src/app/projects/page.js b/src/app/projects/page.js
index e592696..9a7be3e 100644
--- a/src/app/projects/page.js
+++ b/src/app/projects/page.js
@@ -61,24 +61,44 @@ export default function ProjectListPage() {
return (
-
-
-
+
+
+
+
+
+
+
+