fix(geoportal): load MapLibre CSS via CDN link injection + fullscreen layout

- Static CSS import doesn't work with next/dynamic + standalone output.
  Now injects a <link> tag to unpkg CDN at module load time (bulletproof).
- Geoportal is now fullscreen: map fills entire viewport below the header,
  no duplicate title/description, negative margins bleed to edges.
- Removed page-level CSS imports (no longer needed).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
AI Assistant
2026-03-23 17:01:48 +02:00
parent 3346ec709d
commit 437d734df6
4 changed files with 58 additions and 75 deletions
@@ -2,7 +2,6 @@
import { useState, useRef, useCallback } from "react";
import dynamic from "next/dynamic";
import { Globe } from "lucide-react";
import { LayerPanel, getDefaultVisibility } from "./layer-panel";
import { BasemapSwitcher } from "./basemap-switcher";
import { SearchBar } from "./search-bar";
@@ -94,66 +93,54 @@ export function GeoportalModule() {
}, []);
return (
<div className="space-y-4">
{/* Header */}
<div className="flex items-center gap-3">
<Globe className="h-6 w-6 text-muted-foreground" />
<div>
<h2 className="text-lg font-semibold">Geoportal</h2>
<p className="text-sm text-muted-foreground">
Harta interactiva cu parcele cadastrale, cladiri si limite UAT
</p>
</div>
</div>
<div className="relative -mx-4 -mt-4 sm:-mx-6 sm:-mt-6 lg:-mx-8 lg:-mt-8"
style={{ height: "calc(100vh - 3.5rem)" }}>
{/* Full-bleed map */}
<MapViewer
ref={mapHandleRef}
className="h-full w-full"
basemap={basemap}
selectionMode={selectionMode}
onFeatureClick={handleFeatureClick}
onSelectionChange={handleSelectionChange}
layerVisibility={layerVisibility}
center={flyTarget?.center}
zoom={flyTarget?.zoom}
/>
{/* Map container */}
<div className="relative h-[calc(100vh-12rem)] min-h-[500px] rounded-lg border overflow-hidden">
<MapViewer
ref={mapHandleRef}
className="h-full w-full"
basemap={basemap}
selectionMode={selectionMode}
onFeatureClick={handleFeatureClick}
onSelectionChange={handleSelectionChange}
layerVisibility={layerVisibility}
center={flyTarget?.center}
zoom={flyTarget?.zoom}
{/* Top-left controls: search + layers */}
<div className="absolute top-3 left-3 z-10 flex flex-col gap-2 max-w-xs">
<SearchBar onResultSelect={handleSearchResult} />
<LayerPanel
visibility={layerVisibility}
onVisibilityChange={handleVisibilityChange}
/>
{/* Top-left controls: search + layers */}
<div className="absolute top-3 left-3 z-10 flex flex-col gap-2 max-w-xs">
<SearchBar onResultSelect={handleSearchResult} />
<LayerPanel
visibility={layerVisibility}
onVisibilityChange={handleVisibilityChange}
/>
</div>
{/* Top-right: basemap switcher */}
<div className="absolute top-3 right-14 z-10">
<BasemapSwitcher value={basemap} onChange={setBasemap} />
</div>
{/* Bottom-left: selection toolbar */}
<div className="absolute bottom-8 left-3 z-10">
<SelectionToolbar
selectedFeatures={selectedFeatures}
selectionMode={selectionMode}
onToggleSelectionMode={handleToggleSelectionMode}
onClearSelection={handleClearSelection}
/>
</div>
{/* Right side: feature info panel */}
{clickedFeature && !selectionMode && (
<div className="absolute top-3 right-3 z-10 mt-12">
<FeatureInfoPanel
feature={clickedFeature}
onClose={() => setClickedFeature(null)}
/>
</div>
)}
</div>
{/* Top-right: basemap switcher (offset to avoid nav controls) */}
<div className="absolute top-3 right-14 z-10">
<BasemapSwitcher value={basemap} onChange={setBasemap} />
</div>
{/* Bottom-left: selection toolbar */}
<div className="absolute bottom-8 left-3 z-10">
<SelectionToolbar
selectedFeatures={selectedFeatures}
selectionMode={selectionMode}
onToggleSelectionMode={handleToggleSelectionMode}
onClearSelection={handleClearSelection}
/>
</div>
{/* Right side: feature info panel */}
{clickedFeature && !selectionMode && (
<div className="absolute top-16 right-3 z-10">
<FeatureInfoPanel
feature={clickedFeature}
onClose={() => setClickedFeature(null)}
/>
</div>
)}
</div>
);
}