forked from emre/www_projectmycelium_com
Replace static actual grid data
This commit is contained in:
84
src/components/ui/DynamicMapContainer.tsx
Normal file
84
src/components/ui/DynamicMapContainer.tsx
Normal file
@@ -0,0 +1,84 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import WorldMap from './world-map';
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
// Interface for the simplified data passed to WorldMap
|
||||
interface GeoNode {
|
||||
lat: number;
|
||||
lng: number;
|
||||
label?: string;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
// Interface for the raw data structure expected from the gridproxy API
|
||||
interface RawNode {
|
||||
node_id: number;
|
||||
location: {
|
||||
latitude: string; // API often returns these as strings
|
||||
longitude: string; // API often returns these as strings
|
||||
city: string;
|
||||
country: string;
|
||||
};
|
||||
// ... other raw fields you don't need
|
||||
}
|
||||
|
||||
function DynamicMapContainer() {
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [nodes, setNodes] = useState<GeoNode[]>([]);
|
||||
const API_URL = "https://gridproxy.grid.tf/nodes?healthy=true";
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchNodeData() {
|
||||
try {
|
||||
const response = await fetch(API_URL);
|
||||
const data: RawNode[] = await response.json(); // Type the incoming data
|
||||
|
||||
// 🚨 Map the API response to your component's expected GeoNode format
|
||||
const geoNodes: GeoNode[] = data
|
||||
.filter((node: RawNode) => node.location && node.location.latitude && node.location.longitude)
|
||||
.map((node: RawNode) => ({
|
||||
// Convert string coordinates to numbers
|
||||
lat: parseFloat(node.location.latitude),
|
||||
lng: parseFloat(node.location.longitude),
|
||||
label: `${node.location.city}, ${node.location.country} (${node.node_id})`,
|
||||
// Optionally set color based on some node property if available
|
||||
}));
|
||||
|
||||
setNodes(geoNodes);
|
||||
setLoading(false);
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch node data:", error);
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
fetchNodeData();
|
||||
}, []);
|
||||
|
||||
// --- RENDERING ---
|
||||
|
||||
if (loading) {
|
||||
// Show a loading state while data is being fetched
|
||||
return (
|
||||
<div className="flex justify-center items-center w-full aspect-[2/1] bg-[#111111] rounded-lg text-cyan-500">
|
||||
<motion.span
|
||||
animate={{ rotate: 360 }}
|
||||
transition={{ duration: 1, repeat: Infinity, ease: "linear" }}
|
||||
className="text-4xl"
|
||||
>
|
||||
🌎
|
||||
</motion.span>
|
||||
<p className="ml-4">Loading nodes...</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Pass the dynamically fetched nodes to your WorldMap component
|
||||
return (
|
||||
<WorldMap
|
||||
nodes={nodes}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default DynamicMapContainer;
|
||||
Reference in New Issue
Block a user