import { forwardRef } from 'react'; import { Icon, Text, Box, Tooltip, Menu, MenuButton, MenuList } from '@chakra-ui/react'; import { CgMoreO as More } from '@meronex/icons/cg'; import { BisError as Warning } from '@meronex/icons/bi'; import { MdNotInterested as NotAllowed } from '@meronex/icons/md'; import { RiHome2Fill as End } from '@meronex/icons/ri'; import { BsQuestionCircleFill as Question } from '@meronex/icons/bs'; import { FaCheckCircle as Check, FaChevronRight as ChevronRight } from '@meronex/icons/fa'; import dayjs from 'dayjs'; import relativeTimePlugin from 'dayjs/plugin/relativeTime'; import utcPlugin from 'dayjs/plugin/utc'; import { If } from '~/components'; import { useConfig, useColorValue } from '~/context'; import { useOpposingColor } from '~/hooks'; import type { TAge, TActive, TWeight, TASPath, TMonoField, TRPKIState, TCommunities, } from './types'; dayjs.extend(relativeTimePlugin); dayjs.extend(utcPlugin); export const MonoField = (props: TMonoField) => { const { v, ...rest } = props; return ( {v} ); }; export const Active = (props: TActive) => { const { isActive } = props; const color = useColorValue(['gray.500', 'green.500'], ['whiteAlpha.300', 'blackAlpha.500']); return ( <> ); }; export const Age = (props: TAge) => { const { inSeconds, ...rest } = props; const now = dayjs.utc(); const then = now.subtract(inSeconds, 'second'); return ( {now.to(then, true)} ); }; export const Weight = (props: TWeight) => { const { weight, winningWeight, ...rest } = props; const fixMeText = winningWeight === 'low' ? 'Lower Weight is Preferred' : 'Higher Weight is Preferred'; return ( {weight} ); }; export const ASPath = (props: TASPath) => { const { path, active } = props; const color = useColorValue( // light: inactive, active ['blackAlpha.500', 'blackAlpha.500'], // dark: inactive, active ['whiteAlpha.600', 'blackAlpha.700'], ); if (path.length === 0) { return ; } let paths = [] as JSX.Element[]; path.map((asn, i) => { const asnStr = String(asn); i !== 0 && paths.push( , ); paths.push( {asnStr} , ); }); return <>{paths}; }; export const Communities = (props: TCommunities) => { const { communities } = props; const bg = useColorValue('white', 'gray.900'); const color = useOpposingColor(bg); return ( <> {communities.join('\n')} ); }; export const RPKIState = forwardRef((props, ref) => { const { state, active } = props; const { web } = useConfig(); const bg = useColorValue( [ ['red.400', 'green.500', 'yellow.400', 'gray.500'], ['red.500', 'green.500', 'yellow.500', 'gray.600'], ], [ ['red.300', 'green.300', 'yellow.300', 'gray.300'], ['red.500', 'green.600', 'yellow.500', 'gray.800'], ], ); const color = useOpposingColor(bg[+active][state]); const icon = [NotAllowed, Check, Warning, Question]; const text = [ web.text.rpki_invalid, web.text.rpki_valid, web.text.rpki_unknown, web.text.rpki_unverified, ]; return ( ); });