feat: display screen resolution, content stats, and advanced metrics on dashboard
This commit is contained in:
@@ -3,11 +3,19 @@ import apiRequest from './client'
|
||||
export interface Stats {
|
||||
pageviews: number
|
||||
visitors: number
|
||||
bounce_rate: number
|
||||
avg_duration: number
|
||||
}
|
||||
|
||||
export interface TopPage {
|
||||
path: string
|
||||
pageviews: number
|
||||
visits?: number // For entry/exit pages
|
||||
}
|
||||
|
||||
export interface ScreenResolutionStat {
|
||||
screen_resolution: string
|
||||
pageviews: number
|
||||
}
|
||||
|
||||
export interface TopReferrer {
|
||||
@@ -139,3 +147,26 @@ export async function getDailyStats(siteId: string, startDate?: string, endDate?
|
||||
if (endDate) params.append('end_date', endDate)
|
||||
return apiRequest<{ stats: DailyStat[] }>(`/sites/${siteId}/daily?${params.toString()}`).then(r => r?.stats || [])
|
||||
}
|
||||
export async function getEntryPages(siteId: string, startDate?: string, endDate?: string, limit = 10): Promise<TopPage[]> {
|
||||
const params = new URLSearchParams()
|
||||
if (startDate) params.append('start_date', startDate)
|
||||
if (endDate) params.append('end_date', endDate)
|
||||
params.append('limit', limit.toString())
|
||||
return apiRequest<{ pages: TopPage[] }>(`/sites/${siteId}/entry-pages?${params.toString()}`).then(r => r?.pages || [])
|
||||
}
|
||||
|
||||
export async function getExitPages(siteId: string, startDate?: string, endDate?: string, limit = 10): Promise<TopPage[]> {
|
||||
const params = new URLSearchParams()
|
||||
if (startDate) params.append('start_date', startDate)
|
||||
if (endDate) params.append('end_date', endDate)
|
||||
params.append('limit', limit.toString())
|
||||
return apiRequest<{ pages: TopPage[] }>(`/sites/${siteId}/exit-pages?${params.toString()}`).then(r => r?.pages || [])
|
||||
}
|
||||
|
||||
export async function getScreenResolutions(siteId: string, startDate?: string, endDate?: string, limit = 10): Promise<ScreenResolutionStat[]> {
|
||||
const params = new URLSearchParams()
|
||||
if (startDate) params.append('start_date', startDate)
|
||||
if (endDate) params.append('end_date', endDate)
|
||||
params.append('limit', limit.toString())
|
||||
return apiRequest<{ screen_resolutions: ScreenResolutionStat[] }>(`/sites/${siteId}/screen-resolutions?${params.toString()}`).then(r => r?.screen_resolutions || [])
|
||||
}
|
||||
|
||||
23
lib/api/stats_extra.ts
Normal file
23
lib/api/stats_extra.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
export async function getEntryPages(siteId: string, startDate?: string, endDate?: string, limit = 10): Promise<TopPage[]> {
|
||||
const params = new URLSearchParams()
|
||||
if (startDate) params.append('start_date', startDate)
|
||||
if (endDate) params.append('end_date', endDate)
|
||||
params.append('limit', limit.toString())
|
||||
return apiRequest<{ pages: TopPage[] }>(`/sites/${siteId}/entry-pages?${params.toString()}`).then(r => r?.pages || [])
|
||||
}
|
||||
|
||||
export async function getExitPages(siteId: string, startDate?: string, endDate?: string, limit = 10): Promise<TopPage[]> {
|
||||
const params = new URLSearchParams()
|
||||
if (startDate) params.append('start_date', startDate)
|
||||
if (endDate) params.append('end_date', endDate)
|
||||
params.append('limit', limit.toString())
|
||||
return apiRequest<{ pages: TopPage[] }>(`/sites/${siteId}/exit-pages?${params.toString()}`).then(r => r?.pages || [])
|
||||
}
|
||||
|
||||
export async function getScreenResolutions(siteId: string, startDate?: string, endDate?: string, limit = 10): Promise<ScreenResolutionStat[]> {
|
||||
const params = new URLSearchParams()
|
||||
if (startDate) params.append('start_date', startDate)
|
||||
if (endDate) params.append('end_date', endDate)
|
||||
params.append('limit', limit.toString())
|
||||
return apiRequest<{ screen_resolutions: ScreenResolutionStat[] }>(`/sites/${siteId}/screen-resolutions?${params.toString()}`).then(r => r?.screen_resolutions || [])
|
||||
}
|
||||
@@ -42,3 +42,17 @@ export function formatRelativeTime(date: string | Date): string {
|
||||
if (minutes > 0) return `${minutes} minute${minutes > 1 ? 's' : ''} ago`
|
||||
return 'Just now'
|
||||
}
|
||||
/**
|
||||
* Format duration in seconds to "1m 30s" or "30s"
|
||||
*/
|
||||
export function formatDuration(seconds: number): string {
|
||||
if (!seconds) return '0s'
|
||||
|
||||
const m = Math.floor(seconds / 60)
|
||||
const s = Math.floor(seconds % 60)
|
||||
|
||||
if (m > 0) {
|
||||
return `${m}m ${s}s`
|
||||
}
|
||||
return `${s}s`
|
||||
}
|
||||
|
||||
14
lib/utils/format_extra.ts
Normal file
14
lib/utils/format_extra.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Format duration in seconds to "1m 30s" or "30s"
|
||||
*/
|
||||
export function formatDuration(seconds: number): string {
|
||||
if (!seconds) return '0s'
|
||||
|
||||
const m = Math.floor(seconds / 60)
|
||||
const s = Math.floor(seconds % 60)
|
||||
|
||||
if (m > 0) {
|
||||
return `${m}m ${s}s`
|
||||
}
|
||||
return `${s}s`
|
||||
}
|
||||
Reference in New Issue
Block a user