'use client' import { useState, useEffect } from 'react' import Image from 'next/image' import { formatNumber } from '@ciphera-net/ui' import { getReferrerDisplayName, getReferrerFavicon, getReferrerIcon, mergeReferrersByDisplayName } from '@/lib/utils/icons' import { Modal, GlobeIcon } from '@ciphera-net/ui' import { ListSkeleton } from '@/components/skeletons' import { getTopReferrers, TopReferrer } from '@/lib/api/stats' interface TopReferrersProps { referrers: Array<{ referrer: string; pageviews: number }> collectReferrers?: boolean siteId: string dateRange: { start: string, end: string } } const LIMIT = 7 export default function TopReferrers({ referrers, collectReferrers = true, siteId, dateRange }: TopReferrersProps) { const [isModalOpen, setIsModalOpen] = useState(false) const [fullData, setFullData] = useState([]) const [isLoadingFull, setIsLoadingFull] = useState(false) const [faviconFailed, setFaviconFailed] = useState>(new Set()) // Filter out empty/unknown referrers const filteredReferrers = (referrers || []).filter( ref => ref.referrer && ref.referrer !== 'Unknown' && ref.referrer !== '' ) const mergedReferrers = mergeReferrersByDisplayName(filteredReferrers) const hasData = mergedReferrers.length > 0 const displayedReferrers = hasData ? mergedReferrers.slice(0, LIMIT) : [] const emptySlots = Math.max(0, LIMIT - displayedReferrers.length) const showViewAll = hasData && mergedReferrers.length > LIMIT function renderReferrerIcon(referrer: string) { const faviconUrl = getReferrerFavicon(referrer) const useFavicon = faviconUrl && !faviconFailed.has(referrer) if (useFavicon) { return ( setFaviconFailed((prev) => new Set(prev).add(referrer))} unoptimized /> ) } return {getReferrerIcon(referrer)} } useEffect(() => { if (isModalOpen) { const fetchData = async () => { setIsLoadingFull(true) try { const data = await getTopReferrers(siteId, dateRange.start, dateRange.end, 100) // Filter fetched data too const filtered = (data || []).filter( ref => ref.referrer && ref.referrer !== 'Unknown' && ref.referrer !== '' ) setFullData(filtered) } catch (e) { console.error(e) } finally { setIsLoadingFull(false) } } fetchData() } else { setFullData([]) } }, [isModalOpen, siteId, dateRange]) return ( <>

Top Referrers

{showViewAll && ( )}
{!collectReferrers ? (

Referrer tracking is disabled in site settings

) : hasData ? ( <> {displayedReferrers.map((ref, index) => (
{renderReferrerIcon(ref.referrer)} {getReferrerDisplayName(ref.referrer)}
{formatNumber(ref.pageviews)}
))} {Array.from({ length: emptySlots }).map((_, i) => (
setIsModalOpen(false)} title="Top Referrers" >
{isLoadingFull ? (
) : ( mergeReferrersByDisplayName(fullData.length > 0 ? fullData : filteredReferrers).map((ref, index) => (
{renderReferrerIcon(ref.referrer)} {getReferrerDisplayName(ref.referrer)}
{formatNumber(ref.pageviews)}
)) )}
) }