From 1ee4e11bbe1372634a8d87e6ab6dfc8293f5488d Mon Sep 17 00:00:00 2001 From: Benjamin Preiss Date: Wed, 26 Jun 2024 15:11:21 +0200 Subject: [PATCH] feat: connect geo-data to world map --- apps/info-dashboard/src/app/page.tsx | 552 ++++++++++-------- .../ActiveNodesWorldMap.tsx | 14 +- apps/info-dashboard/src/lib/fetchers/nodes.ts | 20 + 3 files changed, 337 insertions(+), 249 deletions(-) diff --git a/apps/info-dashboard/src/app/page.tsx b/apps/info-dashboard/src/app/page.tsx index ecc2c14..c226af3 100644 --- a/apps/info-dashboard/src/app/page.tsx +++ b/apps/info-dashboard/src/app/page.tsx @@ -7,21 +7,21 @@ import MetricsCard from "@/components/MetricsCard/MetricsCard"; import HeadingSection from "@/components/HeadingSection"; import SectionContainer from "@/components/SectionContainer"; import { - alertAndFeedbackAlertCircle, - arrowsArrowDown, - arrowsArrowUp, - arrowsSwitchVertical01, - generalLoading01, - generalSearchLg, + alertAndFeedbackAlertCircle, + arrowsArrowDown, + arrowsArrowUp, + arrowsSwitchVertical01, + generalLoading01, + generalSearchLg, } from "@frontline-hq/untitledui-icons"; import CardWithBorder from "@/components/CardWithBorder/CardWithBorder"; import { - Area, - AreaChart, - CartesianGrid, - ResponsiveContainer, - XAxis, - YAxis, + Area, + AreaChart, + CartesianGrid, + ResponsiveContainer, + XAxis, + YAxis, } from "recharts"; import { useQuery } from "@tanstack/react-query"; import { fetchMetrics, toChartData } from "@/lib/fetchers/metrics"; @@ -30,237 +30,315 @@ import FeaturedIcon from "@/components/FeaturedIcon"; import { DateTime } from "luxon"; import EmptyState from "@/components/EmptyState/EmptyState"; import ActiveNodesWorldMap from "@/components/ActiveNodesWorldMap/ActiveNodesWorldMap"; +import { fetchNodes, toGeoJson } from "@/lib/fetchers/nodes"; export default function Home() { - const { data, isLoading, isError } = useQuery({ - queryFn: fetchMetrics, - queryKey: ["metrics"], //Array according to Documentation - }); - const timeData = { - Nodes: toChartData(data?.Nodes ?? []), - JobsCompleted: toChartData(data?.JobsCompleted ?? []), - }; - return ( - <> - - Lilypad Metrics Dashboard - Monitor the Lilypad Network! - - - - - - - - - - {/* + const { + data: metricsData, + isLoading: metricsIsLoading, + isError: metricsIsError, + } = useQuery({ + queryFn: fetchMetrics, + queryKey: ["metrics"], //Array according to Documentation + }); + const { + data: nodesData, + isLoading: nodesIsLoading, + isError: nodesIsError, + } = useQuery({ + queryFn: fetchNodes, + queryKey: ["nodes"], + }); + const timeData = { + Nodes: toChartData(metricsData?.Nodes ?? []), + JobsCompleted: toChartData(metricsData?.JobsCompleted ?? []), + }; + return ( + <> + + + Lilypad Metrics Dashboard - Monitor the Lilypad Network! + + + + + + + + + + + {/* */} -
- - {/* - {(["TotalJobs", "TotalNodes", "TotalModules"] as const).map( - (key, index) => { - const percentage = isLoading || isError ? 0 : 100; +
+ + {/* + {(["TotalJobs", "TotalNodes", "TotalModules"] as const).map( + (key, index) => { + const percentage = + metricsIsLoading || metricsIsError ? 0 : 100; - return ( - - {{ - badge: ( - 0 - ? arrowsArrowUp - : percentage === 0 - ? arrowsSwitchVertical01 - : arrowsArrowDown, - }} - badgeType="Pill color" - color={ - percentage > 0 - ? "success" - : percentage === 0 - ? "gray" - : "error" - } - size="md" - > - {isLoading ? "0" : isError ? "err" : percentage} - - ), - header: isLoading ? ( - - ) : isError ? ( - !err - ) : ( - {data?.[key]} - ), - }} - - ); - } - )} - - - {(["Nodes", "JobsCompleted"] as const).map((key, id) => { - return ( - -
- {isLoading || isError || data?.[key].length === 0 ? ( - - - - ) : ( - <> -
-
- {key === "Nodes" - ? m.metrics_active_nodes_chart_title() - : m.metrics_total_jobs_completed_chart_title()} -
-
-
- - - - - - - - - - DateTime.fromMillis(epochMillis).toFormat( - "MM yyyy" - ) - } - domain={["auto", "auto"]} - dataKey="epochMillis" - /> - - - - - -
-
- {m.metrics_dashboard_month_time_axis_label()} -
-
-
- - )} -
-
- ); - })} -
- - - - - */} -
- - ); + return ( + + {{ + badge: ( + 0 + ? arrowsArrowUp + : percentage === 0 + ? arrowsSwitchVertical01 + : arrowsArrowDown, + }} + badgeType="Pill color" + color={ + percentage > 0 + ? "success" + : percentage === 0 + ? "gray" + : "error" + } + size="md" + > + {metricsIsLoading + ? "0" + : metricsIsError + ? "err" + : percentage} + + ), + header: metricsIsLoading ? ( + + ) : metricsIsError ? ( + !err + ) : ( + {metricsData?.[key]} + ), + }} + + ); + } + )} +
+ + {(["Nodes", "JobsCompleted"] as const).map((key, id) => { + return ( + +
+ {metricsIsLoading || + metricsIsError || + metricsData?.[key].length === 0 ? ( + + + + ) : ( + <> +
+
+ {key === "Nodes" + ? m.metrics_active_nodes_chart_title() + : m.metrics_total_jobs_completed_chart_title()} +
+
+
+ + + + + + + + + + DateTime.fromMillis( + epochMillis + ).toFormat( + "MM yyyy" + ) + } + domain={[ + "auto", + "auto", + ]} + dataKey="epochMillis" + /> + + + + + +
+
+ {m.metrics_dashboard_month_time_axis_label()} +
+
+
+ + )} +
+
+ ); + })} +
*/} + + + {nodesIsLoading || + nodesIsError || + nodesData?.length === 0 ? ( + + + + ) : ( + + )} + + +
+ + ); } diff --git a/apps/info-dashboard/src/components/ActiveNodesWorldMap/ActiveNodesWorldMap.tsx b/apps/info-dashboard/src/components/ActiveNodesWorldMap/ActiveNodesWorldMap.tsx index 6a23b84..0fb1c7e 100644 --- a/apps/info-dashboard/src/components/ActiveNodesWorldMap/ActiveNodesWorldMap.tsx +++ b/apps/info-dashboard/src/components/ActiveNodesWorldMap/ActiveNodesWorldMap.tsx @@ -3,20 +3,10 @@ import type { FeatureCollection } from "geojson"; import { getStyle } from "./protomaps/style"; import { PropsWithChildren } from "react"; -const geojson: FeatureCollection = { - type: "FeatureCollection", - features: [ - { - type: "Feature", - properties: [], - geometry: { type: "Point", coordinates: [-122.4, 37.8] }, - }, - ], -}; - export default function ActiveNodesWorldMap({ protomapsApiKey, -}: PropsWithChildren<{ protomapsApiKey: string }>) { + geojson, +}: PropsWithChildren<{ protomapsApiKey: string; geojson: FeatureCollection }>) { return (
d.Latitude !== 0 || d.Longitude !== 0) + .map((d) => ({ + type: "Feature", + properties: [], + geometry: { + type: "Point", + coordinates: [d.Longitude, d.Latitude], + }, + })), + }; + return geojson; +}