feat: add ICANN accreditation status on domain result page

This commit is contained in:
Maël Gangloff
2025-09-15 23:04:28 +02:00
parent b1566bbeac
commit c4f79bece8
12 changed files with 338 additions and 153 deletions

View File

@@ -1,11 +1,16 @@
import {Flex, List, Tag, Tooltip, Typography} from 'antd'
import {Flex, List, Tag, Tooltip} from 'antd'
import React from 'react'
import type {Domain} from '../../utils/api'
import {rdapRoleDetailTranslation, rdapRoleTranslation} from '../../utils/functions/rdapTranslation'
import {
icannAccreditationTranslation,
rdapRoleDetailTranslation,
rdapRoleTranslation
} from '../../utils/functions/rdapTranslation'
import {roleToAvatar} from '../../utils/functions/roleToAvatar'
import {rolesToColor} from '../../utils/functions/rolesToColor'
import {sortDomainEntities} from '../../utils/functions/sortDomainEntities'
import {extractDetailsFromJCard} from '../../utils/functions/extractDetailsFromJCard'
import {CheckCircleOutlined, CloseCircleOutlined, SettingOutlined} from "@ant-design/icons"
export function EntitiesList({domain}: { domain: Domain }) {
const rdapRoleTranslated = rdapRoleTranslation()
@@ -27,11 +32,28 @@ export function EntitiesList({domain}: { domain: Domain }) {
dataSource={sortDomainEntities(domain)}
renderItem={(e) => {
const details = extractDetailsFromJCard(e)
const icannAccreditationTranslated = icannAccreditationTranslation()
const status = e.entity.icannAccreditation?.status as ('Terminated' | 'Accredited' | 'Reserved' | undefined)
return <List.Item>
<List.Item.Meta
avatar={roleToAvatar(e)}
title={<Typography.Text code>{e.entity.handle}</Typography.Text>}
title={<Flex gap='small'>
<Tag>{e.entity.handle}</Tag>
{
e.entity.icannAccreditation && status && <Tooltip
title={e.entity.icannAccreditation.registrarName + " (" + icannAccreditationTranslated[status] + ")"}>
<Tag icon={
status === 'Terminated' ? <CloseCircleOutlined /> :
status === 'Accredited' ? <CheckCircleOutlined/> : <SettingOutlined/>
} color={
status === 'Terminated' ? 'red' :
status === 'Accredited' ? 'green' : 'yellow'
}>{e.entity.icannAccreditation.id}</Tag>
</Tooltip>
}
</Flex>}
description={<>
{details.fn && <div>👤 {details.fn}</div>}
{details.organization && <div>🏢 {details.organization}</div>}

View File

@@ -9,12 +9,12 @@ import {getIcannAccreditations} from "../../utils/api/icann-accreditations"
const {Text, Paragraph} = Typography
interface FiltersType {
'icannAccreditation.status': 'Accredited' | 'Reserved' | 'Terminated',
status: 'Accredited' | 'Reserved' | 'Terminated',
}
function RegistrarListTable(filters: FiltersType) {
interface TableRow {
key: string
key: number
handle: number
name: string
}
@@ -26,9 +26,9 @@ function RegistrarListTable(filters: FiltersType) {
getIcannAccreditations(params).then((data) => {
setTotal(data['hydra:totalItems'])
setDataTable(data['hydra:member'].map((accreditation: IcannAccreditation) => ({
key: accreditation.handle,
handle: parseInt(accreditation.handle),
name: accreditation.icannAccreditation.registrarName
key: accreditation.id,
handle: accreditation.id,
name: accreditation.registrarName
})
).sort((a, b) => a.handle - b.handle))
})
@@ -76,17 +76,17 @@ export default function IcannRegistrarPage() {
Accredited: <>
<Text>{t`An accredited number means that ICANN's contract with the registrar is ongoing.`}</Text>
<Divider/>
<RegistrarListTable {...{'icannAccreditation.status': 'Accredited'}} />
<RegistrarListTable status='Accredited' />
</>,
Reserved: <>
<Text>{t`A reserved number can be used by TLD registries for specific operations.`}</Text>
<Divider/>
<RegistrarListTable {...{'icannAccreditation.status': 'Reserved'}} />
<RegistrarListTable status='Reserved' />
</>,
Terminated: <>
<Text>{t`A terminated number means that ICANN's contract with the registrar has been terminated.`}</Text>
<Divider/>
<RegistrarListTable {...{'icannAccreditation.status': 'Terminated'}} />
<RegistrarListTable status='Terminated' />
</>
}

View File

@@ -8,7 +8,7 @@ interface IcannAccreditationList {
export async function getIcannAccreditations(params: object): Promise<IcannAccreditationList> {
return (await request<IcannAccreditationList>({
url: 'entities/icann-accreditations',
url: 'icann-accreditations',
params
})).data
}

View File

@@ -32,6 +32,11 @@ export interface Entity {
string,
string | string[],
]>] | []
remarks?: {
type: string
description: string
}[]
icannAccreditation?: IcannAccreditation
}
export interface Nameserver {
@@ -125,13 +130,11 @@ export interface TrackedDomains {
}
export interface IcannAccreditation {
handle: string
icannAccreditation: {
registrarName: string
status: string
date?: string
updated?: string
}
id: number
registrarName: string
status: string
date?: string
updated?: string
}
export async function request<T = object, R = AxiosResponse<T>, D = object>(config: AxiosRequestConfig): Promise<R> {

View File

@@ -113,3 +113,10 @@ export const rdapStatusCodeDetailTranslation = () => ({
administrative: t`The object instance has been allocated administratively (i.e., not for use by the recipient in their own right in operational networks).`,
reserved: t`The object instance has been allocated to an IANA special-purpose address registry.`
})
export const icannAccreditationTranslation = () => ({
Terminated: t`Terminated`,
Accredited: t`Accredited`,
Reserved: t`Reserved`
})