'use client' import { useState, useEffect } from 'react' import { formatNumber } from '@ciphera-net/ui' import { getBrowserIcon, getOSIcon, getDeviceIcon } from '@/lib/utils/icons' import { MdMonitor } from 'react-icons/md' import { Modal, GridIcon } from '@ciphera-net/ui' import { ListSkeleton } from '@/components/skeletons' import { getBrowsers, getOS, getDevices, getScreenResolutions } from '@/lib/api/stats' interface TechSpecsProps { browsers: Array<{ browser: string; pageviews: number }> os: Array<{ os: string; pageviews: number }> devices: Array<{ device: string; pageviews: number }> screenResolutions: Array<{ screen_resolution: string; pageviews: number }> collectDeviceInfo?: boolean collectScreenResolution?: boolean siteId: string dateRange: { start: string, end: string } } type Tab = 'browsers' | 'os' | 'devices' | 'screens' const LIMIT = 7 export default function TechSpecs({ browsers, os, devices, screenResolutions, collectDeviceInfo = true, collectScreenResolution = true, siteId, dateRange }: TechSpecsProps) { const [activeTab, setActiveTab] = useState('browsers') const [isModalOpen, setIsModalOpen] = useState(false) type TechItem = { name: string; pageviews: number; icon: React.ReactNode } const [fullData, setFullData] = useState([]) const [isLoadingFull, setIsLoadingFull] = useState(false) // Filter out "Unknown" entries that result from disabled collection const filterUnknown = (items: Array<{ name: string; pageviews: number; icon: React.ReactNode }>) => { return items.filter(item => item.name && item.name !== 'Unknown' && item.name !== '') } useEffect(() => { if (isModalOpen) { const fetchData = async () => { setIsLoadingFull(true) try { let data: TechItem[] = [] if (activeTab === 'browsers') { const res = await getBrowsers(siteId, dateRange.start, dateRange.end, 100) data = res.map(b => ({ name: b.browser, pageviews: b.pageviews, icon: getBrowserIcon(b.browser) })) } else if (activeTab === 'os') { const res = await getOS(siteId, dateRange.start, dateRange.end, 100) data = res.map(o => ({ name: o.os, pageviews: o.pageviews, icon: getOSIcon(o.os) })) } else if (activeTab === 'devices') { const res = await getDevices(siteId, dateRange.start, dateRange.end, 100) data = res.map(d => ({ name: d.device, pageviews: d.pageviews, icon: getDeviceIcon(d.device) })) } else if (activeTab === 'screens') { const res = await getScreenResolutions(siteId, dateRange.start, dateRange.end, 100) data = res.map(s => ({ name: s.screen_resolution, pageviews: s.pageviews, icon: })) } setFullData(filterUnknown(data)) } catch (e) { console.error(e) } finally { setIsLoadingFull(false) } } fetchData() } else { setFullData([]) } }, [isModalOpen, activeTab, siteId, dateRange]) const getRawData = () => { switch (activeTab) { case 'browsers': return browsers.map(b => ({ name: b.browser, pageviews: b.pageviews, icon: getBrowserIcon(b.browser) })) case 'os': return os.map(o => ({ name: o.os, pageviews: o.pageviews, icon: getOSIcon(o.os) })) case 'devices': return devices.map(d => ({ name: d.device, pageviews: d.pageviews, icon: getDeviceIcon(d.device) })) case 'screens': return screenResolutions.map(s => ({ name: s.screen_resolution, pageviews: s.pageviews, icon: })) default: return [] } } // Check if current tab is disabled by privacy settings const isTabDisabled = () => { if (!collectDeviceInfo && (activeTab === 'browsers' || activeTab === 'os' || activeTab === 'devices')) { return true } if (!collectScreenResolution && activeTab === 'screens') { return true } return false } const getDisabledMessage = () => { if (!collectDeviceInfo && (activeTab === 'browsers' || activeTab === 'os' || activeTab === 'devices')) { return 'Device info collection is disabled in site settings' } if (!collectScreenResolution && activeTab === 'screens') { return 'Screen resolution collection is disabled in site settings' } return 'No data available' } const rawData = getRawData() const data = filterUnknown(rawData) const hasData = data && 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 ( <>

Technology

{showViewAll && ( )}
{(['browsers', 'os', 'devices', 'screens'] as Tab[]).map((tab) => ( ))}
{isTabDisabled() ? (

{getDisabledMessage()}

) : hasData ? ( <> {displayedData.map((item, index) => (
{item.icon && {item.icon}} {item.name}
{formatNumber(item.pageviews)}
))} {Array.from({ length: emptySlots }).map((_, i) => (
setIsModalOpen(false)} title={`Technology - ${activeTab.charAt(0).toUpperCase() + activeTab.slice(1)}`} >
{isLoadingFull ? (
) : ( (fullData.length > 0 ? fullData : data).map((item, index) => (
{item.icon && {item.icon}} {item.name === 'Unknown' ? 'Unknown' : item.name}
{formatNumber(item.pageviews)}
)) )}
) }