diff --git a/app/analytics/conversions/page.tsx b/app/analytics/conversions/page.tsx deleted file mode 100644 index d20bef5..0000000 --- a/app/analytics/conversions/page.tsx +++ /dev/null @@ -1,151 +0,0 @@ -"use client"; - -import { useState, useEffect } from 'react'; -import { addDays, format } from 'date-fns'; -import { DateRangePicker } from '../../components/ui/DateRangePicker'; -import TimeSeriesChart from '../../components/charts/TimeSeriesChart'; -import { TimeSeriesData } from '../../api/types'; - -interface ConversionStats { - totalConversions: number; - conversionRate: number; - averageValue: number; - conversionsByType: { - type: string; - count: number; - value: number; - percentage: number; - }[]; -} - -export default function ConversionsPage() { - const [dateRange, setDateRange] = useState({ - from: new Date('2024-02-01'), - to: new Date('2025-03-05') - }); - - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - const [stats, setStats] = useState(null); - const [timeSeriesData, setTimeSeriesData] = useState([]); - - 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 [statsRes, timeSeriesRes] = await Promise.all([ - fetch(`/api/events/conversions/stats?startTime=${startTime}&endTime=${endTime}`), - fetch(`/api/events/conversions/time-series?startTime=${startTime}&endTime=${endTime}`) - ]); - - const [statsData, timeSeriesData] = await Promise.all([ - statsRes.json(), - timeSeriesRes.json() - ]); - - if (!statsRes.ok) throw new Error(statsData.error || 'Failed to fetch conversion stats'); - if (!timeSeriesRes.ok) throw new Error(timeSeriesData.error || 'Failed to fetch time series data'); - - setStats(statsData); - setTimeSeriesData(timeSeriesData.data); - } catch (err) { - setError(err instanceof Error ? err.message : 'An error occurred while fetching data'); - } finally { - setLoading(false); - } - }; - - fetchData(); - }, [dateRange]); - - if (loading) { - return ( -
-
-
- ); - } - - if (error) { - return ( -
-
{error}
-
- ); - } - - return ( -
-
-

Conversion Analytics

- -
- - {stats && ( -
-
-

Total Conversions

-

{stats.totalConversions.toLocaleString()}

-
-
-

Conversion Rate

-

{stats.conversionRate.toFixed(2)}%

-
-
-

Average Value

-

${stats.averageValue.toFixed(2)}

-
-
- )} - -
-

Conversion Trends

-
- -
-
- - {stats && ( -
-

Conversion Types

-
- {stats.conversionsByType.map((item, index) => ( -
-
-
- {item.type} - - {item.count.toLocaleString()} conversions - -
-
- - ${item.value.toFixed(2)} - - - ({item.percentage.toFixed(1)}%) - -
-
-
-
-
-
- ))} -
-
- )} -
- ); -} \ No newline at end of file diff --git a/app/analytics/devices/page.tsx b/app/analytics/devices/page.tsx index b10d534..6c5c3e7 100644 --- a/app/analytics/devices/page.tsx +++ b/app/analytics/devices/page.tsx @@ -69,16 +69,16 @@ export default function DeviceAnalyticsPage() {
{/* 设备类型 */}
-

Device Types

+

Device Types

{deviceData?.deviceTypes.map(item => (
- {item.type} - {item.count} ({item.percentage.toFixed(1)}%) + {item.type} + {item.count} ({item.percentage.toFixed(1)}%)
@@ -88,16 +88,16 @@ export default function DeviceAnalyticsPage() { {/* 浏览器 */}
-

Browsers

+

Browsers

{deviceData?.browsers.map(item => (
- {item.name} - {item.count} ({item.percentage.toFixed(1)}%) + {item.name} + {item.count} ({item.percentage.toFixed(1)}%)
@@ -107,16 +107,16 @@ export default function DeviceAnalyticsPage() { {/* 操作系统 */}
-

Operating Systems

+

Operating Systems

{deviceData?.operatingSystems.map(item => (
- {item.name} - {item.count} ({item.percentage.toFixed(1)}%) + {item.name} + {item.count} ({item.percentage.toFixed(1)}%)
diff --git a/app/analytics/geo/page.tsx b/app/analytics/geo/page.tsx index f29d60e..7bccb5e 100644 --- a/app/analytics/geo/page.tsx +++ b/app/analytics/geo/page.tsx @@ -37,27 +37,27 @@ export default function GeoAnalyticsPage() {
{/* 页面标题 */}
-

Geographic Analysis

-

Analyze visitor distribution by location

+

Geographic Analysis

+

Analyze visitor distribution by location

{/* 时间范围选择器 */}
- + setDateRange(prev => ({ ...prev, from: new Date(e.target.value) }))} />
- + setDateRange(prev => ({ ...prev, to: new Date(e.target.value) }))} /> @@ -71,33 +71,33 @@ export default function GeoAnalyticsPage() { - - - - + + + + {geoData.map(item => ( - - - @@ -122,14 +122,14 @@ export default function GeoAnalyticsPage() { {/* 无数据状态 */} {!isLoading && !error && geoData.length === 0 && ( -
+

No geographic data available

)}
{/* 提示信息 */} -
+

Note: Geographic data is based on IP addresses and may not be 100% accurate.

diff --git a/app/layout.tsx b/app/layout.tsx index 61f1c59..317a463 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -52,12 +52,6 @@ export default function RootLayout({ > Devices - - Conversions - diff --git a/app/page.tsx b/app/page.tsx index fedad19..4128c67 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -42,16 +42,6 @@ export default function HomePage() { ), }, - { - title: 'Conversions', - description: 'Track conversion rates and analyze the performance of your links.', - href: '/analytics/conversions', - icon: ( - - - - ), - }, ]; return (
LocationVisitsUnique VisitorsPercentageLocationVisitsUnique VisitorsPercentage
+ {item.location} + {item.visits} + {item.visitors}
- {item.percentage.toFixed(1)}% + {item.percentage.toFixed(1)}%