From b425f5b98768ab1d28adc580c3827e7182021ba2 Mon Sep 17 00:00:00 2001 From: William Tso Date: Mon, 31 Mar 2025 19:46:31 +0800 Subject: [PATCH] dashboard data --- app/(app)/dashboard/page.tsx | 248 ++++++++++++++++++++++++----------- 1 file changed, 170 insertions(+), 78 deletions(-) diff --git a/app/(app)/dashboard/page.tsx b/app/(app)/dashboard/page.tsx index 7739b1f..c97e6a4 100644 --- a/app/(app)/dashboard/page.tsx +++ b/app/(app)/dashboard/page.tsx @@ -1,7 +1,7 @@ "use client"; import { useState, useEffect } from 'react'; -import { addDays, format } from 'date-fns'; +import { format } from 'date-fns'; import { DateRangePicker } from '@/app/components/ui/DateRangePicker'; import TimeSeriesChart from '@/app/components/charts/TimeSeriesChart'; import GeoAnalytics from '@/app/components/analytics/GeoAnalytics'; @@ -21,57 +21,117 @@ export default function DashboardPage() { const [geoData, setGeoData] = useState([]); const [deviceData, setDeviceData] = useState(null); - useEffect(() => { - const fetchData = async () => { - setLoading(true); - setError(null); - - try { - const startTime = format(dateRange.from, "yyyy-MM-dd'T'HH:mm:ss'Z'"); - const endTime = format(dateRange.to, "yyyy-MM-dd'T'HH:mm:ss'Z'"); - - // 并行获取所有数据 - const [summaryRes, timeSeriesRes, geoRes, deviceRes] = await Promise.all([ - fetch(`/api/events/summary?startTime=${startTime}&endTime=${endTime}`), - fetch(`/api/events/time-series?startTime=${startTime}&endTime=${endTime}`), - fetch(`/api/events/geo?startTime=${startTime}&endTime=${endTime}`), - fetch(`/api/events/devices?startTime=${startTime}&endTime=${endTime}`) - ]); - - const [summaryData, timeSeriesData, geoData, deviceData] = await Promise.all([ - summaryRes.json(), - timeSeriesRes.json(), - geoRes.json(), - deviceRes.json() - ]); - - if (!summaryRes.ok) throw new Error(summaryData.error || 'Failed to fetch summary data'); - if (!timeSeriesRes.ok) throw new Error(timeSeriesData.error || 'Failed to fetch time series data'); - if (!geoRes.ok) throw new Error(geoData.error || 'Failed to fetch geo data'); - if (!deviceRes.ok) throw new Error(deviceData.error || 'Failed to fetch device data'); - - setSummary(summaryData); - setTimeSeriesData(timeSeriesData.data); - setGeoData(geoData.data); - setDeviceData(deviceData.data); - } catch (err) { - setError(err instanceof Error ? err.message : 'An error occurred while fetching data'); - } finally { - setLoading(false); + // 获取统计数据 + const fetchSummary = async () => { + try { + const startTime = format(dateRange.from, "yyyy-MM-dd'T'HH:mm:ss'Z'"); + const endTime = format(dateRange.to, "yyyy-MM-dd'T'HH:mm:ss'Z'"); + + const response = await fetch( + `/api/events/summary?startTime=${startTime}&endTime=${endTime}` + ); + const data = await response.json(); + + if (!response.ok) { + throw new Error(data.error || 'Failed to fetch summary'); } - }; - fetchData(); + if (data.success && data.data) { + console.log('Summary data:', data.data); // 添加日志 + setSummary(data.data); + } + } catch (err) { + console.error('Error fetching summary:', err); + setError(err instanceof Error ? err.message : 'Failed to load summary'); + } + }; + + // 获取时间序列数据 + const fetchTimeSeriesData = async () => { + try { + const startTime = format(dateRange.from, "yyyy-MM-dd'T'HH:mm:ss'Z'"); + const endTime = format(dateRange.to, "yyyy-MM-dd'T'HH:mm:ss'Z'"); + + const response = await fetch( + `/api/events/time-series?startTime=${startTime}&endTime=${endTime}&granularity=day` + ); + const data = await response.json(); + + if (!response.ok) { + throw new Error(data.error || 'Failed to fetch time series data'); + } + + if (data.success && Array.isArray(data.data)) { + setTimeSeriesData(data.data); + } + } catch (err) { + console.error('Error fetching time series:', err); + } + }; + + // 获取地理位置数据 + const fetchGeoData = async () => { + try { + const startTime = format(dateRange.from, "yyyy-MM-dd'T'HH:mm:ss'Z'"); + const endTime = format(dateRange.to, "yyyy-MM-dd'T'HH:mm:ss'Z'"); + + const response = await fetch( + `/api/events/geo?startTime=${startTime}&endTime=${endTime}` + ); + const data = await response.json(); + + if (!response.ok) { + throw new Error(data.error || 'Failed to fetch geo data'); + } + + if (data.success && Array.isArray(data.data)) { + setGeoData(data.data); + } + } catch (err) { + console.error('Error fetching geo data:', err); + } + }; + + // 获取设备数据 + const fetchDeviceData = async () => { + try { + const startTime = format(dateRange.from, "yyyy-MM-dd'T'HH:mm:ss'Z'"); + const endTime = format(dateRange.to, "yyyy-MM-dd'T'HH:mm:ss'Z'"); + + const response = await fetch( + `/api/events/devices?startTime=${startTime}&endTime=${endTime}` + ); + const data = await response.json(); + + if (!response.ok) { + throw new Error(data.error || 'Failed to fetch device data'); + } + + if (data.success && data.data) { + setDeviceData(data.data); + } + } catch (err) { + console.error('Error fetching device data:', err); + } + }; + + // 加载所有数据 + const loadAllData = async () => { + setLoading(true); + await Promise.all([ + fetchSummary(), + fetchTimeSeriesData(), + fetchGeoData(), + fetchDeviceData() + ]); + setLoading(false); + }; + + // 当日期范围改变时重新加载数据 + useEffect(() => { + loadAllData(); }, [dateRange]); - if (loading) { - return ( -
-
-
- ); - } - if (error) { return (
@@ -90,50 +150,82 @@ export default function DashboardPage() { />
- {summary && ( -
-
-

Total Events

-

- {typeof summary.totalEvents === 'number' ? summary.totalEvents.toLocaleString() : summary.totalEvents} -

-
-
-

Unique Visitors

-

- {typeof summary.uniqueVisitors === 'number' ? summary.uniqueVisitors.toLocaleString() : summary.uniqueVisitors} -

-
-
-

Total Conversions

-

- {typeof summary.totalConversions === 'number' ? summary.totalConversions.toLocaleString() : summary.totalConversions} -

-
-
-

Avg. Time Spent

-

- {summary.averageTimeSpent?.toFixed(1) || '0'}s -

-
+
+
+

Total Events

+

+ {loading ? ( + Loading... + ) : ( + summary?.totalEvents?.toLocaleString() || '0' + )} +

- )} +
+

Unique Visitors

+

+ {loading ? ( + Loading... + ) : ( + summary?.uniqueVisitors?.toLocaleString() || '0' + )} +

+
+
+

Total Conversions

+

+ {loading ? ( + Loading... + ) : ( + summary?.totalConversions?.toLocaleString() || '0' + )} +

+
+
+

Avg. Time Spent

+

+ {loading ? ( + Loading... + ) : ( + `${summary?.averageTimeSpent?.toFixed(1) || '0'}s` + )} +

+
+

Event Trends

- + {loading ? ( +
+ Loading... +
+ ) : ( + + )}

Device Analytics

- {deviceData && } + {loading ? ( +
+ Loading... +
+ ) : ( + deviceData && + )}

Geographic Distribution

- + {loading ? ( +
+ Loading... +
+ ) : ( + + )}
);