Analytics: 3-tab layout + fix geographic data loss; v1.1.34
Splits the analytics panel into Traffic / Engagement / System tabs so episode plays, engagement metrics, and contact/study data are no longer buried under the visitor log. Fixes a bug where topCountries, topStates, topCities, device breakdown, and referrers were computed from only the 100 most-recent visitor rows instead of all rows in the selected range — causing older geographic data (e.g. visits from India, Texas, Georgia) to silently disappear from the aggregate totals. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -78,6 +78,7 @@ export function AnalyticsPanel({
|
||||
onDeployHook,
|
||||
onRefreshStatus,
|
||||
}: Props) {
|
||||
const [panelTab, setPanelTab] = useState<'traffic' | 'engagement' | 'system'>('traffic')
|
||||
const [chartTab, setChartTab] = useState<'overview' | 'breakdown' | 'geographic' | 'referrers'>('overview')
|
||||
const [expandedVisitor, setExpandedVisitor] = useState<string | null>(null)
|
||||
const [fullBackupFile, setFullBackupFile] = useState<File | null>(null)
|
||||
@@ -245,6 +246,14 @@ export function AnalyticsPanel({
|
||||
<p>Real-time insights into site traffic, bot detection, visitor behavior, and data management.</p>
|
||||
</div>
|
||||
|
||||
{/* Top-level panel tabs */}
|
||||
<div className="admin-tabs admin-tabs--charts" style={{ marginBottom: '1.5rem' }}>
|
||||
<button type="button" className={`admin-tab${panelTab === 'traffic' ? ' admin-tab--active' : ''}`} onClick={() => setPanelTab('traffic')}>Traffic</button>
|
||||
<button type="button" className={`admin-tab${panelTab === 'engagement' ? ' admin-tab--active' : ''}`} onClick={() => setPanelTab('engagement')}>Engagement</button>
|
||||
<button type="button" className={`admin-tab${panelTab === 'system' ? ' admin-tab--active' : ''}`} onClick={() => setPanelTab('system')}>System</button>
|
||||
</div>
|
||||
|
||||
{panelTab === 'traffic' && (<>
|
||||
{/* Time-range tabs */}
|
||||
{onRangeChange && (
|
||||
<div style={{ display: 'flex', gap: '0.5rem', marginBottom: '1.5rem', flexWrap: 'wrap' }}>
|
||||
@@ -523,6 +532,9 @@ export function AnalyticsPanel({
|
||||
)}
|
||||
</div>
|
||||
|
||||
</>)}
|
||||
|
||||
{panelTab === 'engagement' && (<>
|
||||
{/* Episode Plays */}
|
||||
{stats.episodePlays && stats.episodePlays.length > 0 && (
|
||||
<>
|
||||
@@ -790,6 +802,9 @@ export function AnalyticsPanel({
|
||||
</>
|
||||
)}
|
||||
|
||||
</>)}
|
||||
|
||||
{panelTab === 'system' && (<>
|
||||
{/* Deployment & Cache Status */}
|
||||
<div className="admin-stats-head admin-stats-head--visitors">
|
||||
<h2>Deployment & Cache Status</h2>
|
||||
@@ -872,6 +887,7 @@ export function AnalyticsPanel({
|
||||
</button>
|
||||
</div>
|
||||
{maintenanceMsg && <p className="admin-stats-note">{maintenanceMsg}</p>}
|
||||
</>)}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user