diff --git a/components/DvpnMap.js b/components/DvpnMap.js
new file mode 100644
index 0000000..ab9852b
--- /dev/null
+++ b/components/DvpnMap.js
@@ -0,0 +1,123 @@
+import dynamic from 'next/dynamic';
+import { useEffect, useState } from 'react';
+import 'leaflet/dist/leaflet.css';
+import L from 'leaflet';
+
+// Dynamically import components with ssr: false
+const MapContainer = dynamic(() => import('react-leaflet').then((module) => module.MapContainer), { ssr: false });
+const TileLayer = dynamic(() => import('react-leaflet').then((module) => module.TileLayer), { ssr: false });
+const Marker = dynamic(() => import('react-leaflet').then((module) => module.Marker), { ssr: false });
+const Popup = dynamic(() => import('react-leaflet').then((module) => module.Popup), { ssr: false });
+
+// Define a custom animated icon
+const animatedIcon = L.divIcon({
+ className: 'custom-animated-icon',
+ html: `
+
+ `,
+ iconSize: [20, 20],
+ iconAnchor: [10, 10],
+ popupAnchor: [0, -10],
+});
+
+const DvpnMap = ({ nodes }) => {
+ const [isClient, setIsClient] = useState(false);
+ const [offsets, setOffsets] = useState({});
+
+ useEffect(() => {
+ setIsClient(true);
+
+ // Initialize offsets
+ const offsetMap = {};
+ nodes.forEach((node) => {
+ const [lat, lon] = node.ipinfolocation.split(',').map(Number);
+ const key = `${lat},${lon}`;
+ if (!offsetMap[key]) {
+ offsetMap[key] = [0, 0];
+ } else {
+ // Apply a small offset if multiple markers have the same coordinates
+ offsetMap[key] = [offsetMap[key][0] + 0.01, offsetMap[key][1] + 0.01];
+ }
+ });
+ setOffsets(offsetMap);
+ }, [nodes]);
+
+ if (!isClient) {
+ return null;
+ }
+
+ return (
+
+
+
+ {/* */}
+ {/* */}
+ {nodes.map((node, index) => {
+ const [lat, lon] = node.ipinfolocation.split(',').map(Number);
+ const key = `${lat},${lon}`;
+ const offset = offsets[key] || [0, 0];
+ return (
+
+
+
+
{node.name}
+
Country: {node.ipinfocountry}
+
City: {node.ipinfocity}
+
Node Name: {node.nodename}
+
Download Speed: {node.downloadSpeed} Mbps
+
Upload Speed: {node.uploadSpeed} Mbps
+
+
+
+ );
+ })}
+
+
+
+ );
+};
+
+export default DvpnMap;
diff --git a/components/DwifiMap.js b/components/DwifiMap.js
new file mode 100644
index 0000000..217e52b
--- /dev/null
+++ b/components/DwifiMap.js
@@ -0,0 +1,124 @@
+import { useState, useEffect, useRef } from 'react';
+import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet';
+import 'leaflet/dist/leaflet.css';
+import L from 'leaflet';
+
+// Custom icon
+const customIcon = new L.Icon({
+ iconUrl: 'https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon.png',
+ iconRetinaUrl: 'https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon-2x.png',
+ iconSize: [25, 41],
+ iconAnchor: [12, 41],
+ popupAnchor: [1, -34],
+ shadowUrl: 'https://unpkg.com/leaflet@1.7.1/dist/images/marker-shadow.png',
+ shadowSize: [41, 41],
+});
+
+export default function DwifiMap() {
+ const [nodes, setNodes] = useState([]);
+ const socketRef = useRef(null); // Use ref to maintain WebSocket across renders
+
+ useEffect(() => {
+ const socket = new WebSocket('wss://dev.gateway.erebrus.io/api/v1.0/nodedwifi/stream');
+
+ socket.onopen = function () {
+ console.log('WebSocket is open now.');
+ };
+
+ socket.onmessage = function (event) {
+ console.log('Received:', event.data);
+ };
+
+ socket.onerror = function (event) {
+ console.error('WebSocket error:', event);
+ };
+
+ socket.onclose = function (event) {
+ console.log('WebSocket is closed now.', event);
+ };
+
+ return () => {
+ socket.close();
+ };
+ }, []);
+
+ useEffect(() => {
+ function connectWebSocket() {
+ // Initialize the WebSocket connection
+ socketRef.current = new WebSocket('wss://dev.gateway.erebrus.io/api/v1.0/nodedwifi/stream');
+
+ // Handle the WebSocket connection opening
+ socketRef.current.onopen = function () {
+ console.log('WebSocket is open now.');
+ };
+
+ // Handle incoming WebSocket messages
+ socketRef.current.onmessage = function (event) {
+ const newNode = JSON.parse(event.data);
+ setNodes((prevNodes) => {
+ const existingIndex = prevNodes.findIndex((node) => node.id === newNode.id);
+ if (existingIndex !== -1) {
+ return prevNodes.map((node) => (node.id === newNode.id ? newNode : node));
+ } else {
+ return [...prevNodes, newNode];
+ }
+ });
+ };
+
+ // Handle WebSocket errors
+ socketRef.current.onerror = function (event) {
+ console.error('WebSocket error:', event);
+ };
+
+ // Handle WebSocket closure
+ socketRef.current.onclose = function () {
+ console.log('WebSocket is closed. Attempting to reconnect...');
+ setTimeout(connectWebSocket, 5000); // Attempt to reconnect after 5 seconds
+ };
+ }
+
+ // Establish WebSocket connection
+ connectWebSocket();
+
+ // Cleanup function
+ return () => {
+ console.log('Cleaning up WebSocket connection...');
+ if (socketRef.current) {
+ socketRef.current.close();
+ }
+ };
+ }, []); // Empty dependency array ensures this runs once
+
+ return (
+
+
+
+ {nodes.map((node) => {
+ const [lat, lon] = node.co_ordinates.split(',').map(Number);
+ return (
+
+
+
+
Address: {node.location}
+
Gateway: {node.gateway}
+
Price per Minute: {node.price_per_min}
+
Wallet Address: {node.wallet_address}
+
Chain Name: {node.chain_name}
+
+
+
+ );
+ })}
+
+
+ );
+}
diff --git a/package.json b/package.json
index 5766f36..4460e56 100644
--- a/package.json
+++ b/package.json
@@ -57,6 +57,7 @@
"file-saver": "^2.0.5",
"framer-motion": "^8.0.2",
"js-cookie": "^3.0.5",
+ "leaflet": "^1.9.4",
"mapbox-gl": "^3.5.2",
"next": "13.1.1",
"nft.storage": "^7.1.1",
@@ -68,6 +69,7 @@
"react-google-recaptcha": "^2.1.0",
"react-icons": "^4.7.1",
"react-intersection-observer": "^9.13.0",
+ "react-leaflet": "^4.2.1",
"react-mapbox-gl": "^5.1.1",
"react-responsive-carousel": "^3.2.23",
"react-toastify": "^9.1.1",
diff --git a/pages/dwifi.tsx b/pages/dwifi.tsx
index c7a091f..25c4a70 100644
--- a/pages/dwifi.tsx
+++ b/pages/dwifi.tsx
@@ -2,6 +2,10 @@ import React, { useEffect, useState} from "react";
import Link from "next/link";
import NodeDwifiStream from "../components/nodedataDwifi";
import { motion } from "framer-motion";
+import dynamic from 'next/dynamic';
+
+const DwifiMap = dynamic(() => import('../components/DwifiMap'), { ssr: false });
+
const Dwifi = () => {
@@ -45,7 +49,17 @@ const Dwifi = () => {
+
+
+
{/* */}
)
diff --git a/pages/explorer.js b/pages/explorer.js
index bc6f0bd..893f4c4 100644
--- a/pages/explorer.js
+++ b/pages/explorer.js
@@ -1,10 +1,27 @@
import React, { useEffect, useState} from "react";
import Link from "next/link";
import NodesData from "../components/NodesData";
+import dynamic from 'next/dynamic';
+// import Dvpn Map from "../components/DvpnMap"
import { motion } from "framer-motion";
+const DvpnMap = dynamic(() => import('../components/DvpnMap'), { ssr: false });
+
+
const Explorer = () => {
+ const [nodes, setNodes] = useState([]);
+ const [activeMap, setActiveMap] = useState('pin');
+
+ useEffect(() => {
+ async function fetchNodes() {
+ const response = await fetch('https://gateway.erebrus.io/api/v1.0/nodes/all');
+ const data = await response.json();
+ setNodes(data.payload);
+ }
+ fetchNodes();
+ }, []);
+
return (
-
{/* */}
+
+
+
+
)
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b1051a6..f9c28aa 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -152,6 +152,9 @@ importers:
js-cookie:
specifier: ^3.0.5
version: 3.0.5
+ leaflet:
+ specifier: ^1.9.4
+ version: 1.9.4
mapbox-gl:
specifier: ^3.5.2
version: 3.5.2
@@ -182,6 +185,9 @@ importers:
react-intersection-observer:
specifier: ^9.13.0
version: 9.13.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ react-leaflet:
+ specifier: ^4.2.1
+ version: 4.2.1(leaflet@1.9.4)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
react-mapbox-gl:
specifier: ^5.1.1
version: 5.1.1(mapbox-gl@3.5.2)(prop-types@15.8.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
@@ -2744,6 +2750,13 @@ packages:
peerDependencies:
react: '*'
+ '@react-leaflet/core@2.1.0':
+ resolution: {integrity: sha512-Qk7Pfu8BSarKGqILj4x7bCSZ1pjuAPZ+qmRwH5S7mDS91VSbVVsJSrW4qA+GPrro8t69gFYVMWb1Zc4yFmPiVg==}
+ peerDependencies:
+ leaflet: ^1.9.0
+ react: ^18.0.0
+ react-dom: ^18.0.0
+
'@react-native-async-storage/async-storage@1.23.1':
resolution: {integrity: sha512-Qd2kQ3yi6Y3+AcUlrHxSLlnBvpdCEMVGFlVBneVOjaFaPU61g1huc38g339ysXspwY1QZA2aNhrk/KlHGO+ewA==}
peerDependencies:
@@ -7421,6 +7434,9 @@ packages:
resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==}
engines: {node: '>=0.10'}
+ leaflet@1.9.4:
+ resolution: {integrity: sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==}
+
leven@3.1.0:
resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
engines: {node: '>=6'}
@@ -9122,6 +9138,13 @@ packages:
react-is@18.2.0:
resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==}
+ react-leaflet@4.2.1:
+ resolution: {integrity: sha512-p9chkvhcKrWn/H/1FFeVSqLdReGwn2qmiobOQGO3BifX+/vV/39qhY8dGqbdcPh1e6jxh/QHriLXr7a4eLFK4Q==}
+ peerDependencies:
+ leaflet: ^1.9.0
+ react: ^18.0.0
+ react-dom: ^18.0.0
+
react-lifecycles-compat@3.0.4:
resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==}
@@ -13316,7 +13339,7 @@ snapshots:
glob: 7.2.3
jsc-safe-url: 0.2.4
lightningcss: 1.19.0
- postcss: 8.4.33
+ postcss: 8.4.38
resolve-from: 5.0.0
transitivePeerDependencies:
- supports-color
@@ -14966,6 +14989,12 @@ snapshots:
dependencies:
react: 18.2.0
+ '@react-leaflet/core@2.1.0(leaflet@1.9.4)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ dependencies:
+ leaflet: 1.9.4
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+
'@react-native-async-storage/async-storage@1.23.1(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(@types/react@18.2.47)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(utf-8-validate@5.0.10))':
dependencies:
merge-options: 3.0.4
@@ -20114,8 +20143,8 @@ snapshots:
'@typescript-eslint/parser': 5.62.0(eslint@8.30.0)(typescript@5.3.3)
eslint: 8.30.0
eslint-import-resolver-node: 0.3.9
- eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@5.62.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.30.0)
- eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.19.0(eslint@8.30.0)(typescript@5.3.3))(eslint@8.30.0)
+ eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@5.62.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.19.0(eslint@8.30.0)(typescript@5.3.3))(eslint@8.30.0))(eslint@8.30.0)
+ eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@5.62.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.19.0(eslint@8.30.0)(typescript@5.3.3))(eslint@8.30.0))(eslint@8.30.0))(eslint@8.30.0)
eslint-plugin-jsx-a11y: 6.8.0(eslint@8.30.0)
eslint-plugin-react: 7.33.2(eslint@8.30.0)
eslint-plugin-react-hooks: 4.6.0(eslint@8.30.0)
@@ -20133,13 +20162,13 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@5.62.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.30.0):
+ eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@5.62.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.19.0(eslint@8.30.0)(typescript@5.3.3))(eslint@8.30.0))(eslint@8.30.0):
dependencies:
debug: 4.3.4
enhanced-resolve: 5.15.0
eslint: 8.30.0
- eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.62.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@5.62.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.30.0))(eslint@8.30.0)
- eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.19.0(eslint@8.30.0)(typescript@5.3.3))(eslint@8.30.0)
+ eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.62.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@5.62.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.19.0(eslint@8.30.0)(typescript@5.3.3))(eslint@8.30.0))(eslint@8.30.0))(eslint@8.30.0)
+ eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@5.62.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.19.0(eslint@8.30.0)(typescript@5.3.3))(eslint@8.30.0))(eslint@8.30.0))(eslint@8.30.0)
fast-glob: 3.3.2
get-tsconfig: 4.7.2
is-core-module: 2.13.1
@@ -20150,28 +20179,18 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
- eslint-module-utils@2.8.0(@typescript-eslint/parser@5.62.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@5.62.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.30.0))(eslint@8.30.0):
+ eslint-module-utils@2.8.0(@typescript-eslint/parser@5.62.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@5.62.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.19.0(eslint@8.30.0)(typescript@5.3.3))(eslint@8.30.0))(eslint@8.30.0))(eslint@8.30.0):
dependencies:
debug: 3.2.7
optionalDependencies:
'@typescript-eslint/parser': 5.62.0(eslint@8.30.0)(typescript@5.3.3)
eslint: 8.30.0
eslint-import-resolver-node: 0.3.9
- eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@5.62.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.30.0)
+ eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@5.62.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.19.0(eslint@8.30.0)(typescript@5.3.3))(eslint@8.30.0))(eslint@8.30.0)
transitivePeerDependencies:
- supports-color
- eslint-module-utils@2.8.0(@typescript-eslint/parser@6.19.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@8.30.0):
- dependencies:
- debug: 3.2.7
- optionalDependencies:
- '@typescript-eslint/parser': 6.19.0(eslint@8.30.0)(typescript@5.3.3)
- eslint: 8.30.0
- eslint-import-resolver-node: 0.3.9
- transitivePeerDependencies:
- - supports-color
-
- eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.19.0(eslint@8.30.0)(typescript@5.3.3))(eslint@8.30.0):
+ eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@5.62.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.19.0(eslint@8.30.0)(typescript@5.3.3))(eslint@8.30.0))(eslint@8.30.0))(eslint@8.30.0):
dependencies:
array-includes: 3.1.7
array.prototype.findlastindex: 1.2.3
@@ -20181,7 +20200,7 @@ snapshots:
doctrine: 2.1.0
eslint: 8.30.0
eslint-import-resolver-node: 0.3.9
- eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.19.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@8.30.0)
+ eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.62.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@5.62.0(eslint@8.30.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.19.0(eslint@8.30.0)(typescript@5.3.3))(eslint@8.30.0))(eslint@8.30.0))(eslint@8.30.0)
hasown: 2.0.0
is-core-module: 2.13.1
is-glob: 4.0.3
@@ -20192,7 +20211,7 @@ snapshots:
semver: 6.3.1
tsconfig-paths: 3.15.0
optionalDependencies:
- '@typescript-eslint/parser': 6.19.0(eslint@8.30.0)(typescript@5.3.3)
+ '@typescript-eslint/parser': 5.62.0(eslint@8.30.0)(typescript@5.3.3)
transitivePeerDependencies:
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
@@ -22246,6 +22265,8 @@ snapshots:
dependencies:
language-subtag-registry: 0.3.22
+ leaflet@1.9.4: {}
+
leven@3.1.0: {}
levn@0.3.0:
@@ -24276,6 +24297,13 @@ snapshots:
react-is@18.2.0: {}
+ react-leaflet@4.2.1(leaflet@1.9.4)(react-dom@18.2.0(react@18.2.0))(react@18.2.0):
+ dependencies:
+ '@react-leaflet/core': 2.1.0(leaflet@1.9.4)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ leaflet: 1.9.4
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+
react-lifecycles-compat@3.0.4: {}
react-mapbox-gl@5.1.1(mapbox-gl@3.5.2)(prop-types@15.8.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0):