refactor: migrate dashboard to SWR hooks, eliminate all any[] state
Replace 22 manual useState + useEffect + setInterval polling with 11 focused SWR hooks. Removes ~85 lines of polling/visibility logic that SWR handles natively. All any[] types replaced with proper interfaces (TopPage, CountryStat, BrowserStat, etc.). Organization state in layout typed as OrganizationMember[]. Resolves F-7, F-8, F-15 from audit report. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,7 @@ import {
|
||||
getDashboardReferrers,
|
||||
getDashboardPerformance,
|
||||
getDashboardGoals,
|
||||
getCampaigns,
|
||||
getRealtime,
|
||||
getStats,
|
||||
getDailyStats,
|
||||
@@ -20,6 +21,7 @@ import type { Site } from '@/lib/api/sites'
|
||||
import type {
|
||||
Stats,
|
||||
DailyStat,
|
||||
CampaignStat,
|
||||
DashboardOverviewData,
|
||||
DashboardPagesData,
|
||||
DashboardLocationsData,
|
||||
@@ -33,7 +35,7 @@ import type {
|
||||
const fetchers = {
|
||||
site: (siteId: string) => getSite(siteId),
|
||||
dashboard: (siteId: string, start: string, end: string) => getDashboard(siteId, start, end),
|
||||
dashboardOverview: (siteId: string, start: string, end: string) => getDashboardOverview(siteId, start, end),
|
||||
dashboardOverview: (siteId: string, start: string, end: string, interval?: string) => getDashboardOverview(siteId, start, end, interval),
|
||||
dashboardPages: (siteId: string, start: string, end: string) => getDashboardPages(siteId, start, end),
|
||||
dashboardLocations: (siteId: string, start: string, end: string) => getDashboardLocations(siteId, start, end),
|
||||
dashboardDevices: (siteId: string, start: string, end: string) => getDashboardDevices(siteId, start, end),
|
||||
@@ -44,6 +46,8 @@ const fetchers = {
|
||||
dailyStats: (siteId: string, start: string, end: string, interval: 'hour' | 'day' | 'minute') =>
|
||||
getDailyStats(siteId, start, end, interval),
|
||||
realtime: (siteId: string) => getRealtime(siteId),
|
||||
campaigns: (siteId: string, start: string, end: string, limit: number) =>
|
||||
getCampaigns(siteId, start, end, limit),
|
||||
}
|
||||
|
||||
// * Standard SWR config for dashboard data
|
||||
@@ -140,10 +144,10 @@ export function useRealtime(siteId: string, refreshInterval: number = 5000) {
|
||||
}
|
||||
|
||||
// * Hook for focused dashboard overview data (Fix 4.2: Efficient Data Transfer)
|
||||
export function useDashboardOverview(siteId: string, start: string, end: string) {
|
||||
export function useDashboardOverview(siteId: string, start: string, end: string, interval?: string) {
|
||||
return useSWR<DashboardOverviewData>(
|
||||
siteId && start && end ? ['dashboardOverview', siteId, start, end] : null,
|
||||
() => fetchers.dashboardOverview(siteId, start, end),
|
||||
siteId && start && end ? ['dashboardOverview', siteId, start, end, interval] : null,
|
||||
() => fetchers.dashboardOverview(siteId, start, end, interval),
|
||||
{
|
||||
...dashboardSWRConfig,
|
||||
refreshInterval: 60 * 1000,
|
||||
@@ -230,5 +234,18 @@ export function useDashboardGoals(siteId: string, start: string, end: string) {
|
||||
)
|
||||
}
|
||||
|
||||
// * Hook for campaigns data (used by export modal)
|
||||
export function useCampaigns(siteId: string, start: string, end: string, limit = 100) {
|
||||
return useSWR<CampaignStat[]>(
|
||||
siteId && start && end ? ['campaigns', siteId, start, end, limit] : null,
|
||||
() => fetchers.campaigns(siteId, start, end, limit),
|
||||
{
|
||||
...dashboardSWRConfig,
|
||||
refreshInterval: 60 * 1000,
|
||||
dedupingInterval: 10 * 1000,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// * Re-export for convenience
|
||||
export { fetchers }
|
||||
|
||||
Reference in New Issue
Block a user