update viewers page

This commit is contained in:
Heidi
2026-05-16 08:13:13 +01:00
parent 752b5f9eb8
commit bcade3392f
+52 -13
View File
@@ -2265,7 +2265,6 @@ function ViewersPage({ viewers }) {
const activePages = data.active_pages || []
const activity24h = filledLast24Hours(data.activity_24h || [])
const activity30d = filledLast30Days(data.activity_30d || [])
const dataTypes = data.data_types || []
const totals = data.totals || {}
const generatedAt = data.generated_at ? dateFormat.format(new Date(data.generated_at)) : 'Waiting for data'
const periods = {
@@ -2326,7 +2325,7 @@ function ViewersPage({ viewers }) {
{Object.entries(periods).map(([key, period]) => (
<button
className={`rounded px-3 py-1.5 transition ${
analyticsWindow === key ? 'bg-fury-red text-bg shadow-sm' : 'text-text-soft hover:text-text'
analyticsWindow === key ? 'bg-fury-red text-fury-violet shadow-sm' : 'text-text-soft hover:text-text'
}`}
key={key}
onClick={() => setAnalyticsWindow(key)}
@@ -2489,18 +2488,10 @@ function ViewersPage({ viewers }) {
<div className="grid gap-6 xl:grid-cols-[0.9fr_1.1fr]">
<div className="rounded-lg border border-border bg-fury-white shadow-sm">
<div className="border-b border-surface px-5 py-4">
<h2 className="text-lg font-semibold">Collected data types</h2>
<p className="mt-1 text-sm text-text-soft">
Optional fields only appear for visitors who explicitly allow them
</p>
<h2 className="text-lg font-semibold">Locations</h2>
<p className="mt-1 text-sm text-text-soft">Cities and locations seen over {periodData.title.toLowerCase()}</p>
</div>
{dataTypes.map((item) => (
<div className="border-b border-surface px-5 py-3 text-sm" key={item.key}>
<p className="font-semibold">{item.label}</p>
<p className="mt-1 text-text-soft">{item.detail}</p>
</div>
))}
{!dataTypes.length ? <p className="px-5 py-10 text-sm text-text-soft">No collection manifest returned</p> : null}
<LocationSignalTable countries={periodData.countries} locations={periodData.locations} />
</div>
<div className="rounded-lg border border-border bg-fury-white shadow-sm">
@@ -2522,6 +2513,54 @@ function ViewersPage({ viewers }) {
)
}
function LocationSignalTable({ countries, locations }) {
const rows = locations.length
? locations.map((location) => ({
key: `${location.country}-${location.region}-${location.city}-${location.latitude}-${location.longitude}-${location.timezone}`,
place: location.city || location.region || location.timezone || 'Unknown city',
region: location.region || 'Not shared',
country: countryNames[location.country] || location.country || 'Not shared',
visitors: location.visitors,
events: location.events,
}))
: countries.map((country) => ({
key: country.country,
place: countryNames[country.country] || country.country || 'Unknown country',
region: 'Country signal',
country: countryNames[country.country] || country.country || 'Not shared',
visitors: country.visitors,
events: country.events,
}))
return (
<div className="overflow-x-auto">
<table className="w-full min-w-[520px] text-left text-sm">
<thead className="border-b border-surface text-xs uppercase tracking-wide text-text-soft">
<tr>
<th className="px-5 py-3 font-semibold">City/location</th>
<th className="px-5 py-3 font-semibold">Region</th>
<th className="px-5 py-3 font-semibold">Country</th>
<th className="px-5 py-3 text-right font-semibold">Visitors</th>
<th className="px-5 py-3 text-right font-semibold">Events</th>
</tr>
</thead>
<tbody>
{rows.map((row) => (
<tr className="border-b border-surface" key={row.key}>
<td className="px-5 py-3 font-semibold">{row.place}</td>
<td className="px-5 py-3 text-text-soft">{row.region}</td>
<td className="px-5 py-3 text-text-soft">{row.country}</td>
<td className="px-5 py-3 text-right font-semibold text-fury-cyan">{formatNumber(row.visitors)}</td>
<td className="px-5 py-3 text-right text-text-soft">{formatNumber(row.events)}</td>
</tr>
))}
</tbody>
</table>
{!rows.length ? <p className="px-5 py-10 text-sm text-text-soft">No location data recorded yet</p> : null}
</div>
)
}
function LocationSignalMap({ countries, locations }) {
const mapRef = useRef(null)
const markersRef = useRef(null)