diff --git a/src/App.jsx b/src/App.jsx index d157cce..f778a59 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -2513,6 +2513,7 @@ function ViewersPage({ viewers }) { function LocationSignalMap({ countries, locations }) { const mapRef = useRef(null) const markersRef = useRef(null) + const countryMarkerColor = '#e82517' const maxMarkerVisitors = Math.max( 1, ...countries.map((country) => Number(country.visitors || 0)), @@ -2602,7 +2603,82 @@ function LocationSignalMap({ countries, locations }) { return minRadius + normalized * (maxRadius - minRadius) } - countryMarkers.forEach((country) => { + const mapMarkers = cityMarkers.length ? cityMarkers : countryMarkers + mapMarkers.forEach((location) => { + const isCityMarker = cityMarkers.length > 0 + const radius = isCityMarker + ? scaleMarkerRadius(location.visitors, 5, 14) + : scaleMarkerRadius(location.visitors, 8, 24) + const tooltipPlace = isCityMarker ? location.label : location.label + L.circleMarker([location.lat, location.lon], { + color: countryMarkerColor, + fillColor: countryMarkerColor, + fillOpacity: 0.4, + opacity: 0, + radius, + stroke: false, + }) + .bindTooltip(`${tooltipPlace}: ${formatNumber(location.visitors)} visitors`, { + direction: 'top', + opacity: 0.95, + }) + .addTo(layer) + }) + }, [cityMarkers, countryMarkerColor, countryMarkers, maxMarkerVisitors]) + + return ( +
+
+
+
+ +
+ {topLocations.map((location) => ( +
+
+

{location.label}

+

{location.detail}

+
+

{formatNumber(location.visitors)}

+
+ ))} +
+ + {!countries.length && !locations.length ? ( +

+ No Cloudflare location signals have been shared yet. +

+ ) : null} +
+ ) +} + +function UptimePage({ uptime }) { + const [hoveredSnapshot, setHoveredSnapshot] = useState(null) + const checks = uptime.checks + const history = uptime.history + const operationalCount = checks.filter((check) => check.ok).length + const allOperational = checks.length > 0 && operationalCount === checks.length + const updatedAt = uptime.updatedAt ? dateFormat.format(new Date(uptime.updatedAt)) : 'Not checked yet' + const lastIssue = history.find((item) => item.status !== 'operational') + const uptimeSummary = uptime.summary || {} + const overview = [ + { + label: 'Live checks', + value: formatNumber(checks.length), + detail: allOperational ? 'all endpoints responding' : `${formatNumber(checks.length - operationalCount)} need attention`, + }, + { + label: '7 day uptime', + value: `${Math.round(Number(uptimeSummary.uptime_percent_7d || 0))}%`, + detail: `${formatNumber(uptimeSummary.samples_7d || 0)} retained probes`, + }, + { + label: 'Last issue', + value: lastIssue ? shortDateFormat.format(new Date(lastIssue.checked_at)) : 'None', + detail: lastIssue ? `${lastIssue.status} on ${lastIssue.target}` : 'no stored incidents', + }, + ] const radius = scaleMarkerRadius(country.visitors, 8, 24) L.circleMarker([country.lat, country.lon], { color: '#e82517',