'use client' import { useState, useEffect } from 'react' import { formatNumber } from '@/lib/utils/format' import { Modal } from '@ciphera-net/ui' import { getCampaigns, CampaignStat } from '@/lib/api/stats' interface CampaignsProps { siteId: string dateRange: { start: string, end: string } } const LIMIT = 7 export default function Campaigns({ siteId, dateRange }: CampaignsProps) { const [data, setData] = useState([]) const [isLoading, setIsLoading] = useState(true) const [isModalOpen, setIsModalOpen] = useState(false) const [fullData, setFullData] = useState([]) const [isLoadingFull, setIsLoadingFull] = useState(false) useEffect(() => { const fetchData = async () => { setIsLoading(true) try { const result = await getCampaigns(siteId, dateRange.start, dateRange.end) setData(result) } catch (e) { console.error(e) } finally { setIsLoading(false) } } fetchData() }, [siteId, dateRange]) useEffect(() => { if (isModalOpen) { const fetchFullData = async () => { setIsLoadingFull(true) try { const result = await getCampaigns(siteId, dateRange.start, dateRange.end) setFullData(result) } catch (e) { console.error(e) } finally { setIsLoadingFull(false) } } fetchFullData() } else { setFullData([]) } }, [isModalOpen, siteId, dateRange]) const hasData = data.length > 0 const displayedData = hasData ? data.slice(0, LIMIT) : [] const emptySlots = Math.max(0, LIMIT - displayedData.length) const showViewAll = hasData && data.length > LIMIT return ( <>

Campaigns

{showViewAll && ( )}
{isLoading ? (

Loading...

) : hasData ? ( <>
Source
Medium
Campaign
Visitors
{displayedData.map((item, index) => (
{item.source}
{item.medium || '-'}
{item.campaign || '-'}
{formatNumber(item.visitors)}
))} {Array.from({ length: emptySlots }).map((_, i) => (
setIsModalOpen(false)} title="All Campaigns" >
{isLoadingFull ? (
Loading...
) : ( <>
Source
Medium
Campaign
Visitors
{(fullData.length > 0 ? fullData : data).map((item, index) => (
{item.source}
{item.medium || '-'}
{item.campaign || '-'}
{formatNumber(item.visitors)}
))} )}
) }