Release 0.14.0-alpha #42

Merged
uz1mani merged 109 commits from staging into main 2026-03-12 12:12:03 +00:00
53 changed files with 5866 additions and 1201 deletions
Showing only changes of commit 5f797112ec - Show all commits

View File

@@ -201,7 +201,7 @@ export default function Chart({
// ─── Data ────────────────────────────────────────────────────────── // ─── Data ──────────────────────────────────────────────────────────
const chartData = data.map((item) => { const chartData = useMemo(() => data.map((item) => {
let formattedDate: string let formattedDate: string
if (interval === 'minute') { if (interval === 'minute') {
formattedDate = new Date(item.date).toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }) formattedDate = new Date(item.date).toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' })
@@ -223,7 +223,7 @@ export default function Chart({
bounce_rate: item.bounce_rate, bounce_rate: item.bounce_rate,
avg_duration: item.avg_duration, avg_duration: item.avg_duration,
} }
}) }), [data, interval])
const annotationMarkers = useMemo(() => { const annotationMarkers = useMemo(() => {
if (!annotations?.length) return [] if (!annotations?.length) return []
@@ -298,7 +298,7 @@ export default function Chart({
// ─── Metrics with trends ────────────────────────────────────────── // ─── Metrics with trends ──────────────────────────────────────────
const metricsWithTrends = METRIC_CONFIGS.map((m) => { const metricsWithTrends = useMemo(() => METRIC_CONFIGS.map((m) => {
const value = stats[m.key] const value = stats[m.key]
const previousValue = prevStats?.[m.key] const previousValue = prevStats?.[m.key]
const change = previousValue != null && previousValue > 0 const change = previousValue != null && previousValue > 0
@@ -313,7 +313,7 @@ export default function Chart({
change, change,
isPositive, isPositive,
} }
}) }), [stats, prevStats])
const hasData = data.length > 0 const hasData = data.length > 0
const hasAnyNonZero = hasData && chartData.some((d) => (d[metric] as number) > 0 const hasAnyNonZero = hasData && chartData.some((d) => (d[metric] as number) > 0

View File

@@ -1,6 +1,6 @@
'use client' 'use client'
import { useEffect, useRef } from 'react' import { useEffect, useMemo, useRef } from 'react'
import createGlobe from 'cobe' import createGlobe from 'cobe'
import { useTheme } from '@ciphera-net/ui' import { useTheme } from '@ciphera-net/ui'
import { countryCentroids } from '@/lib/country-centroids' import { countryCentroids } from '@/lib/country-centroids'
@@ -22,16 +22,19 @@ export default function Globe({ data, className }: GlobeProps) {
// Update refs without causing effect re-runs // Update refs without causing effect re-runs
isDarkRef.current = resolvedTheme === 'dark' isDarkRef.current = resolvedTheme === 'dark'
// Compute markers into ref // Compute markers into ref (memoized to avoid recalculating on every render)
const max = data.length ? Math.max(...data.map((d) => d.pageviews)) : 0 const markers = useMemo(() => {
markersRef.current = max > 0 const max = data.length ? Math.max(...data.map((d) => d.pageviews)) : 0
? data return max > 0
.filter((d) => d.country && d.country !== 'Unknown' && countryCentroids[d.country]) ? data
.map((d) => ({ .filter((d) => d.country && d.country !== 'Unknown' && countryCentroids[d.country])
location: [countryCentroids[d.country].lat, countryCentroids[d.country].lng] as [number, number], .map((d) => ({
size: 0.03 + (d.pageviews / max) * 0.12, location: [countryCentroids[d.country].lat, countryCentroids[d.country].lng] as [number, number],
})) size: 0.03 + (d.pageviews / max) * 0.12,
: [] }))
: []
}, [data])
markersRef.current = markers
useEffect(() => { useEffect(() => {
if (!canvasRef.current) return if (!canvasRef.current) return