GerardCB's picture
Deploy to Spaces (Final Clean)
4851501
"use client";
import dynamic from "next/dynamic";
import ChatPanel from "@/components/ChatPanel";
import { useState } from "react";
import type { MapLayer } from "@/components/MapViewer";
// Dynamic import for MapViewer (client-side only)
const MapViewer = dynamic(() => import("@/components/MapViewer"), {
ssr: false,
loading: () => <div className="w-full h-full bg-slate-100 flex items-center justify-center">Loading Map...</div>
});
export default function Home() {
const [layers, setLayers] = useState<MapLayer[]>([]);
const handleMapUpdate = (newGeojson: any) => {
// Unique ID generation
const id = Date.now().toString() + Math.random().toString(36).substr(2, 9);
// Extract metadata from backend response
const name = newGeojson.properties?.layer_name || `Layer ${layers.length + 1}`;
const recommendedStyle = newGeojson.properties?.style || {};
const choroplethConfig = newGeojson.properties?.choropleth || null;
// Construct new layer with defaults if style is missing
const newLayer: MapLayer = {
id,
name,
data: newGeojson,
visible: true,
style: {
color: recommendedStyle.color || "#6366f1",
fillColor: recommendedStyle.fillColor || recommendedStyle.color || "#6366f1",
fillOpacity: recommendedStyle.fillOpacity || 0.3,
weight: recommendedStyle.weight || 1
},
// Pass choropleth config if present
...(choroplethConfig && { choropleth: choroplethConfig }),
// Point marker config
pointMarker: newGeojson.properties?.pointMarker
};
// Add to layers (newest on top)
setLayers(prev => [...prev, newLayer]);
};
const handleLayerUpdate = (id: string, updates: Partial<MapLayer>) => {
setLayers(prev => prev.map(layer =>
layer.id === id ? { ...layer, ...updates } : layer
));
};
const handleLayerRemove = (id: string) => {
setLayers(prev => prev.filter(layer => layer.id !== id));
};
const handleLayerReorder = (fromIndex: number, toIndex: number) => {
setLayers(prev => {
const newLayers = [...prev];
const [movedLayer] = newLayers.splice(fromIndex, 1);
newLayers.splice(toIndex, 0, movedLayer);
return newLayers;
});
};
return (
<main className="flex h-screen w-full overflow-hidden">
{/* Left Panel: Chat (30-40% width) */}
<div className="w-[400px] md:w-[450px] lg:w-[30%] shrink-0 h-full relative z-10">
<ChatPanel onMapUpdate={handleMapUpdate} layers={layers} />
</div>
{/* Right Panel: Map (Remaining width) */}
<div className="flex-1 h-full relative">
<MapViewer
layers={layers}
onLayerUpdate={handleLayerUpdate}
onLayerRemove={handleLayerRemove}
onLayerReorder={handleLayerReorder}
/>
</div>
</main>
);
}