This commit is contained in:
2025-03-25 21:12:03 +08:00
parent ecf21a812f
commit e0ac87fb25
2 changed files with 105 additions and 34 deletions

View File

@@ -1,14 +1,14 @@
"use client";
import { useState, useEffect, useRef } from 'react';
import { addDays, format } from 'date-fns';
import { useState, useEffect } from 'react';
import { format } from 'date-fns';
import { DateRangePicker } from '../components/ui/DateRangePicker';
import { Event, EventFilters } from '../api/types';
import { Event } from '../api/types';
export default function EventsPage() {
const [dateRange, setDateRange] = useState({
from: addDays(new Date(), -7),
to: new Date()
from: new Date('2024-02-01'),
to: new Date('2025-03-05')
});
const [loading, setLoading] = useState(true);
@@ -22,7 +22,7 @@ export default function EventsPage() {
linkSlug: ''
});
const [filters, setFilters] = useState<EventFilters>({
const [filters, setFilters] = useState({
startTime: format(new Date('2024-02-01'), "yyyy-MM-dd'T'HH:mm:ss'Z'"),
endTime: format(new Date('2025-03-05'), "yyyy-MM-dd'T'HH:mm:ss'Z'"),
page: 1,
@@ -30,8 +30,6 @@ export default function EventsPage() {
});
const [summary, setSummary] = useState<any>(null);
const observerRef = useRef<IntersectionObserver | null>(null);
const lastEventRef = useRef<HTMLDivElement | null>(null);
const fetchEvents = async (pageNum: number) => {
try {
@@ -56,15 +54,19 @@ export default function EventsPage() {
throw new Error(data.error || 'Failed to fetch events');
}
const eventsData = data.data || data.events || [];
if (pageNum === 1) {
setEvents(data.events);
setEvents(eventsData);
} else {
setEvents(prev => [...prev, ...data.events]);
setEvents(prev => [...prev, ...eventsData]);
}
setHasMore(data.events.length === 50);
setHasMore(Array.isArray(eventsData) && eventsData.length === 50);
} catch (err) {
console.error("Error fetching events:", err);
setError(err instanceof Error ? err.message : 'An error occurred while fetching events');
setEvents([]);
} finally {
setLoading(false);
}
@@ -174,42 +176,53 @@ export default function EventsPage() {
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
Referrer
</th>
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
Conversion
</th>
</tr>
</thead>
<tbody className="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
{events.map((event, index) => (
<tr key={event.id} className={index % 2 === 0 ? 'bg-white dark:bg-gray-800' : 'bg-gray-50 dark:bg-gray-900'}>
{Array.isArray(events) && events.map((event, index) => (
<tr key={event.event_id || index} className={index % 2 === 0 ? 'bg-white dark:bg-gray-800' : 'bg-gray-50 dark:bg-gray-900'}>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
{formatDate(event.time)}
{event.event_time && formatDate(event.event_time)}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm">
<span className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${
event.type === 'conversion' ? 'bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100' : 'bg-blue-100 text-blue-800 dark:bg-blue-800 dark:text-blue-100'
event.event_type === 'conversion' ? 'bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100' : 'bg-blue-100 text-blue-800 dark:bg-blue-800 dark:text-blue-100'
}`}>
{event.type}
{event.event_type || 'unknown'}
</span>
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
<div>
<div className="font-medium">{event.linkInfo.shortUrl}</div>
<div className="text-gray-500 dark:text-gray-400 text-xs">{event.linkInfo.originalUrl}</div>
<div className="font-medium">{event.link_slug || '-'}</div>
<div className="text-gray-500 dark:text-gray-400 text-xs">{event.link_original_url || '-'}</div>
</div>
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
<div>
<div>{event.visitor.browser}</div>
<div className="text-gray-500 dark:text-gray-400 text-xs">{event.visitor.os} / {event.visitor.device}</div>
<div>{event.browser || '-'}</div>
<div className="text-gray-500 dark:text-gray-400 text-xs">{event.os || '-'} / {event.device_type || '-'}</div>
</div>
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
<div>
<div>{event.location.city}</div>
<div className="text-gray-500 dark:text-gray-400 text-xs">{event.location.region}, {event.location.country}</div>
<div>{event.city || '-'}</div>
<div className="text-gray-500 dark:text-gray-400 text-xs">{event.country || '-'}</div>
</div>
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
{event.referrer || '-'}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
<div>
<div>{event.conversion_type || '-'}</div>
{event.conversion_value > 0 && (
<div className="text-gray-500 dark:text-gray-400 text-xs">Value: {event.conversion_value}</div>
)}
</div>
</td>
</tr>
))}
</tbody>
@@ -233,7 +246,7 @@ export default function EventsPage() {
</div>
)}
{!loading && events.length === 0 && (
{!loading && Array.isArray(events) && events.length === 0 && (
<div className="flex justify-center p-8 text-gray-500 dark:text-gray-400">
No events found
</div>