'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' import { SiTorproject } from 'react-icons/si' import { FaUserSecret, FaSatellite, FaGlobe } from 'react-icons/fa' interface LocationProps { countries: Array<{ country: string; pageviews: number }> cities: Array<{ city: string; country: string; pageviews: number }> regions: Array<{ region: string; country: string; pageviews: number }> geoDataLevel?: 'full' | 'country' | 'none' } type Tab = 'map' | 'countries' | 'regions' | 'cities' const LIMIT = 7 export default function Locations({ countries, cities, regions, geoDataLevel = 'full' }: LocationProps) { const [activeTab, setActiveTab] = useState('map') const [isModalOpen, setIsModalOpen] = useState(false) const getFlagComponent = (countryCode: string) => { if (!countryCode || countryCode === 'Unknown') return null switch (countryCode) { case 'T1': return case 'A1': return case 'A2': return case 'O1': case 'EU': case 'AP': return } const FlagComponent = (Flags as any)[countryCode] return FlagComponent ? : null } const getCountryName = (code: string) => { if (!code || code === 'Unknown') return 'Unknown' switch (code) { case 'T1': return 'Tor Network' case 'A1': return 'Anonymous Proxy' case 'A2': return 'Satellite Provider' case 'O1': return 'Other' case 'EU': return 'Europe' case 'AP': return 'Asia/Pacific' } try { const regionNames = new Intl.DisplayNames(['en'], { type: 'region' }) return regionNames.of(code) || code } catch (e) { return code } } const getRegionName = (regionCode: string, countryCode: string) => { // Check for special country codes first switch (countryCode) { case 'T1': return 'Tor Network' case 'A1': return 'Anonymous Proxy' case 'A2': return 'Satellite Provider' case 'O1': return 'Other' case 'EU': return 'Europe' case 'AP': return 'Asia/Pacific' } 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 getCityName = (city: string) => { // Check for special codes that might appear in city field switch (city) { case 'T1': return 'Tor Network' case 'A1': return 'Anonymous Proxy' case 'A2': return 'Satellite Provider' case 'O1': return 'Other' } if (!city || city === 'Unknown') return 'Unknown' return city } const getData = () => { switch (activeTab) { case 'countries': return countries case 'regions': return regions case 'cities': return cities default: return [] } } // Check if the current tab's data is disabled by privacy settings const isTabDisabled = () => { if (geoDataLevel === 'none') return true if (geoDataLevel === 'country' && (activeTab === 'regions' || activeTab === 'cities')) return true return false } // Filter out "Unknown" entries that result from disabled collection const filterUnknown = (data: any[]) => { return data.filter(item => { if (activeTab === 'countries') return item.country && item.country !== 'Unknown' && item.country !== '' if (activeTab === 'regions') return item.region && item.region !== 'Unknown' && item.region !== '' if (activeTab === 'cities') return item.city && item.city !== 'Unknown' && item.city !== '' return true }) } const rawData = activeTab === 'map' ? [] : getData() const data = filterUnknown(rawData) const hasData = activeTab === 'map' ? (countries && filterUnknown(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 const getDisabledMessage = () => { if (geoDataLevel === 'none') { return 'Geographic data collection is disabled in site settings' } if (geoDataLevel === 'country' && (activeTab === 'regions' || activeTab === 'cities')) { return `${activeTab === 'regions' ? 'Region' : 'City'} tracking is disabled. Only country-level data is collected.` } return 'No data available' } return ( <>

Locations

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

{getDisabledMessage()}

) : 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) : getCityName(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) : getCityName(item.city)}
{formatNumber(item.pageviews)}
))}
) }