on df0c310 help sign in
bridge/src/views/Transactions/TransactionRow.tsx
116 lines 3.0 kB history raw
1import { useMemo } from 'react';
2import cn from 'classnames';
3import { Box, Icon, Row } from '@tlon/indigo-react';
4import { RollerTransaction } from '@urbit/roller-api';
5import { format, fromUnixTime } from 'date-fns';
7import { useTimerStore } from 'store/timerStore';
8import {
9 TRANSACTION_STATUS_ICONS,
10 TRANSACTION_TYPE_ICONS,
11 TRANSACTION_TYPE_TITLES,
12} from 'lib/constants';
13import { abbreviateAddress } from 'lib/utils/address';
14import { titleize } from 'form/formatters';
15import LayerIndicator from 'components/L2/LayerIndicator';
16import { useExploreTxUrl } from 'lib/explorer';
18interface TransactionRowProps extends RollerTransaction {
19 className?: string;
20 layer?: 1 | 2;
23export const TransactionRow = ({
24 className = '',
25 ship,
26 type = '',
27 hash,
28 status = 'pending',
29 time,
30 layer = 2,
31}: TransactionRowProps) => {
32 const { nextRoll } = useTimerStore();
34 const label = useMemo(() => {
35 return TRANSACTION_TYPE_TITLES[type] || type;
36 }, [type]);
38 const icon = useMemo(() => {
39 return <Icon icon={TRANSACTION_TYPE_ICONS[type] || 'Bug'} />;
40 }, [type]);
42 const shortHash = useMemo(() => {
43 return hash ? abbreviateAddress(hash) : '';
44 }, [hash]);
46 const parsedDate = useMemo(() => {
47 if (!time) {
48 return null;
49 }
51 return fromUnixTime(time / 1000);
52 }, [time]);
54 const shortDate = useMemo(() => {
55 if (!parsedDate) {
56 return null;
57 }
59 return format(parsedDate, 'MMMM dd');
60 }, [parsedDate]);
62 const longDate = useMemo(() => {
63 if (!parsedDate) {
64 return;
65 }
67 return parsedDate.toISOString();
68 }, [parsedDate]);
70 const statusBadge = useMemo(() => {
71 return (
72 <div className={cn(['badge', status])}>
73 <span className={'icon-wrapper'}>
74 <Icon icon={TRANSACTION_STATUS_ICONS[status] || 'Bug'} />
75 </span>
76 <span>
77 {status === 'pending' && layer === 2 ? nextRoll : titleize(status)}
78 </span>
79 </div>
80 );
81 }, [nextRoll, status, layer]);
83 const txHash = useExploreTxUrl(hash);
85 return (
86 <Box className={`transaction-row ${className}`}>
87 <Box className="icon">{icon}</Box>
88 <Box className="info">
89 <Row className="title-row">
90 <Box className="title">{label}</Box>
91 <Box className="status">{statusBadge}</Box>
92 </Row>
93 <Row className="info-row">
94 <Box className="hash-container">
95 {layer === 1 ? (
96 <a
97 className="etherscan"
98 href={txHash}
99 rel="noreferrer"
100 target="_blank">
101 Etherscan
102 <Icon className="arrow" icon="ArrowEast" />
103 </a>
104 ) : (
105 !!hash && <Box className="hash">{shortHash}</Box>
106 )}
107 <LayerIndicator layer={layer} size={'sm'} />
108 </Box>
109 <Box className="date" title={longDate}>
110 {shortDate}
111 </Box>
112 </Row>
113 </Box>
114 </Box>
115 );
116};