feat(pagespeed): add API client, SWR hooks, and sidebar navigation

- PageSpeed API client with types for config, checks, and audits
- SWR hooks: usePageSpeedConfig, usePageSpeedLatest, usePageSpeedHistory
- GaugeIcon added to sidebar under Infrastructure group
This commit is contained in:
Usman Baig
2026-03-22 18:05:17 +01:00
parent b026476311
commit 780dd464a1
3 changed files with 116 additions and 0 deletions

83
lib/api/pagespeed.ts Normal file
View File

@@ -0,0 +1,83 @@
import apiRequest from './client'
// * Types for PageSpeed Insights monitoring
export interface PageSpeedConfig {
site_id: string
enabled: boolean
frequency: 'daily' | 'weekly' | 'monthly'
url: string | null
next_check_at: string | null
created_at: string
updated_at: string
}
export interface AuditSummary {
id: string
title: string
description: string
score: number | null
display_value?: string
savings_ms?: number
category: 'opportunity' | 'diagnostic' | 'passed'
}
export interface PageSpeedCheck {
id: string
site_id: string
strategy: 'mobile' | 'desktop'
performance_score: number | null
accessibility_score: number | null
best_practices_score: number | null
seo_score: number | null
lcp_ms: number | null
cls: number | null
tbt_ms: number | null
fcp_ms: number | null
si_ms: number | null
tti_ms: number | null
audits: AuditSummary[] | null
triggered_by: 'scheduled' | 'manual'
checked_at: string
}
export async function getPageSpeedConfig(siteId: string): Promise<PageSpeedConfig> {
return apiRequest<PageSpeedConfig>(`/sites/${siteId}/pagespeed/config`)
}
export async function updatePageSpeedConfig(
siteId: string,
config: { enabled: boolean; frequency: string; url?: string }
): Promise<PageSpeedConfig> {
return apiRequest<PageSpeedConfig>(`/sites/${siteId}/pagespeed/config`, {
method: 'PUT',
body: JSON.stringify(config),
})
}
export async function getPageSpeedLatest(siteId: string): Promise<PageSpeedCheck[]> {
const res = await apiRequest<{ checks: PageSpeedCheck[] }>(`/sites/${siteId}/pagespeed/latest`)
return res?.checks ?? []
}
export async function getPageSpeedHistory(
siteId: string,
strategy: 'mobile' | 'desktop' = 'mobile',
days = 90
): Promise<PageSpeedCheck[]> {
const res = await apiRequest<{ checks: PageSpeedCheck[] }>(
`/sites/${siteId}/pagespeed/history?strategy=${strategy}&days=${days}`
)
return res?.checks ?? []
}
export async function getPageSpeedCheck(siteId: string, checkId: string): Promise<PageSpeedCheck> {
return apiRequest<PageSpeedCheck>(`/sites/${siteId}/pagespeed/checks/${checkId}`)
}
export async function triggerPageSpeedCheck(siteId: string): Promise<PageSpeedCheck[]> {
const res = await apiRequest<{ checks: PageSpeedCheck[] }>(`/sites/${siteId}/pagespeed/check`, {
method: 'POST',
})
return res?.checks ?? []
}

View File

@@ -31,6 +31,7 @@ import { getSite } from '@/lib/api/sites'
import type { Site } from '@/lib/api/sites'
import { listFunnels, type Funnel } from '@/lib/api/funnels'
import { getUptimeStatus, type UptimeStatusResponse } from '@/lib/api/uptime'
import { getPageSpeedConfig, getPageSpeedLatest, getPageSpeedHistory, type PageSpeedConfig, type PageSpeedCheck } from '@/lib/api/pagespeed'
import { listGoals, type Goal } from '@/lib/api/goals'
import { listReportSchedules, listAlertSchedules, type ReportSchedule } from '@/lib/api/report-schedules'
import { listSessions, getBotFilterStats, type SessionSummary, type BotFilterStats } from '@/lib/api/bot-filter'
@@ -79,6 +80,9 @@ const fetchers = {
getJourneyEntryPoints(siteId, start, end),
funnels: (siteId: string) => listFunnels(siteId),
uptimeStatus: (siteId: string) => getUptimeStatus(siteId),
pageSpeedConfig: (siteId: string) => getPageSpeedConfig(siteId),
pageSpeedLatest: (siteId: string) => getPageSpeedLatest(siteId),
pageSpeedHistory: (siteId: string, strategy: 'mobile' | 'desktop', days: number) => getPageSpeedHistory(siteId, strategy, days),
goals: (siteId: string) => listGoals(siteId),
reportSchedules: (siteId: string) => listReportSchedules(siteId),
alertSchedules: (siteId: string) => listAlertSchedules(siteId),
@@ -550,5 +554,32 @@ export function useBotFilterStats(siteId: string) {
)
}
// * Hook for PageSpeed config
export function usePageSpeedConfig(siteId: string) {
return useSWR<PageSpeedConfig>(
siteId ? ['pageSpeedConfig', siteId] : null,
() => fetchers.pageSpeedConfig(siteId),
{ ...dashboardSWRConfig, refreshInterval: 0, dedupingInterval: 10 * 1000 }
)
}
// * Hook for latest PageSpeed checks (mobile + desktop)
export function usePageSpeedLatest(siteId: string) {
return useSWR<PageSpeedCheck[]>(
siteId ? ['pageSpeedLatest', siteId] : null,
() => fetchers.pageSpeedLatest(siteId),
{ ...dashboardSWRConfig, refreshInterval: 60 * 1000, dedupingInterval: 10 * 1000, keepPreviousData: true }
)
}
// * Hook for PageSpeed score history (trend chart)
export function usePageSpeedHistory(siteId: string, strategy: 'mobile' | 'desktop', days = 90) {
return useSWR<PageSpeedCheck[]>(
siteId ? ['pageSpeedHistory', siteId, strategy, days] : null,
() => fetchers.pageSpeedHistory(siteId, strategy, days),
{ ...dashboardSWRConfig, refreshInterval: 60 * 1000, dedupingInterval: 10 * 1000, keepPreviousData: true }
)
}
// * Re-export for convenience
export { fetchers }