"use client"; import { useState, useEffect } from 'react'; import { format } from 'date-fns'; // 更复杂的事件类型定义 interface Event { event_id?: string; url_id: string; url: string; event_type: string; visitor_id: string; created_at: string; referrer?: string; browser?: string; os?: string; device_type?: string; country?: string; city?: string; } // 创建获取事件的函数 const fetchEvents = async ( startTime?: string, endTime?: string, urlId?: string, eventType?: string ): Promise => { try { // 构建查询参数 const params = new URLSearchParams(); if (startTime) params.append('startTime', startTime); if (endTime) params.append('endTime', endTime); if (urlId) params.append('urlId', urlId); if (eventType) params.append('eventType', eventType); // 发送请求 const response = await fetch(`/api/events?${params.toString()}`); if (!response.ok) { throw new Error('Failed to fetch events'); } const data = await response.json(); return data.data || []; } catch (error) { console.error('Error fetching events:', error); return []; } }; const formatDate = (dateString: string) => { if (!dateString) return ''; try { return format(new Date(dateString), 'yyyy-MM-dd HH:mm:ss'); } catch { return dateString; } }; export default function EventsPage() { // 状态定义 const [events, setEvents] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [filters, setFilters] = useState({ startDate: format(new Date(Date.now() - 7 * 24 * 60 * 60 * 1000), 'yyyy-MM-dd'), endDate: format(new Date(), 'yyyy-MM-dd'), urlId: '', eventType: '' }); // 加载事件数据 useEffect(() => { const loadEvents = async () => { setLoading(true); setError(null); try { const startTime = `${filters.startDate}T00:00:00Z`; const endTime = `${filters.endDate}T23:59:59Z`; const eventsData = await fetchEvents( startTime, endTime, filters.urlId || undefined, filters.eventType || undefined ); setEvents(eventsData); } catch (err) { setError('Failed to load events'); console.error(err); } finally { setLoading(false); } }; loadEvents(); }, [filters]); // 处理筛选条件变化 const handleFilterChange = (name: string, value: string) => { setFilters(prev => ({ ...prev, [name]: value })); }; return (
{/* 页面标题 */}

Events

View and analyze all events for your URLs

{/* 过滤器面板 */}
handleFilterChange('startDate', e.target.value)} className="block w-full px-3 py-2 bg-white border border-gray-300 rounded-md text-sm text-gray-900" />
handleFilterChange('endDate', e.target.value)} className="block w-full px-3 py-2 bg-white border border-gray-300 rounded-md text-sm text-gray-900" />
handleFilterChange('urlId', e.target.value)} className="block w-full px-3 py-2 bg-white border border-gray-300 rounded-md text-sm text-gray-900" placeholder="Filter by URL ID" />
{/* 事件表格 */}
{events.map((event, index) => ( ))}
Time URL ID URL Event Type Visitor ID Referrer Location
{formatDate(event.created_at)} {event.url_id} {event.url} {event.event_type} {event.visitor_id.substring(0, 8)}... {event.referrer || '-'} {event.country && event.city ? `${event.city}, ${event.country}` : (event.country || '-')}
{/* 加载状态 */} {loading && (
)} {/* 错误状态 */} {error && (
{error}
)} {/* 空状态 */} {!loading && !error && events.length === 0 && (
No events found
)}
); }