2024-12-30 23:50:15 +01:00
import { Timeline , Tooltip , Typography } from 'antd'
import React from 'react'
2024-12-31 13:55:42 +01:00
import type { Event } from '../../utils/api'
2024-12-30 23:50:15 +01:00
import useBreakpoint from '../../hooks/useBreakpoint'
import { rdapEventDetailTranslation , rdapEventNameTranslation } from '../../utils/functions/rdapTranslation'
import { actionToColor } from '../../utils/functions/actionToColor'
import { actionToIcon } from '../../utils/functions/actionToIcon'
2025-12-10 00:46:28 +01:00
import { ThunderboltOutlined } from "@ant-design/icons"
import { t } from "ttag"
2025-12-11 13:14:13 +01:00
import type { TimeLineItemProps } from "antd/lib/timeline/TimelineItem"
2024-08-03 02:21:11 +02:00
2025-12-11 13:14:13 +01:00
function getWhoisRemoveTimelineEvent ( whoisRemoveDateEstimate : Date , withRenewalPeriod = false ) {
2025-12-10 00:46:28 +01:00
const locale = navigator . language . split ( '-' ) [ 0 ]
const sm = useBreakpoint ( 'sm' )
2025-12-11 13:14:13 +01:00
const eventName = withRenewalPeriod ? t ` Estimated removal (incl. renewal) ` : t ` Estimated removal (excl. renewal) `
const eventDetail = t ` Estimated WHOIS removal date. This is the latest date this record would be deleted, according to ICANN's standard lifecycle. Note that some registries have their own lifecycles. `
2025-12-10 00:46:28 +01:00
const dateStr =
< Typography.Text >
2025-12-11 13:14:13 +01:00
{ whoisRemoveDateEstimate . toLocaleDateString ( locale ) }
2025-12-10 00:46:28 +01:00
< / Typography.Text >
const text = sm
? {
children : < Tooltip placement = 'bottom' title = { eventDetail } >
{ eventName } & emsp ; { dateStr }
< / Tooltip >
}
: {
label : dateStr ,
children : < Tooltip placement = 'left' title = { eventDetail } > { eventName } < / Tooltip >
}
return {
2025-12-11 15:01:08 +01:00
date : whoisRemoveDateEstimate ,
color : withRenewalPeriod ? 'yellow' : 'grey' ,
2025-12-10 00:46:28 +01:00
dot : < ThunderboltOutlined style = { { fontSize : '16px' } } / > ,
pending : true ,
. . . text
}
}
2025-12-11 13:14:13 +01:00
export function EventTimeline ( { events , expiresInDays , isRenewalPeriod } : {
events : Event [ ] ,
expiresInDays? : number ,
isRenewalPeriod : boolean
} ) {
2024-07-30 06:28:00 +02:00
const sm = useBreakpoint ( 'sm' )
2025-12-11 13:14:13 +01:00
const sortedEvents = events . sort ( ( a , b ) = > new Date ( b . date ) . getTime ( ) - new Date ( a . date ) . getTime ( ) )
2024-07-29 18:41:36 +02:00
const locale = navigator . language . split ( '-' ) [ 0 ]
2024-08-20 15:22:14 +02:00
const rdapEventNameTranslated = rdapEventNameTranslation ( )
const rdapEventDetailTranslated = rdapEventDetailTranslation ( )
2025-12-11 15:01:08 +01:00
const items : ( TimeLineItemProps & { date : Date } ) [ ] = [ ]
2024-07-29 18:41:36 +02:00
2025-12-10 00:46:28 +01:00
if ( expiresInDays !== undefined ) {
2025-12-11 13:14:13 +01:00
const whoisRemoveDateEstimate = new Date ( new Date ( ) . getTime ( ) + expiresInDays * 24 * 60 * 60 * 1 e3 )
items . push ( getWhoisRemoveTimelineEvent ( whoisRemoveDateEstimate , true ) )
const expirationEvent = sortedEvents . find ( e = > ! e . deleted && e . action === 'expiration' )
const lastExpirationEvent = sortedEvents . find ( e = > e . deleted && e . action === 'expiration' )
if ( expirationEvent && lastExpirationEvent && isRenewalPeriod ) {
const date = new Date ( whoisRemoveDateEstimate . getTime ( ) - ( new Date ( expirationEvent . date ) . getTime ( ) - new Date ( lastExpirationEvent . date ) . getTime ( ) ) )
items . push ( getWhoisRemoveTimelineEvent ( date , false ) )
}
2025-12-10 00:46:28 +01:00
}
items . push (
2025-12-11 13:14:13 +01:00
. . . sortedEvents
2025-12-10 00:46:28 +01:00
. map ( e = > {
const eventName = (
< Typography.Text style = { { color : e.deleted ? 'grey' : 'default' } } >
{ rdapEventNameTranslated [ e . action as keyof typeof rdapEventNameTranslated ] || e . action }
< / Typography.Text >
)
const dateStr = (
< Typography.Text
style = { { color : e.deleted ? 'grey' : 'default' } }
> { new Date ( e . date ) . toLocaleString ( locale ) }
< / Typography.Text >
)
const eventDetail = rdapEventDetailTranslated [ e . action as keyof typeof rdapEventDetailTranslated ] || undefined
const text = sm
? {
children : < Tooltip placement = 'bottom' title = { eventDetail } >
{ eventName } & emsp ; { dateStr }
< / Tooltip >
2024-12-30 23:50:15 +01:00
}
2025-12-10 00:46:28 +01:00
: {
label : dateStr ,
children : < Tooltip placement = 'left' title = { eventDetail } > { eventName } < / Tooltip >
}
return {
2025-12-11 15:01:08 +01:00
date : new Date ( e . date ) ,
2025-12-10 00:46:28 +01:00
color : e.deleted ? 'grey' : actionToColor ( e . action ) ,
dot : actionToIcon ( e . action ) ,
pending : new Date ( e . date ) . getTime ( ) > new Date ( ) . getTime ( ) ,
. . . text
2024-08-23 21:19:34 +02:00
}
2025-12-10 00:46:28 +01:00
}
)
2024-12-30 23:50:15 +01:00
)
2025-12-10 00:46:28 +01:00
return < Timeline
mode = { sm ? 'left' : 'right' }
2025-12-11 15:01:08 +01:00
items = { items . sort ( ( a , b ) = > b . date . getTime ( ) - a . date . getTime ( ) ) }
2025-12-10 00:46:28 +01:00
/ >
2024-12-30 23:50:15 +01:00
}