"use client"; import { useState, useEffect } from 'react'; import { format } from 'date-fns'; import { DateRangePicker } from '../components/ui/DateRangePicker'; import { Event } from '../api/types'; export default function EventsPage() { 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 [events, setEvents] = useState([]); const [page, setPage] = useState(1); const [hasMore, setHasMore] = useState(true); const [filter, setFilter] = useState({ eventType: '', linkId: '', linkSlug: '' }); 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, pageSize: 20 }); const [summary, setSummary] = useState(null); const fetchEvents = async (pageNum: number) => { 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 params = new URLSearchParams({ startTime, endTime, page: pageNum.toString(), pageSize: '50' }); if (filter.eventType) params.append('eventType', filter.eventType); if (filter.linkId) params.append('linkId', filter.linkId); if (filter.linkSlug) params.append('linkSlug', filter.linkSlug); const response = await fetch(`/api/events?${params.toString()}`); const data = await response.json(); if (!response.ok) { throw new Error(data.error || 'Failed to fetch events'); } const eventsData = data.data || data.events || []; if (pageNum === 1) { setEvents(eventsData); } else { setEvents(prev => [...prev, ...eventsData]); } 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); } }; useEffect(() => { setPage(1); setEvents([]); setLoading(true); fetchEvents(1); }, [dateRange, filter]); const loadMore = () => { if (!loading && hasMore) { const nextPage = page + 1; setPage(nextPage); fetchEvents(nextPage); } }; const formatDate = (dateString: string) => { const date = new Date(dateString); return date.toLocaleString(); }; if (error) { return (
{error}
); } return (

Events

setFilter(prev => ({ ...prev, linkId: e.target.value }))} placeholder="Enter Link ID" className="block w-full px-3 py-2 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-md text-sm text-gray-900 dark:text-gray-100" />
setFilter(prev => ({ ...prev, linkSlug: e.target.value }))} placeholder="Enter Link Slug" className="block w-full px-3 py-2 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-md text-sm text-gray-900 dark:text-gray-100" />
{Array.isArray(events) && events.map((event, index) => ( ))}
Time Type Link Visitor Location Referrer Conversion
{event.event_time && formatDate(event.event_time)} {event.event_type || 'unknown'}
{event.link_slug || '-'}
{event.link_original_url || '-'}
{event.browser || '-'}
{event.os || '-'} / {event.device_type || '-'}
{event.city || '-'}
{event.country || '-'}
{event.referrer || '-'}
{event.conversion_type || '-'}
{event.conversion_value > 0 && (
Value: {event.conversion_value}
)}
{loading && (
)} {!loading && hasMore && (
)} {!loading && Array.isArray(events) && events.length === 0 && (
No events found
)}
); }