2024-12-31 13:55:42 +01:00
import type { ReactElement } from 'react'
2025-02-19 10:10:33 +01:00
import React , { useEffect , useState } from 'react'
import { Card , Divider , Table , Typography } from 'antd'
import type { Tld } from '../../utils/api'
2024-12-31 13:55:42 +01:00
import { getTldList } from '../../utils/api'
2024-07-28 15:36:22 +02:00
import { t } from 'ttag'
2024-12-30 23:50:15 +01:00
import { regionNames } from '../../i18n'
2024-12-31 13:55:42 +01:00
import type { ColumnType } from 'antd/es/table'
2024-12-30 23:50:15 +01:00
import punycode from 'punycode/punycode'
import { getCountryCode } from '../../utils/functions/getCountryCode'
import { tldToEmoji } from '../../utils/functions/tldToEmoji'
2025-02-19 10:10:33 +01:00
import { BankOutlined , FlagOutlined , GlobalOutlined , TrademarkOutlined } from "@ant-design/icons"
2025-09-14 18:09:04 +02:00
import { Link } from "react-router-dom"
2025-10-31 23:13:45 +01:00
import useBreakpoint from "../../hooks/useBreakpoint"
2024-07-26 23:55:12 +02:00
const { Text , Paragraph } = Typography
type TldType = 'iTLD' | 'sTLD' | 'gTLD' | 'ccTLD'
2024-12-30 23:50:15 +01:00
interface FiltersType {
type : TldType ,
contractTerminated? : boolean ,
specification13? : boolean
}
2024-07-26 23:55:12 +02:00
function TldTable ( filters : FiltersType ) {
2024-12-30 23:50:15 +01:00
interface TableRow {
key : string
TLD : ReactElement
Flag? : string
Country? : string
}
2025-10-31 23:02:38 +01:00
const sm = useBreakpoint ( 'sm' )
2024-12-30 23:50:15 +01:00
const [ dataTable , setDataTable ] = useState < TableRow [ ] > ( [ ] )
2024-07-26 23:55:12 +02:00
const [ total , setTotal ] = useState ( 0 )
2024-07-30 23:32:22 +02:00
const fetchData = ( params : FiltersType & { page : number , itemsPerPage : number } ) = > {
2024-07-26 23:55:12 +02:00
getTldList ( params ) . then ( ( data ) = > {
setTotal ( data [ 'hydra:totalItems' ] )
setDataTable ( data [ 'hydra:member' ] . map ( ( tld : Tld ) = > {
2024-08-02 22:31:04 +02:00
const rowData = {
key : tld.tld ,
2025-09-14 17:59:26 +02:00
TLD : < Link to = { '/search/domain/' + tld . tld } > < Typography.Text code > { punycode . toUnicode ( tld . tld ) } < / Typography.Text > < / Link >
2024-08-02 22:31:04 +02:00
}
2024-12-30 23:50:15 +01:00
const type = filters . type
let countryName
switch ( type ) {
2024-07-26 23:55:12 +02:00
case 'ccTLD' :
2024-07-30 23:32:22 +02:00
try {
countryName = regionNames . of ( getCountryCode ( tld . tld ) )
2024-12-30 23:50:15 +01:00
} catch {
2024-07-30 23:32:22 +02:00
countryName = '-'
}
2024-07-26 23:55:12 +02:00
return {
2024-08-02 22:31:04 +02:00
. . . rowData ,
2024-08-22 01:44:50 +02:00
Flag : tldToEmoji ( tld . tld ) ,
2024-07-30 23:32:22 +02:00
Country : countryName
2024-07-26 23:55:12 +02:00
}
case 'gTLD' :
return {
2024-08-02 22:31:04 +02:00
. . . rowData ,
2024-07-26 23:55:12 +02:00
Operator : tld.registryOperator
}
default :
2024-08-02 22:31:04 +02:00
return rowData
2024-07-26 23:55:12 +02:00
}
} ) )
} )
}
useEffect ( ( ) = > {
2024-07-30 23:32:22 +02:00
fetchData ( { . . . filters , page : 1 , itemsPerPage : 30 } )
2024-07-26 23:55:12 +02:00
} , [ ] )
2024-12-30 23:50:15 +01:00
let columns : Array < ColumnType < TableRow > > = [
2024-07-26 23:55:12 +02:00
{
2024-07-28 15:36:22 +02:00
title : t ` TLD ` ,
2024-12-30 23:50:15 +01:00
dataIndex : 'TLD'
2024-07-26 23:55:12 +02:00
}
]
2024-12-30 23:50:15 +01:00
if ( filters . type === 'ccTLD' ) {
columns = [ . . . columns , {
title : t ` Flag ` ,
dataIndex : 'Flag'
} , {
title : t ` Country ` ,
dataIndex : 'Country'
} ]
}
if ( filters . type === 'gTLD' ) {
columns = [ . . . columns , {
title : t ` Registry Operator ` ,
dataIndex : 'Operator'
} ]
}
return (
< Table
columns = { columns }
dataSource = { dataTable }
pagination = { {
total ,
hideOnSinglePage : true ,
defaultPageSize : 30 ,
onChange : ( page , itemsPerPage ) = > {
fetchData ( { . . . filters , page , itemsPerPage } )
}
} }
2025-10-31 23:02:38 +01:00
scroll = { sm ? { } : { y : '50vh' } }
size = { sm ? 'small' : 'large' }
2024-12-30 23:50:15 +01:00
/ >
)
}
2024-07-26 16:45:10 +02:00
export default function TldPage() {
2025-02-19 10:10:33 +01:00
const [ activeTabKey , setActiveTabKey ] = useState < string > ( 'gTLD' )
2025-10-31 23:02:38 +01:00
const sm = useBreakpoint ( "sm" )
2025-02-19 10:10:33 +01:00
const contentList : Record < string , React.ReactNode > = {
sTLD : < >
< Text > { t ` Top-level domains sponsored by specific organizations that set rules for registration and use, often related to particular interest groups or industries. ` } < / Text >
< Divider / >
< TldTable type = 'sTLD' / >
< / > ,
gTLD : < >
< Text > { t ` Generic top-level domains open to everyone, not restricted by specific criteria, representing various themes or industries. ` } < / Text >
< Divider / >
< TldTable type = 'gTLD' contractTerminated = { false } specification13 = { false } / >
< / > ,
ngTLD : < >
< Text > { t ` Generic top-level domains associated with specific brands, allowing companies to use their own brand names as domains. ` } < / Text >
< Divider / >
< TldTable type = 'gTLD' contractTerminated = { false } specification13 / >
< / > ,
ccTLD : < >
< Text > { t ` Top-level domains based on country codes, identifying websites according to their country of origin. ` } < / Text >
< Divider / >
< TldTable type = 'ccTLD' / >
< / >
}
2024-07-30 23:32:22 +02:00
2024-12-30 23:50:15 +01:00
return (
< >
< Paragraph >
{ t ` This page presents all active TLDs in the root zone database. ` }
< / Paragraph >
< Paragraph >
{ t ` IANA provides the list of currently active TLDs, regardless of their type, and ICANN provides the list of gTLDs.
2024-07-28 15:36:22 +02:00
In most cases , the two - letter ccTLD assigned to a country is made in accordance with the ISO 3166 - 1 standard .
This data is updated every month . Three HTTP requests are needed for the complete update of TLDs in Domain Watchdog ( two requests to IANA and one to ICANN ) .
At the same time , the list of root RDAP servers is updated . ` }
2024-12-30 23:50:15 +01:00
< / Paragraph >
< Divider / >
2025-02-19 10:10:33 +01:00
< Card
style = { { width : '100%' } }
tabProps = { {
size : 'middle' ,
} }
tabList = { [
2024-12-30 23:50:15 +01:00
{
key : 'gTLD' ,
label : t ` Generic Top-Level-Domains ` ,
2025-02-19 10:10:33 +01:00
icon : < GlobalOutlined / >
} ,
{
key : 'ccTLD' ,
label : t ` Country-Code Top-Level-Domains ` ,
icon : < FlagOutlined / >
2024-12-30 23:50:15 +01:00
} ,
{
key : 'ngTLD' ,
label : t ` Brand Generic Top-Level-Domains ` ,
2025-02-19 10:10:33 +01:00
icon : < TrademarkOutlined / >
2024-12-30 23:50:15 +01:00
} ,
{
2025-02-19 10:10:33 +01:00
key : 'sTLD' ,
label : t ` Sponsored Top-Level-Domains ` ,
icon : < BankOutlined / >
} ,
2024-12-30 23:50:15 +01:00
] }
2025-02-19 10:10:33 +01:00
activeTabKey = { activeTabKey }
key = { activeTabKey }
onTabChange = { ( k : string ) = > setActiveTabKey ( k ) }
2025-10-31 23:02:38 +01:00
size = { sm ? 'small' : 'default' }
2025-02-19 10:10:33 +01:00
>
{ contentList [ activeTabKey ] }
< / Card >
2024-12-30 23:50:15 +01:00
< / >
)
}