'use client' import { useState } from 'react' import { formatNumber } from '@/lib/utils/format' import * as Flags from 'country-flag-icons/react/3x2' // @ts-ignore import iso3166 from 'iso-3166-2' import WorldMap from './WorldMap' import { Modal } from '@ciphera-net/ui' interface LocationProps { countries: Array<{ country: string; pageviews: number }> cities: Array<{ city: string; country: string; pageviews: number }> regions: Array<{ region: string; country: string; pageviews: number }> } type Tab = 'map' | 'countries' | 'regions' | 'cities' const LIMIT = 7 export default function Locations({ countries, cities, regions }: LocationProps) { const [activeTab, setActiveTab] = useState('map') const [isModalOpen, setIsModalOpen] = useState(false) const getFlagComponent = (countryCode: string) => { if (!countryCode || countryCode === 'Unknown') return null const FlagComponent = (Flags as any)[countryCode] return FlagComponent ? : null } const getCountryName = (code: string) => { if (!code || code === 'Unknown') return 'Unknown' try { const regionNames = new Intl.DisplayNames(['en'], { type: 'region' }) return regionNames.of(code) || code } catch (e) { return code } } const getRegionName = (regionCode: string, countryCode: string) => { if (!regionCode || regionCode === 'Unknown' || !countryCode || countryCode === 'Unknown') return 'Unknown' try { const countryData = iso3166.data[countryCode] if (!countryData || !countryData.sub) return regionCode // ISO 3166-2 structure keys are typically "US-OR" const fullCode = `${countryCode}-${regionCode}` const regionData = countryData.sub[fullCode] if (regionData && regionData.name) { return regionData.name } return regionCode } catch (e) { return regionCode } } const getData = () => { switch (activeTab) { case 'countries': return countries case 'regions': return regions case 'cities': return cities default: return [] } } const data = activeTab === 'map' ? [] : getData() const hasData = activeTab === 'map' ? (countries && countries.length > 0) : (data && data.length > 0) const displayedData = (activeTab !== 'map' && hasData) ? (data as any[]).slice(0, LIMIT) : [] const emptySlots = Math.max(0, LIMIT - displayedData.length) const showViewAll = activeTab !== 'map' && hasData && data.length > LIMIT return ( <>

Locations

{showViewAll && ( )}
{(['map', 'countries', 'regions', 'cities'] as Tab[]).map((tab) => ( ))}
{activeTab === 'map' ? ( hasData ? : (

No data available

) ) : ( hasData ? ( <> {displayedData.map((item, index) => (
{activeTab === 'countries' && {getFlagComponent(item.country)}} {activeTab !== 'countries' && {getFlagComponent(item.country)}} {activeTab === 'countries' ? getCountryName(item.country) : activeTab === 'regions' ? getRegionName(item.region, item.country) : (item.city === 'Unknown' ? 'Unknown' : item.city)}
{formatNumber(item.pageviews)}
))} {Array.from({ length: emptySlots }).map((_, i) => (
setIsModalOpen(false)} title={`Locations - ${activeTab.charAt(0).toUpperCase() + activeTab.slice(1)}`} >
{(data as any[]).map((item, index) => (
{getFlagComponent(item.country)} {activeTab === 'countries' ? getCountryName(item.country) : activeTab === 'regions' ? getRegionName(item.region, item.country) : (item.city === 'Unknown' ? 'Unknown' : item.city)}
{formatNumber(item.pageviews)}
))}
) }