Release 0.13.0-alpha #39
@@ -8,6 +8,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|||||||
|
|
||||||
### Improved
|
### Improved
|
||||||
|
|
||||||
|
- **Cleaner internal API code.** The analytics data-fetching layer has been streamlined — 13 near-identical endpoint functions were consolidated using a shared pattern, cutting roughly half the code while keeping every feature working exactly as before. This makes it easier to add new analytics endpoints in the future and reduces the chance of inconsistencies between them.
|
||||||
|
|
||||||
- **More reliable list rendering across the dashboard.** Pages, referrers, locations, devices, funnels, and other data lists now use stable identifiers (like page paths and referrer URLs) instead of array positions as their React keys. This prevents potential display glitches — such as stale data appearing in the wrong row — when lists are filtered, sorted, or updated in real time.
|
- **More reliable list rendering across the dashboard.** Pages, referrers, locations, devices, funnels, and other data lists now use stable identifiers (like page paths and referrer URLs) instead of array positions as their React keys. This prevents potential display glitches — such as stale data appearing in the wrong row — when lists are filtered, sorted, or updated in real time.
|
||||||
- **Deleting a site now fully cleans up all its data.** Previously, deleting a site removed the site record but could leave behind orphaned analytics events in the database, slowly accumulating unused data. Now all events are cleaned up automatically in small batches before the site is removed, keeping your database tidy.
|
- **Deleting a site now fully cleans up all its data.** Previously, deleting a site removed the site record but could leave behind orphaned analytics events in the database, slowly accumulating unused data. Now all events are cleaned up automatically in small batches before the site is removed, keeping your database tidy.
|
||||||
|
|
||||||
|
|||||||
541
lib/api/stats.ts
541
lib/api/stats.ts
@@ -1,6 +1,8 @@
|
|||||||
import apiRequest from './client'
|
import apiRequest from './client'
|
||||||
import { Site } from './sites'
|
import { Site } from './sites'
|
||||||
|
|
||||||
|
// ─── Types ──────────────────────────────────────────────────────────
|
||||||
|
|
||||||
export interface Stats {
|
export interface Stats {
|
||||||
pageviews: number
|
pageviews: number
|
||||||
visitors: number
|
visitors: number
|
||||||
@@ -11,7 +13,7 @@ export interface Stats {
|
|||||||
export interface TopPage {
|
export interface TopPage {
|
||||||
path: string
|
path: string
|
||||||
pageviews: number
|
pageviews: number
|
||||||
visits?: number // For entry/exit pages
|
visits?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ScreenResolutionStat {
|
export interface ScreenResolutionStat {
|
||||||
@@ -101,6 +103,8 @@ export interface AuthParams {
|
|||||||
captcha?: { captcha_id?: string, captcha_solution?: string, captcha_token?: string }
|
captcha?: { captcha_id?: string, captcha_solution?: string, captcha_token?: string }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─── Helpers ────────────────────────────────────────────────────────
|
||||||
|
|
||||||
function appendAuthParams(params: URLSearchParams, auth?: AuthParams) {
|
function appendAuthParams(params: URLSearchParams, auth?: AuthParams) {
|
||||||
if (auth?.password) params.append('password', auth.password)
|
if (auth?.password) params.append('password', auth.password)
|
||||||
if (auth?.captcha?.captcha_id) params.append('captcha_id', auth.captcha.captcha_id)
|
if (auth?.captcha?.captcha_id) params.append('captcha_id', auth.captcha.captcha_id)
|
||||||
@@ -108,198 +112,115 @@ function appendAuthParams(params: URLSearchParams, auth?: AuthParams) {
|
|||||||
if (auth?.captcha?.captcha_token) params.append('captcha_token', auth.captcha.captcha_token)
|
if (auth?.captcha?.captcha_token) params.append('captcha_token', auth.captcha.captcha_token)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getStats(siteId: string, startDate?: string, endDate?: string): Promise<Stats> {
|
function buildQuery(
|
||||||
|
opts: {
|
||||||
|
startDate?: string
|
||||||
|
endDate?: string
|
||||||
|
limit?: number
|
||||||
|
interval?: string
|
||||||
|
countryLimit?: number
|
||||||
|
sort?: string
|
||||||
|
},
|
||||||
|
auth?: AuthParams
|
||||||
|
): string {
|
||||||
const params = new URLSearchParams()
|
const params = new URLSearchParams()
|
||||||
if (startDate) params.append('start_date', startDate)
|
if (opts.startDate) params.append('start_date', opts.startDate)
|
||||||
if (endDate) params.append('end_date', endDate)
|
if (opts.endDate) params.append('end_date', opts.endDate)
|
||||||
|
if (opts.limit != null) params.append('limit', opts.limit.toString())
|
||||||
|
if (opts.interval) params.append('interval', opts.interval)
|
||||||
|
if (opts.countryLimit != null) params.append('country_limit', opts.countryLimit.toString())
|
||||||
|
if (opts.sort) params.append('sort', opts.sort)
|
||||||
|
if (auth) appendAuthParams(params, auth)
|
||||||
const query = params.toString()
|
const query = params.toString()
|
||||||
return apiRequest<Stats>(`/sites/${siteId}/stats${query ? `?${query}` : ''}`)
|
return query ? `?${query}` : ''
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getPublicStats(siteId: string, startDate?: string, endDate?: string, auth?: AuthParams): Promise<Stats> {
|
/** Factory for endpoints that return an array nested under a response key. */
|
||||||
const params = new URLSearchParams()
|
function createListFetcher<T>(path: string, field: string, defaultLimit = 10) {
|
||||||
if (startDate) params.append('start_date', startDate)
|
return (siteId: string, startDate?: string, endDate?: string, limit = defaultLimit): Promise<T[]> =>
|
||||||
if (endDate) params.append('end_date', endDate)
|
apiRequest<Record<string, T[]>>(`/sites/${siteId}/${path}${buildQuery({ startDate, endDate, limit })}`)
|
||||||
appendAuthParams(params, auth)
|
.then(r => r?.[field] || [])
|
||||||
const query = params.toString()
|
|
||||||
return apiRequest<Stats>(`/public/sites/${siteId}/stats${query ? `?${query}` : ''}`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getRealtime(siteId: string): Promise<RealtimeStats> {
|
// ─── List Endpoints ─────────────────────────────────────────────────
|
||||||
|
|
||||||
|
export const getTopPages = createListFetcher<TopPage>('pages', 'pages')
|
||||||
|
export const getTopReferrers = createListFetcher<TopReferrer>('referrers', 'referrers')
|
||||||
|
export const getCountries = createListFetcher<CountryStat>('countries', 'countries')
|
||||||
|
export const getCities = createListFetcher<CityStat>('cities', 'cities')
|
||||||
|
export const getRegions = createListFetcher<RegionStat>('regions', 'regions')
|
||||||
|
export const getBrowsers = createListFetcher<BrowserStat>('browsers', 'browsers')
|
||||||
|
export const getOS = createListFetcher<OSStat>('os', 'os')
|
||||||
|
export const getDevices = createListFetcher<DeviceStat>('devices', 'devices')
|
||||||
|
export const getEntryPages = createListFetcher<TopPage>('entry-pages', 'pages')
|
||||||
|
export const getExitPages = createListFetcher<TopPage>('exit-pages', 'pages')
|
||||||
|
export const getScreenResolutions = createListFetcher<ScreenResolutionStat>('screen-resolutions', 'screen_resolutions')
|
||||||
|
export const getGoalStats = createListFetcher<GoalCountStat>('goals/stats', 'goal_counts', 20)
|
||||||
|
export const getCampaigns = createListFetcher<CampaignStat>('campaigns', 'campaigns')
|
||||||
|
|
||||||
|
// ─── Stats & Realtime ───────────────────────────────────────────────
|
||||||
|
|
||||||
|
export function getStats(siteId: string, startDate?: string, endDate?: string): Promise<Stats> {
|
||||||
|
return apiRequest<Stats>(`/sites/${siteId}/stats${buildQuery({ startDate, endDate })}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPublicStats(siteId: string, startDate?: string, endDate?: string, auth?: AuthParams): Promise<Stats> {
|
||||||
|
return apiRequest<Stats>(`/public/sites/${siteId}/stats${buildQuery({ startDate, endDate }, auth)}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getRealtime(siteId: string): Promise<RealtimeStats> {
|
||||||
return apiRequest<RealtimeStats>(`/sites/${siteId}/realtime`)
|
return apiRequest<RealtimeStats>(`/sites/${siteId}/realtime`)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getPublicRealtime(siteId: string, auth?: AuthParams): Promise<RealtimeStats> {
|
export function getPublicRealtime(siteId: string, auth?: AuthParams): Promise<RealtimeStats> {
|
||||||
const params = new URLSearchParams()
|
return apiRequest<RealtimeStats>(`/public/sites/${siteId}/realtime${buildQuery({}, auth)}`)
|
||||||
appendAuthParams(params, auth)
|
|
||||||
return apiRequest<RealtimeStats>(`/public/sites/${siteId}/realtime?${params.toString()}`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getTopPages(siteId: string, startDate?: string, endDate?: string, limit = 10): Promise<TopPage[]> {
|
// ─── Daily Stats ────────────────────────────────────────────────────
|
||||||
const params = new URLSearchParams()
|
|
||||||
if (startDate) params.append('start_date', startDate)
|
export function getDailyStats(siteId: string, startDate?: string, endDate?: string, interval?: string): Promise<DailyStat[]> {
|
||||||
if (endDate) params.append('end_date', endDate)
|
return apiRequest<{ stats: DailyStat[] }>(`/sites/${siteId}/daily${buildQuery({ startDate, endDate, interval })}`)
|
||||||
params.append('limit', limit.toString())
|
.then(r => r?.stats || [])
|
||||||
return apiRequest<{ pages: TopPage[] }>(`/sites/${siteId}/pages?${params.toString()}`).then(r => r?.pages || [])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getTopReferrers(siteId: string, startDate?: string, endDate?: string, limit = 10): Promise<TopReferrer[]> {
|
export function getPublicDailyStats(siteId: string, startDate?: string, endDate?: string, interval?: string, auth?: AuthParams): Promise<DailyStat[]> {
|
||||||
const params = new URLSearchParams()
|
return apiRequest<{ stats: DailyStat[] }>(`/public/sites/${siteId}/daily${buildQuery({ startDate, endDate, interval }, auth)}`)
|
||||||
if (startDate) params.append('start_date', startDate)
|
.then(r => r?.stats || [])
|
||||||
if (endDate) params.append('end_date', endDate)
|
|
||||||
params.append('limit', limit.toString())
|
|
||||||
return apiRequest<{ referrers: TopReferrer[] }>(`/sites/${siteId}/referrers?${params.toString()}`).then(r => r?.referrers || [])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCountries(siteId: string, startDate?: string, endDate?: string, limit = 10): Promise<CountryStat[]> {
|
// ─── Public Campaigns ───────────────────────────────────────────────
|
||||||
const params = new URLSearchParams()
|
|
||||||
if (startDate) params.append('start_date', startDate)
|
export function getPublicCampaigns(siteId: string, startDate?: string, endDate?: string, limit = 10, auth?: AuthParams): Promise<CampaignStat[]> {
|
||||||
if (endDate) params.append('end_date', endDate)
|
return apiRequest<{ campaigns: CampaignStat[] }>(`/public/sites/${siteId}/campaigns${buildQuery({ startDate, endDate, limit }, auth)}`)
|
||||||
params.append('limit', limit.toString())
|
.then(r => r?.campaigns || [])
|
||||||
return apiRequest<{ countries: CountryStat[] }>(`/sites/${siteId}/countries?${params.toString()}`).then(r => r?.countries || [])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCities(siteId: string, startDate?: string, endDate?: string, limit = 10): Promise<CityStat[]> {
|
// ─── Performance By Page ────────────────────────────────────────────
|
||||||
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<{ cities: CityStat[] }>(`/sites/${siteId}/cities?${params.toString()}`).then(r => r?.cities || [])
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getRegions(siteId: string, startDate?: string, endDate?: string, limit = 10): Promise<RegionStat[]> {
|
export function getPerformanceByPage(
|
||||||
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<{ regions: RegionStat[] }>(`/sites/${siteId}/regions?${params.toString()}`).then(r => r?.regions || [])
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getBrowsers(siteId: string, startDate?: string, endDate?: string, limit = 10): Promise<BrowserStat[]> {
|
|
||||||
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<{ browsers: BrowserStat[] }>(`/sites/${siteId}/browsers?${params.toString()}`).then(r => r?.browsers || [])
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getOS(siteId: string, startDate?: string, endDate?: string, limit = 10): Promise<OSStat[]> {
|
|
||||||
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<{ os: OSStat[] }>(`/sites/${siteId}/os?${params.toString()}`).then(r => r?.os || [])
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getDevices(siteId: string, startDate?: string, endDate?: string, limit = 10): Promise<DeviceStat[]> {
|
|
||||||
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<{ devices: DeviceStat[] }>(`/sites/${siteId}/devices?${params.toString()}`).then(r => r?.devices || [])
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getDailyStats(siteId: string, startDate?: string, endDate?: string, interval?: string): Promise<DailyStat[]> {
|
|
||||||
const params = new URLSearchParams()
|
|
||||||
if (startDate) params.append('start_date', startDate)
|
|
||||||
if (endDate) params.append('end_date', endDate)
|
|
||||||
if (interval) params.append('interval', interval)
|
|
||||||
return apiRequest<{ stats: DailyStat[] }>(`/sites/${siteId}/daily?${params.toString()}`).then(r => r?.stats || [])
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getPublicDailyStats(siteId: string, startDate?: string, endDate?: string, interval?: string, auth?: AuthParams): Promise<DailyStat[]> {
|
|
||||||
const params = new URLSearchParams()
|
|
||||||
if (startDate) params.append('start_date', startDate)
|
|
||||||
if (endDate) params.append('end_date', endDate)
|
|
||||||
if (interval) params.append('interval', interval)
|
|
||||||
appendAuthParams(params, auth)
|
|
||||||
return apiRequest<{ stats: DailyStat[] }>(`/public/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 || [])
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getPerformanceByPage(
|
|
||||||
siteId: string,
|
siteId: string,
|
||||||
startDate?: string,
|
startDate?: string,
|
||||||
endDate?: string,
|
endDate?: string,
|
||||||
opts?: { limit?: number; sort?: 'lcp' | 'cls' | 'inp' }
|
opts?: { limit?: number; sort?: 'lcp' | 'cls' | 'inp' }
|
||||||
): Promise<PerformanceByPageStat[]> {
|
): Promise<PerformanceByPageStat[]> {
|
||||||
const params = new URLSearchParams()
|
return apiRequest<{ performance_by_page: PerformanceByPageStat[] }>(
|
||||||
if (startDate) params.append('start_date', startDate)
|
`/sites/${siteId}/performance-by-page${buildQuery({ startDate, endDate, limit: opts?.limit, sort: opts?.sort })}`
|
||||||
if (endDate) params.append('end_date', endDate)
|
).then(r => r?.performance_by_page ?? [])
|
||||||
if (opts?.limit != null) params.append('limit', String(opts.limit))
|
|
||||||
if (opts?.sort) params.append('sort', opts.sort)
|
|
||||||
const res = await apiRequest<{ performance_by_page: PerformanceByPageStat[] }>(
|
|
||||||
`/sites/${siteId}/performance-by-page?${params.toString()}`
|
|
||||||
)
|
|
||||||
return res?.performance_by_page ?? []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getPublicPerformanceByPage(
|
export function getPublicPerformanceByPage(
|
||||||
siteId: string,
|
siteId: string,
|
||||||
startDate?: string,
|
startDate?: string,
|
||||||
endDate?: string,
|
endDate?: string,
|
||||||
opts?: { limit?: number; sort?: 'lcp' | 'cls' | 'inp' },
|
opts?: { limit?: number; sort?: 'lcp' | 'cls' | 'inp' },
|
||||||
auth?: AuthParams
|
auth?: AuthParams
|
||||||
): Promise<PerformanceByPageStat[]> {
|
): Promise<PerformanceByPageStat[]> {
|
||||||
const params = new URLSearchParams()
|
return apiRequest<{ performance_by_page: PerformanceByPageStat[] }>(
|
||||||
if (startDate) params.append('start_date', startDate)
|
`/public/sites/${siteId}/performance-by-page${buildQuery({ startDate, endDate, limit: opts?.limit, sort: opts?.sort }, auth)}`
|
||||||
if (endDate) params.append('end_date', endDate)
|
).then(r => r?.performance_by_page ?? [])
|
||||||
if (opts?.limit != null) params.append('limit', String(opts.limit))
|
|
||||||
if (opts?.sort) params.append('sort', opts.sort)
|
|
||||||
appendAuthParams(params, auth)
|
|
||||||
const res = await apiRequest<{ performance_by_page: PerformanceByPageStat[] }>(
|
|
||||||
`/public/sites/${siteId}/performance-by-page?${params.toString()}`
|
|
||||||
)
|
|
||||||
return res?.performance_by_page ?? []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getGoalStats(siteId: string, startDate?: string, endDate?: string, limit = 20): Promise<GoalCountStat[]> {
|
// ─── Full Dashboard ─────────────────────────────────────────────────
|
||||||
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<{ goal_counts: GoalCountStat[] }>(`/sites/${siteId}/goals/stats?${params.toString()}`).then(r => r?.goal_counts || [])
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getCampaigns(siteId: string, startDate?: string, endDate?: string, limit = 10): Promise<CampaignStat[]> {
|
|
||||||
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<{ campaigns: CampaignStat[] }>(`/sites/${siteId}/campaigns?${params.toString()}`).then(r => r?.campaigns || [])
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getPublicCampaigns(siteId: string, startDate?: string, endDate?: string, limit = 10, auth?: AuthParams): Promise<CampaignStat[]> {
|
|
||||||
const params = new URLSearchParams()
|
|
||||||
if (startDate) params.append('start_date', startDate)
|
|
||||||
if (endDate) params.append('end_date', endDate)
|
|
||||||
params.append('limit', limit.toString())
|
|
||||||
appendAuthParams(params, auth)
|
|
||||||
return apiRequest<{ campaigns: CampaignStat[] }>(`/public/sites/${siteId}/campaigns?${params.toString()}`).then(r => r?.campaigns || [])
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DashboardData {
|
export interface DashboardData {
|
||||||
site: Site
|
site: Site
|
||||||
@@ -322,16 +243,11 @@ export interface DashboardData {
|
|||||||
goal_counts?: GoalCountStat[]
|
goal_counts?: GoalCountStat[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getDashboard(siteId: string, startDate?: string, endDate?: string, limit = 10, interval?: string): Promise<DashboardData> {
|
export function getDashboard(siteId: string, startDate?: string, endDate?: string, limit = 10, interval?: string): Promise<DashboardData> {
|
||||||
const params = new URLSearchParams()
|
return apiRequest<DashboardData>(`/sites/${siteId}/dashboard${buildQuery({ startDate, endDate, limit, interval })}`)
|
||||||
if (startDate) params.append('start_date', startDate)
|
|
||||||
if (endDate) params.append('end_date', endDate)
|
|
||||||
if (interval) params.append('interval', interval)
|
|
||||||
params.append('limit', limit.toString())
|
|
||||||
return apiRequest<DashboardData>(`/sites/${siteId}/dashboard?${params.toString()}`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getPublicDashboard(
|
export function getPublicDashboard(
|
||||||
siteId: string,
|
siteId: string,
|
||||||
startDate?: string,
|
startDate?: string,
|
||||||
endDate?: string,
|
endDate?: string,
|
||||||
@@ -340,21 +256,12 @@ export async function getPublicDashboard(
|
|||||||
password?: string,
|
password?: string,
|
||||||
captcha?: { captcha_id?: string, captcha_solution?: string, captcha_token?: string }
|
captcha?: { captcha_id?: string, captcha_solution?: string, captcha_token?: string }
|
||||||
): Promise<DashboardData> {
|
): Promise<DashboardData> {
|
||||||
const params = new URLSearchParams()
|
return apiRequest<DashboardData>(
|
||||||
if (startDate) params.append('start_date', startDate)
|
`/public/sites/${siteId}/dashboard${buildQuery({ startDate, endDate, limit, interval }, { password, captcha })}`
|
||||||
if (endDate) params.append('end_date', endDate)
|
)
|
||||||
if (interval) params.append('interval', interval)
|
|
||||||
|
|
||||||
appendAuthParams(params, { password, captcha })
|
|
||||||
|
|
||||||
params.append('limit', limit.toString())
|
|
||||||
return apiRequest<DashboardData>(`/public/sites/${siteId}/dashboard?${params.toString()}`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// * ============================================================================
|
// ─── Focused Dashboard Endpoints ────────────────────────────────────
|
||||||
// * Focused Dashboard Endpoints (Fix 4.2: Efficient Data Transfer)
|
|
||||||
// * These split the massive dashboard payload into smaller, focused chunks
|
|
||||||
// * ============================================================================
|
|
||||||
|
|
||||||
export interface DashboardOverviewData {
|
export interface DashboardOverviewData {
|
||||||
site: Site
|
site: Site
|
||||||
@@ -363,109 +270,18 @@ export interface DashboardOverviewData {
|
|||||||
daily_stats: DailyStat[]
|
daily_stats: DailyStat[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getDashboardOverview(
|
|
||||||
siteId: string,
|
|
||||||
startDate?: string,
|
|
||||||
endDate?: string,
|
|
||||||
interval?: string
|
|
||||||
): Promise<DashboardOverviewData> {
|
|
||||||
const params = new URLSearchParams()
|
|
||||||
if (startDate) params.append('start_date', startDate)
|
|
||||||
if (endDate) params.append('end_date', endDate)
|
|
||||||
if (interval) params.append('interval', interval)
|
|
||||||
return apiRequest<DashboardOverviewData>(`/sites/${siteId}/dashboard/overview?${params.toString()}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getPublicDashboardOverview(
|
|
||||||
siteId: string,
|
|
||||||
startDate?: string,
|
|
||||||
endDate?: string,
|
|
||||||
interval?: string,
|
|
||||||
password?: string,
|
|
||||||
captcha?: { captcha_id?: string, captcha_solution?: string, captcha_token?: string }
|
|
||||||
): Promise<DashboardOverviewData> {
|
|
||||||
const params = new URLSearchParams()
|
|
||||||
if (startDate) params.append('start_date', startDate)
|
|
||||||
if (endDate) params.append('end_date', endDate)
|
|
||||||
if (interval) params.append('interval', interval)
|
|
||||||
appendAuthParams(params, { password, captcha })
|
|
||||||
return apiRequest<DashboardOverviewData>(`/public/sites/${siteId}/dashboard/overview?${params.toString()}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DashboardPagesData {
|
export interface DashboardPagesData {
|
||||||
top_pages: TopPage[]
|
top_pages: TopPage[]
|
||||||
entry_pages: TopPage[]
|
entry_pages: TopPage[]
|
||||||
exit_pages: TopPage[]
|
exit_pages: TopPage[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getDashboardPages(
|
|
||||||
siteId: string,
|
|
||||||
startDate?: string,
|
|
||||||
endDate?: string,
|
|
||||||
limit = 10
|
|
||||||
): Promise<DashboardPagesData> {
|
|
||||||
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<DashboardPagesData>(`/sites/${siteId}/dashboard/pages?${params.toString()}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getPublicDashboardPages(
|
|
||||||
siteId: string,
|
|
||||||
startDate?: string,
|
|
||||||
endDate?: string,
|
|
||||||
limit = 10,
|
|
||||||
password?: string,
|
|
||||||
captcha?: { captcha_id?: string, captcha_solution?: string, captcha_token?: string }
|
|
||||||
): Promise<DashboardPagesData> {
|
|
||||||
const params = new URLSearchParams()
|
|
||||||
if (startDate) params.append('start_date', startDate)
|
|
||||||
if (endDate) params.append('end_date', endDate)
|
|
||||||
params.append('limit', limit.toString())
|
|
||||||
appendAuthParams(params, { password, captcha })
|
|
||||||
return apiRequest<DashboardPagesData>(`/public/sites/${siteId}/dashboard/pages?${params.toString()}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DashboardLocationsData {
|
export interface DashboardLocationsData {
|
||||||
countries: CountryStat[]
|
countries: CountryStat[]
|
||||||
cities: CityStat[]
|
cities: CityStat[]
|
||||||
regions: RegionStat[]
|
regions: RegionStat[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getDashboardLocations(
|
|
||||||
siteId: string,
|
|
||||||
startDate?: string,
|
|
||||||
endDate?: string,
|
|
||||||
limit = 10,
|
|
||||||
countryLimit = 250
|
|
||||||
): Promise<DashboardLocationsData> {
|
|
||||||
const params = new URLSearchParams()
|
|
||||||
if (startDate) params.append('start_date', startDate)
|
|
||||||
if (endDate) params.append('end_date', endDate)
|
|
||||||
params.append('limit', limit.toString())
|
|
||||||
params.append('country_limit', countryLimit.toString())
|
|
||||||
return apiRequest<DashboardLocationsData>(`/sites/${siteId}/dashboard/locations?${params.toString()}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getPublicDashboardLocations(
|
|
||||||
siteId: string,
|
|
||||||
startDate?: string,
|
|
||||||
endDate?: string,
|
|
||||||
limit = 10,
|
|
||||||
countryLimit = 250,
|
|
||||||
password?: string,
|
|
||||||
captcha?: { captcha_id?: string, captcha_solution?: string, captcha_token?: string }
|
|
||||||
): Promise<DashboardLocationsData> {
|
|
||||||
const params = new URLSearchParams()
|
|
||||||
if (startDate) params.append('start_date', startDate)
|
|
||||||
if (endDate) params.append('end_date', endDate)
|
|
||||||
params.append('limit', limit.toString())
|
|
||||||
params.append('country_limit', countryLimit.toString())
|
|
||||||
appendAuthParams(params, { password, captcha })
|
|
||||||
return apiRequest<DashboardLocationsData>(`/public/sites/${siteId}/dashboard/locations?${params.toString()}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DashboardDevicesData {
|
export interface DashboardDevicesData {
|
||||||
browsers: BrowserStat[]
|
browsers: BrowserStat[]
|
||||||
os: OSStat[]
|
os: OSStat[]
|
||||||
@@ -473,127 +289,92 @@ export interface DashboardDevicesData {
|
|||||||
screen_resolutions: ScreenResolutionStat[]
|
screen_resolutions: ScreenResolutionStat[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getDashboardDevices(
|
|
||||||
siteId: string,
|
|
||||||
startDate?: string,
|
|
||||||
endDate?: string,
|
|
||||||
limit = 10
|
|
||||||
): Promise<DashboardDevicesData> {
|
|
||||||
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<DashboardDevicesData>(`/sites/${siteId}/dashboard/devices?${params.toString()}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getPublicDashboardDevices(
|
|
||||||
siteId: string,
|
|
||||||
startDate?: string,
|
|
||||||
endDate?: string,
|
|
||||||
limit = 10,
|
|
||||||
password?: string,
|
|
||||||
captcha?: { captcha_id?: string, captcha_solution?: string, captcha_token?: string }
|
|
||||||
): Promise<DashboardDevicesData> {
|
|
||||||
const params = new URLSearchParams()
|
|
||||||
if (startDate) params.append('start_date', startDate)
|
|
||||||
if (endDate) params.append('end_date', endDate)
|
|
||||||
params.append('limit', limit.toString())
|
|
||||||
appendAuthParams(params, { password, captcha })
|
|
||||||
return apiRequest<DashboardDevicesData>(`/public/sites/${siteId}/dashboard/devices?${params.toString()}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DashboardReferrersData {
|
export interface DashboardReferrersData {
|
||||||
top_referrers: TopReferrer[]
|
top_referrers: TopReferrer[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getDashboardReferrers(
|
|
||||||
siteId: string,
|
|
||||||
startDate?: string,
|
|
||||||
endDate?: string,
|
|
||||||
limit = 10
|
|
||||||
): Promise<DashboardReferrersData> {
|
|
||||||
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<DashboardReferrersData>(`/sites/${siteId}/dashboard/referrers?${params.toString()}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getPublicDashboardReferrers(
|
|
||||||
siteId: string,
|
|
||||||
startDate?: string,
|
|
||||||
endDate?: string,
|
|
||||||
limit = 10,
|
|
||||||
password?: string,
|
|
||||||
captcha?: { captcha_id?: string, captcha_solution?: string, captcha_token?: string }
|
|
||||||
): Promise<DashboardReferrersData> {
|
|
||||||
const params = new URLSearchParams()
|
|
||||||
if (startDate) params.append('start_date', startDate)
|
|
||||||
if (endDate) params.append('end_date', endDate)
|
|
||||||
params.append('limit', limit.toString())
|
|
||||||
appendAuthParams(params, { password, captcha })
|
|
||||||
return apiRequest<DashboardReferrersData>(`/public/sites/${siteId}/dashboard/referrers?${params.toString()}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DashboardPerformanceData {
|
export interface DashboardPerformanceData {
|
||||||
performance?: PerformanceStats
|
performance?: PerformanceStats
|
||||||
performance_by_page?: PerformanceByPageStat[]
|
performance_by_page?: PerformanceByPageStat[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getDashboardPerformance(
|
|
||||||
siteId: string,
|
|
||||||
startDate?: string,
|
|
||||||
endDate?: string
|
|
||||||
): Promise<DashboardPerformanceData> {
|
|
||||||
const params = new URLSearchParams()
|
|
||||||
if (startDate) params.append('start_date', startDate)
|
|
||||||
if (endDate) params.append('end_date', endDate)
|
|
||||||
return apiRequest<DashboardPerformanceData>(`/sites/${siteId}/dashboard/performance?${params.toString()}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getPublicDashboardPerformance(
|
|
||||||
siteId: string,
|
|
||||||
startDate?: string,
|
|
||||||
endDate?: string,
|
|
||||||
password?: string,
|
|
||||||
captcha?: { captcha_id?: string, captcha_solution?: string, captcha_token?: string }
|
|
||||||
): Promise<DashboardPerformanceData> {
|
|
||||||
const params = new URLSearchParams()
|
|
||||||
if (startDate) params.append('start_date', startDate)
|
|
||||||
if (endDate) params.append('end_date', endDate)
|
|
||||||
appendAuthParams(params, { password, captcha })
|
|
||||||
return apiRequest<DashboardPerformanceData>(`/public/sites/${siteId}/dashboard/performance?${params.toString()}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DashboardGoalsData {
|
export interface DashboardGoalsData {
|
||||||
goal_counts: GoalCountStat[]
|
goal_counts: GoalCountStat[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getDashboardGoals(
|
export function getDashboardOverview(siteId: string, startDate?: string, endDate?: string, interval?: string): Promise<DashboardOverviewData> {
|
||||||
siteId: string,
|
return apiRequest<DashboardOverviewData>(`/sites/${siteId}/dashboard/overview${buildQuery({ startDate, endDate, interval })}`)
|
||||||
startDate?: string,
|
|
||||||
endDate?: string,
|
|
||||||
limit = 10
|
|
||||||
): Promise<DashboardGoalsData> {
|
|
||||||
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<DashboardGoalsData>(`/sites/${siteId}/dashboard/goals?${params.toString()}`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getPublicDashboardGoals(
|
export function getPublicDashboardOverview(
|
||||||
siteId: string,
|
siteId: string, startDate?: string, endDate?: string, interval?: string,
|
||||||
startDate?: string,
|
password?: string, captcha?: { captcha_id?: string, captcha_solution?: string, captcha_token?: string }
|
||||||
endDate?: string,
|
): Promise<DashboardOverviewData> {
|
||||||
limit = 10,
|
return apiRequest<DashboardOverviewData>(`/public/sites/${siteId}/dashboard/overview${buildQuery({ startDate, endDate, interval }, { password, captcha })}`)
|
||||||
password?: string,
|
}
|
||||||
captcha?: { captcha_id?: string, captcha_solution?: string, captcha_token?: string }
|
|
||||||
): Promise<DashboardGoalsData> {
|
export function getDashboardPages(siteId: string, startDate?: string, endDate?: string, limit = 10): Promise<DashboardPagesData> {
|
||||||
const params = new URLSearchParams()
|
return apiRequest<DashboardPagesData>(`/sites/${siteId}/dashboard/pages${buildQuery({ startDate, endDate, limit })}`)
|
||||||
if (startDate) params.append('start_date', startDate)
|
}
|
||||||
if (endDate) params.append('end_date', endDate)
|
|
||||||
params.append('limit', limit.toString())
|
export function getPublicDashboardPages(
|
||||||
appendAuthParams(params, { password, captcha })
|
siteId: string, startDate?: string, endDate?: string, limit = 10,
|
||||||
return apiRequest<DashboardGoalsData>(`/public/sites/${siteId}/dashboard/goals?${params.toString()}`)
|
password?: string, captcha?: { captcha_id?: string, captcha_solution?: string, captcha_token?: string }
|
||||||
|
): Promise<DashboardPagesData> {
|
||||||
|
return apiRequest<DashboardPagesData>(`/public/sites/${siteId}/dashboard/pages${buildQuery({ startDate, endDate, limit }, { password, captcha })}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDashboardLocations(siteId: string, startDate?: string, endDate?: string, limit = 10, countryLimit = 250): Promise<DashboardLocationsData> {
|
||||||
|
return apiRequest<DashboardLocationsData>(`/sites/${siteId}/dashboard/locations${buildQuery({ startDate, endDate, limit, countryLimit })}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPublicDashboardLocations(
|
||||||
|
siteId: string, startDate?: string, endDate?: string, limit = 10, countryLimit = 250,
|
||||||
|
password?: string, captcha?: { captcha_id?: string, captcha_solution?: string, captcha_token?: string }
|
||||||
|
): Promise<DashboardLocationsData> {
|
||||||
|
return apiRequest<DashboardLocationsData>(`/public/sites/${siteId}/dashboard/locations${buildQuery({ startDate, endDate, limit, countryLimit }, { password, captcha })}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDashboardDevices(siteId: string, startDate?: string, endDate?: string, limit = 10): Promise<DashboardDevicesData> {
|
||||||
|
return apiRequest<DashboardDevicesData>(`/sites/${siteId}/dashboard/devices${buildQuery({ startDate, endDate, limit })}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPublicDashboardDevices(
|
||||||
|
siteId: string, startDate?: string, endDate?: string, limit = 10,
|
||||||
|
password?: string, captcha?: { captcha_id?: string, captcha_solution?: string, captcha_token?: string }
|
||||||
|
): Promise<DashboardDevicesData> {
|
||||||
|
return apiRequest<DashboardDevicesData>(`/public/sites/${siteId}/dashboard/devices${buildQuery({ startDate, endDate, limit }, { password, captcha })}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDashboardReferrers(siteId: string, startDate?: string, endDate?: string, limit = 10): Promise<DashboardReferrersData> {
|
||||||
|
return apiRequest<DashboardReferrersData>(`/sites/${siteId}/dashboard/referrers${buildQuery({ startDate, endDate, limit })}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPublicDashboardReferrers(
|
||||||
|
siteId: string, startDate?: string, endDate?: string, limit = 10,
|
||||||
|
password?: string, captcha?: { captcha_id?: string, captcha_solution?: string, captcha_token?: string }
|
||||||
|
): Promise<DashboardReferrersData> {
|
||||||
|
return apiRequest<DashboardReferrersData>(`/public/sites/${siteId}/dashboard/referrers${buildQuery({ startDate, endDate, limit }, { password, captcha })}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDashboardPerformance(siteId: string, startDate?: string, endDate?: string): Promise<DashboardPerformanceData> {
|
||||||
|
return apiRequest<DashboardPerformanceData>(`/sites/${siteId}/dashboard/performance${buildQuery({ startDate, endDate })}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPublicDashboardPerformance(
|
||||||
|
siteId: string, startDate?: string, endDate?: string,
|
||||||
|
password?: string, captcha?: { captcha_id?: string, captcha_solution?: string, captcha_token?: string }
|
||||||
|
): Promise<DashboardPerformanceData> {
|
||||||
|
return apiRequest<DashboardPerformanceData>(`/public/sites/${siteId}/dashboard/performance${buildQuery({ startDate, endDate }, { password, captcha })}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDashboardGoals(siteId: string, startDate?: string, endDate?: string, limit = 10): Promise<DashboardGoalsData> {
|
||||||
|
return apiRequest<DashboardGoalsData>(`/sites/${siteId}/dashboard/goals${buildQuery({ startDate, endDate, limit })}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPublicDashboardGoals(
|
||||||
|
siteId: string, startDate?: string, endDate?: string, limit = 10,
|
||||||
|
password?: string, captcha?: { captcha_id?: string, captcha_solution?: string, captcha_token?: string }
|
||||||
|
): Promise<DashboardGoalsData> {
|
||||||
|
return apiRequest<DashboardGoalsData>(`/public/sites/${siteId}/dashboard/goals${buildQuery({ startDate, endDate, limit }, { password, captcha })}`)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user