Compare commits
3 commits
f051581171
...
3ab47584bb
| Author | SHA1 | Date | |
|---|---|---|---|
| 3ab47584bb | |||
| 8a36517f08 | |||
| a25000e039 |
3 changed files with 42 additions and 71 deletions
|
|
@ -19,76 +19,76 @@ const baseConfigs: Omit<LayerConfig, 'getUrl'>[] = [
|
||||||
radius: 1,
|
radius: 1,
|
||||||
topic: 'Parcels',
|
topic: 'Parcels',
|
||||||
style: new Style({
|
style: new Style({
|
||||||
stroke: new Stroke({ color: 'green', width: 1.5 }),
|
stroke: new Stroke({ color: '#00D9FF', width: 5.5 }),
|
||||||
fill: new Fill({ color: 'rgba(0, 255, 0, 0.1)' }),
|
fill: new Fill({ color: 'rgba(0, 217, 255, 0.1)' }),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
radius: 100,
|
radius: 100,
|
||||||
topic: 'Sewer_Main_SD',
|
topic: 'Sewer_Main_SD',
|
||||||
style: new Style({
|
style: new Style({
|
||||||
stroke: new Stroke({ color: 'purple', width: 2 }),
|
stroke: new Stroke({ color: '#FF00FF', width: 2 }),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
radius: 50,
|
radius: 50,
|
||||||
topic: 'Zoning_Base_SD',
|
topic: 'Zoning_Base_SD',
|
||||||
style: new Style({
|
style: new Style({
|
||||||
stroke: new Stroke({ color: 'red', width: 1 }),
|
stroke: new Stroke({ color: '#FF3333', width: 1 }),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
radius: 50,
|
radius: 50,
|
||||||
topic: 'Water_Main_SD',
|
topic: 'Water_Main_SD',
|
||||||
style: new Style({
|
style: new Style({
|
||||||
stroke: new Stroke({ color: 'blue', width: 5 }),
|
stroke: new Stroke({ color: '#0066FF', width: 5 }),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
radius: 1000,
|
radius: 1000,
|
||||||
topic: 'Sustainable_Development_Areas',
|
topic: 'Sustainable_Development_Areas',
|
||||||
style: new Style({
|
style: new Style({
|
||||||
stroke: new Stroke({ color: 'green', width: 3 }),
|
stroke: new Stroke({ color: '#00FF66', width: 3 }),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
radius: 1000,
|
radius: 1000,
|
||||||
topic: 'Housing_Solution_Areas',
|
topic: 'Housing_Solution_Areas',
|
||||||
style: new Style({
|
style: new Style({
|
||||||
stroke: new Stroke({ color: 'black', width: 2.5 }),
|
stroke: new Stroke({ color: '#FFD700', width: 2.5 }),
|
||||||
fill: new Fill({ color: 'rgba(255, 200, 0, 0.1)' }),
|
fill: new Fill({ color: 'rgba(255, 215, 0, 0.1)' }),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
radius: 100000,
|
radius: 100000,
|
||||||
topic: 'Promise_Zones_SD',
|
topic: 'Promise_Zones_SD',
|
||||||
style: new Style({
|
style: new Style({
|
||||||
stroke: new Stroke({ color: 'black', width: 2.5 }),
|
stroke: new Stroke({ color: '#9933FF', width: 2.5 }),
|
||||||
fill: new Fill({ color: 'rgba(116, 3, 255, 0.1)' }),
|
fill: new Fill({ color: 'rgba(153, 51, 255, 0.1)' }),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
radius: 100000,
|
radius: 100000,
|
||||||
topic: 'MHPA_SD',
|
topic: 'MHPA_SD',
|
||||||
style: new Style({
|
style: new Style({
|
||||||
stroke: new Stroke({ color: 'orange', width: 2.5 }),
|
stroke: new Stroke({ color: '#FF6B6B', width: 2.5 }),
|
||||||
fill: new Fill({ color: 'rgba(116, 3, 255, 0.1)' }),
|
fill: new Fill({ color: 'rgba(255, 107, 107, 0.1)' }),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
radius: 100000,
|
radius: 100000,
|
||||||
topic: 'Coastal_Zones',
|
topic: 'Coastal_Zones',
|
||||||
style: new Style({
|
style: new Style({
|
||||||
stroke: new Stroke({ color: 'skin', width: 2.5 }),
|
stroke: new Stroke({ color: '#FF9966', width: 2.5 }),
|
||||||
fill: new Fill({ color: 'rgba(116, 3, 255, 0.1)' }),
|
fill: new Fill({ color: 'rgba(255, 153, 102, 0.1)' }),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
radius: 100000,
|
radius: 100000,
|
||||||
topic: 'Community_Plan_Implementation_Overlay_Zone_SD',
|
topic: 'Community_Plan_Implementation_Overlay_Zone_SD',
|
||||||
style: new Style({
|
style: new Style({
|
||||||
stroke: new Stroke({ color: 'darkblue', width: 2.5 }),
|
stroke: new Stroke({ color: '#4169E1', width: 2.5 }),
|
||||||
fill: new Fill({ color: 'rgba(116, 3, 255, 0.1)' }),
|
fill: new Fill({ color: 'rgba(65, 105, 225, 0.1)' }),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
@ -96,8 +96,8 @@ const baseConfigs: Omit<LayerConfig, 'getUrl'>[] = [
|
||||||
radius: 100000,
|
radius: 100000,
|
||||||
topic: 'Airport_Influence_Area',
|
topic: 'Airport_Influence_Area',
|
||||||
style: new Style({
|
style: new Style({
|
||||||
stroke: new Stroke({ color: 'darkyellow', width: 2.5 }),
|
stroke: new Stroke({ color: '#FFBB00', width: 2.5 }),
|
||||||
fill: new Fill({ color: 'rgba(116, 3, 255, 0.1)' }),
|
fill: new Fill({ color: 'rgba(255, 187, 0, 0.1)' }),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
@ -105,8 +105,8 @@ const baseConfigs: Omit<LayerConfig, 'getUrl'>[] = [
|
||||||
radius: 100000,
|
radius: 100000,
|
||||||
topic: 'Historic_Districts_SD',
|
topic: 'Historic_Districts_SD',
|
||||||
style: new Style({
|
style: new Style({
|
||||||
stroke: new Stroke({ color: 'white', width: 2.5 }),
|
stroke: new Stroke({ color: '#C0C0C0', width: 2.5 }),
|
||||||
fill: new Fill({ color: 'rgba(116, 3, 255, 0.1)' }),
|
fill: new Fill({ color: 'rgba(192, 192, 192, 0.1)' }),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
@ -114,8 +114,8 @@ const baseConfigs: Omit<LayerConfig, 'getUrl'>[] = [
|
||||||
radius: 100000,
|
radius: 100000,
|
||||||
topic: 'HRB_Designated_Resources_SD',
|
topic: 'HRB_Designated_Resources_SD',
|
||||||
style: new Style({
|
style: new Style({
|
||||||
stroke: new Stroke({ color: 'darkgreen', width: 2.5 }),
|
stroke: new Stroke({ color: '#00CC66', width: 2.5 }),
|
||||||
fill: new Fill({ color: 'rgba(116, 3, 255, 0.1)' }),
|
fill: new Fill({ color: 'rgba(0, 204, 102, 0.1)' }),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
@ -123,8 +123,8 @@ const baseConfigs: Omit<LayerConfig, 'getUrl'>[] = [
|
||||||
radius: 100000,
|
radius: 100000,
|
||||||
topic: 'Fire_Hazard_Severity_Zones_SD',
|
topic: 'Fire_Hazard_Severity_Zones_SD',
|
||||||
style: new Style({
|
style: new Style({
|
||||||
stroke: new Stroke({ color: 'yellow', width: 1.5 }),
|
stroke: new Stroke({ color: '#FF6600', width: 1.5 }),
|
||||||
fill: new Fill({ color: 'rgba(116, 3, 255, 0.1)' }),
|
fill: new Fill({ color: 'rgba(255, 102, 0, 0.1)' }),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
// src/Methods/addMarker.ts
|
|
||||||
|
|
||||||
import Feature from 'ol/Feature';
|
import Feature from 'ol/Feature';
|
||||||
import Point from 'ol/geom/Point';
|
import Point from 'ol/geom/Point';
|
||||||
|
|
@ -9,16 +8,11 @@ import Icon from 'ol/style/Icon';
|
||||||
import { Map } from 'ol';
|
import { Map } from 'ol';
|
||||||
import { Coordinate } from 'ol/coordinate';
|
import { Coordinate } from 'ol/coordinate';
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a custom icon marker to the map at a given coordinate,
|
|
||||||
* replacing the previous marker layer if one exists.
|
|
||||||
*/
|
|
||||||
export const addMarker = (
|
export const addMarker = (
|
||||||
coords: Coordinate,
|
coords: Coordinate,
|
||||||
map: Map,
|
map: Map,
|
||||||
existingMarkerLayer: VectorLayer | null
|
existingMarkerLayer: VectorLayer | null
|
||||||
): VectorLayer => {
|
): VectorLayer => {
|
||||||
// Create feature for the marker
|
|
||||||
const markerFeature = new Feature({
|
const markerFeature = new Feature({
|
||||||
geometry: new Point(coords),
|
geometry: new Point(coords),
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -13,16 +13,15 @@ import gsap from 'gsap';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { easeOut } from 'ol/easing';
|
import { easeOut } from 'ol/easing';
|
||||||
|
|
||||||
// --- THEME CONFIGURATION ---
|
|
||||||
const themes = {
|
const themes = {
|
||||||
dark: {
|
dark: {
|
||||||
bg: '#050505',
|
bg: '#050505',
|
||||||
glass: 'rgba(20, 20, 20, 0.75)', // Slightly darker for better contrast
|
glass: 'rgba(20, 20, 20, 0.75)',
|
||||||
border: 'rgba(255, 255, 255, 0.15)', // Stronger border
|
border: 'rgba(255, 255, 255, 0.15)',
|
||||||
textMain: '#ffffff',
|
textMain: '#ffffff',
|
||||||
textMuted: '#AAAAAA',
|
textMuted: '#AAAAAA',
|
||||||
iconColor: '#ffffff',
|
iconColor: '#ffffff',
|
||||||
shadow: '0 4px 20px rgba(0,0,0,0.4)', // Strong shadow
|
shadow: '0 4px 20px rgba(0,0,0,0.4)',
|
||||||
switchTrackActive: 'rgba(255,255,255,0.2)',
|
switchTrackActive: 'rgba(255,255,255,0.2)',
|
||||||
switchTrackInactive: 'rgba(255,255,255,0.05)',
|
switchTrackInactive: 'rgba(255,255,255,0.05)',
|
||||||
switchKnobActive: '#fff',
|
switchKnobActive: '#fff',
|
||||||
|
|
@ -31,7 +30,7 @@ const themes = {
|
||||||
},
|
},
|
||||||
light: {
|
light: {
|
||||||
bg: '#F4F4F5',
|
bg: '#F4F4F5',
|
||||||
glass: 'rgba(255, 255, 255, 0.90)', // More opaque for visibility
|
glass: 'rgba(255, 255, 255, 0.90)',
|
||||||
border: 'rgba(0, 0, 0, 0.1)',
|
border: 'rgba(0, 0, 0, 0.1)',
|
||||||
textMain: '#18181B',
|
textMain: '#18181B',
|
||||||
textMuted: '#52525B',
|
textMuted: '#52525B',
|
||||||
|
|
@ -45,7 +44,6 @@ const themes = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- SCROLLBAR CSS ---
|
|
||||||
const scrollbarStyles = `
|
const scrollbarStyles = `
|
||||||
.custom-scrollbar::-webkit-scrollbar { width: 4px; }
|
.custom-scrollbar::-webkit-scrollbar { width: 4px; }
|
||||||
.custom-scrollbar::-webkit-scrollbar-track { background: rgba(128, 128, 128, 0.1); border-radius: 4px; }
|
.custom-scrollbar::-webkit-scrollbar-track { background: rgba(128, 128, 128, 0.1); border-radius: 4px; }
|
||||||
|
|
@ -53,18 +51,14 @@ const scrollbarStyles = `
|
||||||
.custom-scrollbar::-webkit-scrollbar-thumb:hover { background: rgba(128, 128, 128, 0.5); }
|
.custom-scrollbar::-webkit-scrollbar-thumb:hover { background: rgba(128, 128, 128, 0.5); }
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// --- HELPER: Extract Color ---
|
|
||||||
const extractColorFromStyle = (style: any): string => {
|
const extractColorFromStyle = (style: any): string => {
|
||||||
let color: any = '#888888';
|
if (style.getStroke() && style.getStroke().getColor()) {
|
||||||
if (style.getStroke() && style.getStroke().getColor()) color = style.getStroke().getColor();
|
return style.getStroke().getColor();
|
||||||
else if (style.getFill() && style.getFill().getColor()) color = style.getFill().getColor();
|
}
|
||||||
|
if (style.getFill() && style.getFill().getColor()) {
|
||||||
const colorMap: Record<string, string> = {
|
return style.getFill().getColor();
|
||||||
'skin': '#FFCBA4', 'darkyellow': '#FCC200', 'darkblue': '#00008B',
|
}
|
||||||
'darkgreen': '#006400', 'purple': '#800080', 'orange': '#FFA500',
|
return '#888888';
|
||||||
'green': '#00FF00', 'blue': '#0000FF', 'red': '#FF0000', 'black': '#888888',
|
|
||||||
};
|
|
||||||
return colorMap[color] || color;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
interface MapViewProps {
|
interface MapViewProps {
|
||||||
|
|
@ -75,7 +69,6 @@ interface MapViewProps {
|
||||||
const MapView: React.FC<MapViewProps> = ({ initialAddressData, initialTerm }) => {
|
const MapView: React.FC<MapViewProps> = ({ initialAddressData, initialTerm }) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
// -- STATE --
|
|
||||||
const [isDarkMode, setIsDarkMode] = useState(true);
|
const [isDarkMode, setIsDarkMode] = useState(true);
|
||||||
const currentTheme = isDarkMode ? themes.dark : themes.light;
|
const currentTheme = isDarkMode ? themes.dark : themes.light;
|
||||||
|
|
||||||
|
|
@ -90,7 +83,6 @@ const MapView: React.FC<MapViewProps> = ({ initialAddressData, initialTerm }) =>
|
||||||
size: { width: 0, height: 0 }
|
size: { width: 0, height: 0 }
|
||||||
});
|
});
|
||||||
|
|
||||||
// -- REFS --
|
|
||||||
const mapDivRef = useRef<HTMLDivElement>(null);
|
const mapDivRef = useRef<HTMLDivElement>(null);
|
||||||
const mapRef = useRef<Map | null>(null);
|
const mapRef = useRef<Map | null>(null);
|
||||||
const tileLayerRef = useRef<TileLayer<XYZ> | null>(null);
|
const tileLayerRef = useRef<TileLayer<XYZ> | null>(null);
|
||||||
|
|
@ -100,10 +92,8 @@ const MapView: React.FC<MapViewProps> = ({ initialAddressData, initialTerm }) =>
|
||||||
);
|
);
|
||||||
const uiContainerRef = useRef<HTMLDivElement>(null);
|
const uiContainerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
// -- GSAP ENTRANCE --
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
const ctx = gsap.context(() => {
|
const ctx = gsap.context(() => {
|
||||||
// We use clearProps: 'all' to ensure GSAP doesn't leave the elements with weird opacity states
|
|
||||||
gsap.from('.floating-ui', {
|
gsap.from('.floating-ui', {
|
||||||
y: 20,
|
y: 20,
|
||||||
opacity: 0,
|
opacity: 0,
|
||||||
|
|
@ -111,13 +101,12 @@ const MapView: React.FC<MapViewProps> = ({ initialAddressData, initialTerm }) =>
|
||||||
stagger: 0.1,
|
stagger: 0.1,
|
||||||
ease: 'power3.out',
|
ease: 'power3.out',
|
||||||
delay: 0.5,
|
delay: 0.5,
|
||||||
clearProps: 'opacity,transform' // Crucial: Ensures visibility after animation ends
|
clearProps: 'opacity,transform'
|
||||||
});
|
});
|
||||||
}, uiContainerRef);
|
}, uiContainerRef);
|
||||||
return () => ctx.revert();
|
return () => ctx.revert();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// -- MAP INIT --
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!mapRef.current) {
|
if (!mapRef.current) {
|
||||||
const baseLayer = new TileLayer({
|
const baseLayer = new TileLayer({
|
||||||
|
|
@ -154,7 +143,6 @@ const MapView: React.FC<MapViewProps> = ({ initialAddressData, initialTerm }) =>
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// -- THEME SWITCHING --
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (mapRef.current && tileLayerRef.current) {
|
if (mapRef.current && tileLayerRef.current) {
|
||||||
tileLayerRef.current.setSource(new XYZ({
|
tileLayerRef.current.setSource(new XYZ({
|
||||||
|
|
@ -164,7 +152,6 @@ const MapView: React.FC<MapViewProps> = ({ initialAddressData, initialTerm }) =>
|
||||||
}
|
}
|
||||||
}, [isDarkMode]);
|
}, [isDarkMode]);
|
||||||
|
|
||||||
// -- SEARCH DATA --
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (initialAddressData && initialAddressData.length > 0) {
|
if (initialAddressData && initialAddressData.length > 0) {
|
||||||
const lat = parseFloat(initialAddressData[0].lat);
|
const lat = parseFloat(initialAddressData[0].lat);
|
||||||
|
|
@ -196,7 +183,6 @@ const MapView: React.FC<MapViewProps> = ({ initialAddressData, initialTerm }) =>
|
||||||
const clickedLonLat = clickedCoordinate ? toLonLat(clickedCoordinate) : null;
|
const clickedLonLat = clickedCoordinate ? toLonLat(clickedCoordinate) : null;
|
||||||
const activeLayerCount = Object.values(layerVisibility).filter(Boolean).length;
|
const activeLayerCount = Object.values(layerVisibility).filter(Boolean).length;
|
||||||
|
|
||||||
// -- STYLES --
|
|
||||||
const styles = {
|
const styles = {
|
||||||
wrapper: {
|
wrapper: {
|
||||||
position: 'relative' as const, width: '100vw', height: '100vh',
|
position: 'relative' as const, width: '100vw', height: '100vh',
|
||||||
|
|
@ -207,7 +193,7 @@ const MapView: React.FC<MapViewProps> = ({ initialAddressData, initialTerm }) =>
|
||||||
uiLayer: {
|
uiLayer: {
|
||||||
position: 'absolute' as const, top: 0, left: 0, width: '100%', height: '100%',
|
position: 'absolute' as const, top: 0, left: 0, width: '100%', height: '100%',
|
||||||
pointerEvents: 'none' as const,
|
pointerEvents: 'none' as const,
|
||||||
zIndex: 1000, // FORCE TOP LAYER
|
zIndex: 1000,
|
||||||
padding: '24px',
|
padding: '24px',
|
||||||
display: 'flex', flexDirection: 'column' as const, justifyContent: 'space-between',
|
display: 'flex', flexDirection: 'column' as const, justifyContent: 'space-between',
|
||||||
},
|
},
|
||||||
|
|
@ -216,7 +202,7 @@ const MapView: React.FC<MapViewProps> = ({ initialAddressData, initialTerm }) =>
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
pointerEvents: 'auto' as const,
|
pointerEvents: 'auto' as const,
|
||||||
gap: '12px',
|
gap: '12px',
|
||||||
width: '100%' // Ensure it spans width
|
width: '100%'
|
||||||
},
|
},
|
||||||
glassPanel: {
|
glassPanel: {
|
||||||
background: currentTheme.glass,
|
background: currentTheme.glass,
|
||||||
|
|
@ -232,7 +218,7 @@ const MapView: React.FC<MapViewProps> = ({ initialAddressData, initialTerm }) =>
|
||||||
backdropFilter: 'blur(20px)', border: `1px solid ${currentTheme.border}`,
|
backdropFilter: 'blur(20px)', border: `1px solid ${currentTheme.border}`,
|
||||||
boxShadow: currentTheme.shadow,
|
boxShadow: currentTheme.shadow,
|
||||||
transition: 'all 0.3s ease',
|
transition: 'all 0.3s ease',
|
||||||
flexShrink: 0 // Prevent collapsing
|
flexShrink: 0
|
||||||
},
|
},
|
||||||
actionButton: {
|
actionButton: {
|
||||||
width: '48px', height: '48px', borderRadius: '50%',
|
width: '48px', height: '48px', borderRadius: '50%',
|
||||||
|
|
@ -240,10 +226,10 @@ const MapView: React.FC<MapViewProps> = ({ initialAddressData, initialTerm }) =>
|
||||||
background: currentTheme.glass,
|
background: currentTheme.glass,
|
||||||
backdropFilter: 'blur(20px)', WebkitBackdropFilter: 'blur(20px)',
|
backdropFilter: 'blur(20px)', WebkitBackdropFilter: 'blur(20px)',
|
||||||
border: `1px solid ${currentTheme.border}`,
|
border: `1px solid ${currentTheme.border}`,
|
||||||
color: currentTheme.iconColor, // Explicit high contrast color
|
color: currentTheme.iconColor,
|
||||||
boxShadow: currentTheme.shadow, // Force visibility
|
boxShadow: currentTheme.shadow,
|
||||||
cursor: 'pointer', transition: 'all 0.2s',
|
cursor: 'pointer', transition: 'all 0.2s',
|
||||||
flexShrink: 0 // Prevent collapsing
|
flexShrink: 0
|
||||||
},
|
},
|
||||||
controlsContainer: {
|
controlsContainer: {
|
||||||
marginTop: 'auto', maxWidth: '340px', maxHeight: '60vh',
|
marginTop: 'auto', maxWidth: '340px', maxHeight: '60vh',
|
||||||
|
|
@ -346,19 +332,15 @@ const MapView: React.FC<MapViewProps> = ({ initialAddressData, initialTerm }) =>
|
||||||
<div style={styles.wrapper}>
|
<div style={styles.wrapper}>
|
||||||
<style>{scrollbarStyles}</style>
|
<style>{scrollbarStyles}</style>
|
||||||
|
|
||||||
{/* 1. MAP LAYER */}
|
|
||||||
<div
|
<div
|
||||||
ref={mapDivRef}
|
ref={mapDivRef}
|
||||||
style={{ width: '100%', height: '100%', transition: 'filter 0.5s' }}
|
style={{ width: '100%', height: '100%', transition: 'filter 0.5s' }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* 2. UI LAYER */}
|
|
||||||
<div ref={uiContainerRef} style={styles.uiLayer}>
|
<div ref={uiContainerRef} style={styles.uiLayer}>
|
||||||
|
|
||||||
{/* TOP BAR */}
|
|
||||||
<div style={styles.topBar}>
|
<div style={styles.topBar}>
|
||||||
|
|
||||||
{/* Back Button */}
|
|
||||||
<button
|
<button
|
||||||
className="floating-ui"
|
className="floating-ui"
|
||||||
style={styles.actionButton}
|
style={styles.actionButton}
|
||||||
|
|
@ -370,7 +352,6 @@ const MapView: React.FC<MapViewProps> = ({ initialAddressData, initialTerm }) =>
|
||||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M19 12H5M12 19l-7-7 7-7"/></svg>
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M19 12H5M12 19l-7-7 7-7"/></svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{/* Location Badge */}
|
|
||||||
<div className="floating-ui" style={styles.locationBadge}>
|
<div className="floating-ui" style={styles.locationBadge}>
|
||||||
<div style={{ width: '6px', height: '6px', background: '#00FF94', borderRadius: '50%', marginRight: '12px', boxShadow: '0 0 8px #00FF94' }} />
|
<div style={{ width: '6px', height: '6px', background: '#00FF94', borderRadius: '50%', marginRight: '12px', boxShadow: '0 0 8px #00FF94' }} />
|
||||||
<span style={{ fontSize: '14px', fontWeight: 600, letterSpacing: '0.5px', color: currentTheme.textMain, textTransform: 'uppercase' }}>
|
<span style={{ fontSize: '14px', fontWeight: 600, letterSpacing: '0.5px', color: currentTheme.textMain, textTransform: 'uppercase' }}>
|
||||||
|
|
@ -378,7 +359,6 @@ const MapView: React.FC<MapViewProps> = ({ initialAddressData, initialTerm }) =>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Theme Toggle Button */}
|
|
||||||
<button
|
<button
|
||||||
className="floating-ui"
|
className="floating-ui"
|
||||||
style={styles.actionButton}
|
style={styles.actionButton}
|
||||||
|
|
@ -396,7 +376,6 @@ const MapView: React.FC<MapViewProps> = ({ initialAddressData, initialTerm }) =>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* CONTROLS */}
|
|
||||||
<div className="floating-ui" style={styles.controlsContainer}>
|
<div className="floating-ui" style={styles.controlsContainer}>
|
||||||
<div style={styles.controlsHeader}>Overlay Controls</div>
|
<div style={styles.controlsHeader}>Overlay Controls</div>
|
||||||
|
|
||||||
|
|
@ -428,14 +407,12 @@ const MapView: React.FC<MapViewProps> = ({ initialAddressData, initialTerm }) =>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* HUD */}
|
|
||||||
{clickedCoordinate && (
|
{clickedCoordinate && (
|
||||||
<div className="floating-ui" style={styles.hud}>
|
<div className="floating-ui" style={styles.hud}>
|
||||||
LOCATION_LOCK: {clickedCoordinate[1].toFixed(4)} N, {clickedCoordinate[0].toFixed(4)} E
|
LOCATION_LOCK: {clickedCoordinate[1].toFixed(4)} N, {clickedCoordinate[0].toFixed(4)} E
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* RIGHT SIDEBAR */}
|
|
||||||
<div className="floating-ui" style={styles.rightSidebar}>
|
<div className="floating-ui" style={styles.rightSidebar}>
|
||||||
<div style={styles.sidebarCard}>
|
<div style={styles.sidebarCard}>
|
||||||
<div style={styles.sidebarTitle}>General Values</div>
|
<div style={styles.sidebarTitle}>General Values</div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue