131 lines
3.2 KiB
TypeScript
131 lines
3.2 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
import dynamic from "next/dynamic";
|
|
|
|
interface CountryData {
|
|
name: string;
|
|
count: number;
|
|
position?: [number, number]; // latitude, longitude
|
|
}
|
|
|
|
interface ObservatoryMapProps {
|
|
countries: CountryData[];
|
|
onCountrySelect: (country: string) => void;
|
|
selectedCountry: string | null;
|
|
}
|
|
|
|
// Add type declaration for leaflet
|
|
declare global {
|
|
interface Window {
|
|
_leaflet_L: any;
|
|
}
|
|
}
|
|
|
|
// Mapping of countries to geographic coordinates [latitude, longitude]
|
|
const COUNTRY_COORDINATES: Record<string, [number, number]> = {
|
|
// Africa
|
|
'Sudan': [15.5, 30.5],
|
|
'Egypt': [26.8, 30.8],
|
|
'South Africa': [-30.6, 22.9],
|
|
'Nigeria': [9.1, 8.7],
|
|
'Kenya': [0.0, 38.0],
|
|
'Ethiopia': [9.1, 40.5],
|
|
'Morocco': [31.8, -7.1],
|
|
'Algeria': [28.0, 1.7],
|
|
'Tunisia': [34.0, 9.0],
|
|
|
|
// Americas
|
|
'USA': [37.1, -95.7],
|
|
'New York': [40.7, -74.0],
|
|
'Canada': [56.1, -106.3],
|
|
'Mexico': [23.6, -102.5],
|
|
'Brazil': [-14.2, -51.9],
|
|
'Argentina': [-38.4, -63.6],
|
|
|
|
// Europe
|
|
'UK': [55.4, -3.4],
|
|
'France': [46.2, 2.2],
|
|
'Germany': [51.2, 10.4],
|
|
'Italy': [41.9, 12.6],
|
|
'Spain': [40.5, -3.7],
|
|
'Ukraine': [48.4, 31.2],
|
|
'Russia': [61.5, 105.3],
|
|
'Poland': [51.9, 19.1],
|
|
'Sweden': [60.1, 18.6],
|
|
'Norway': [60.5, 8.5],
|
|
'Finland': [61.9, 25.7],
|
|
'Greece': [39.1, 21.8],
|
|
'Netherlands': [52.1, 5.3],
|
|
'Belgium': [50.5, 4.5],
|
|
'Portugal': [39.4, -8.2],
|
|
'Switzerland': [46.8, 8.2],
|
|
'Austria': [47.5, 14.5],
|
|
|
|
// Asia
|
|
'China': [35.9, 104.2],
|
|
'India': [20.6, 79.0],
|
|
'Japan': [36.2, 138.3],
|
|
'South Korea': [35.9, 127.8],
|
|
'Indonesia': [-0.8, 113.9],
|
|
'Thailand': [15.9, 101.0],
|
|
'Vietnam': [14.1, 108.3],
|
|
'Philippines': [12.9, 121.8],
|
|
'Malaysia': [4.2, 101.9],
|
|
'Singapore': [1.3, 103.8],
|
|
'Pakistan': [30.4, 69.3],
|
|
'Iran': [32.4, 53.7],
|
|
'Iraq': [33.2, 43.7],
|
|
'Saudi Arabia': [23.9, 45.1],
|
|
'Turkey': [38.9, 35.2],
|
|
'Israel': [31.0, 34.9],
|
|
'Palestine': [31.9, 35.2],
|
|
'Syria': [34.8, 39.0],
|
|
'Afghanistan': [33.9, 67.7],
|
|
|
|
// Oceania
|
|
'Australia': [-25.3, 133.8],
|
|
|
|
// Other
|
|
'United Nations': [40.7, -74.0], // UN HQ in New York
|
|
};
|
|
|
|
// Create a client-only map component to avoid SSR issues
|
|
const MapComponent = dynamic(
|
|
() => import('./map-component').then((mod) => mod.MapComponent),
|
|
{
|
|
ssr: false,
|
|
loading: () => (
|
|
<div className="w-full h-full bg-gray-100 flex items-center justify-center">
|
|
<p className="text-gray-500">Loading map...</p>
|
|
</div>
|
|
),
|
|
}
|
|
);
|
|
|
|
export function ObservatoryMap({
|
|
countries,
|
|
onCountrySelect,
|
|
selectedCountry
|
|
}: ObservatoryMapProps) {
|
|
// Prepare countries with coordinates
|
|
const countriesWithCoordinates = countries.filter(country => {
|
|
return COUNTRY_COORDINATES[country.name] !== undefined;
|
|
}).map(country => ({
|
|
...country,
|
|
position: COUNTRY_COORDINATES[country.name]
|
|
}));
|
|
|
|
// Sort countries by count (higher count = shows on top)
|
|
const sortedCountries = [...countriesWithCoordinates].sort((a, b) => b.count - a.count);
|
|
|
|
return (
|
|
<div className="w-full h-full">
|
|
<MapComponent
|
|
countries={sortedCountries}
|
|
onCountrySelect={onCountrySelect}
|
|
selectedCountry={selectedCountry}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|