1
1
import React , { useMemo } from "react" ;
2
2
import styled , { useTheme } from "styled-components" ;
3
3
4
- import { responsiveSize } from "styles/responsiveSize" ;
5
-
4
+ import Skeleton from "react-loading-skeleton" ;
6
5
import { useParams } from "react-router-dom" ;
7
6
8
7
import { _TimelineItem1 , CustomTimeline } from "@kleros/ui-components-library" ;
@@ -14,14 +13,20 @@ import { Periods } from "consts/periods";
14
13
import { usePopulatedDisputeData } from "hooks/queries/usePopulatedDisputeData" ;
15
14
import { getLocalRounds } from "utils/getLocalRounds" ;
16
15
import { getVoteChoice } from "utils/getVoteChoice" ;
16
+ import { shortenTxnHash } from "utils/shortenAddress" ;
17
17
18
18
import { DisputeDetailsQuery , useDisputeDetailsQuery } from "queries/useDisputeDetailsQuery" ;
19
19
import { useVotingHistory } from "queries/useVotingHistory" ;
20
20
21
21
import { ClassicRound } from "src/graphql/graphql" ;
22
+ import { getTxnExplorerLink } from "src/utils" ;
23
+
24
+ import { responsiveSize } from "styles/responsiveSize" ;
22
25
23
26
import { StyledClosedCircle } from "components/StyledIcons/ClosedCircleIcon" ;
24
27
28
+ import { ExternalLink } from "../ExternalLink" ;
29
+
25
30
const Container = styled . div `
26
31
display: flex;
27
32
position: relative;
@@ -50,6 +55,16 @@ const StyledCalendarIcon = styled(CalendarIcon)`
50
55
height: 14px;
51
56
` ;
52
57
58
+ const LinkContainer = styled . div `
59
+ display: flex;
60
+ gap: 4px;
61
+ align-items: center;
62
+ span {
63
+ font-size: 14px;
64
+ color: ${ ( { theme } ) => theme . primaryText } ;
65
+ }
66
+ ` ;
67
+
53
68
const formatDate = ( date : string ) => {
54
69
const options : Intl . DateTimeFormatOptions = { year : "numeric" , month : "long" , day : "numeric" } ;
55
70
const startingDate = new Date ( parseInt ( date ) * 1000 ) ;
@@ -67,6 +82,9 @@ const useItems = (disputeDetails?: DisputeDetailsQuery, arbitrable?: `0x${string
67
82
const localRounds : ClassicRound [ ] = getLocalRounds ( votingHistory ?. dispute ?. disputeKitDispute ) as ClassicRound [ ] ;
68
83
const rounds = votingHistory ?. dispute ?. rounds ;
69
84
const theme = useTheme ( ) ;
85
+ const txnExplorerLink = useMemo ( ( ) => {
86
+ return getTxnExplorerLink ( votingHistory ?. dispute ?. transactionHash ?? "" ) ;
87
+ } , [ votingHistory ] ) ;
70
88
71
89
return useMemo < TimelineItems | undefined > ( ( ) => {
72
90
const dispute = disputeDetails ?. dispute ;
@@ -119,7 +137,18 @@ const useItems = (disputeDetails?: DisputeDetailsQuery, arbitrable?: `0x${string
119
137
[
120
138
{
121
139
title : "Dispute created" ,
122
- party : "" ,
140
+ party : (
141
+ < LinkContainer >
142
+ < span > at</ span >
143
+ < ExternalLink to = { txnExplorerLink } rel = "noopener noreferrer" target = "_blank" >
144
+ { votingHistory ?. dispute ?. transactionHash ? (
145
+ shortenTxnHash ( votingHistory ?. dispute ?. transactionHash )
146
+ ) : (
147
+ < Skeleton height = { 16 } width = { 56 } />
148
+ ) }
149
+ </ ExternalLink >
150
+ </ LinkContainer >
151
+ ) ,
123
152
subtitle : formatDate ( votingHistory ?. dispute ?. createdAt ) ,
124
153
rightSided : true ,
125
154
variant : theme . secondaryPurple ,
@@ -128,7 +157,7 @@ const useItems = (disputeDetails?: DisputeDetailsQuery, arbitrable?: `0x${string
128
157
) ;
129
158
}
130
159
return ;
131
- } , [ disputeDetails , disputeData , localRounds , theme ] ) ;
160
+ } , [ disputeDetails , disputeData , localRounds , theme , rounds , votingHistory , txnExplorerLink ] ) ;
132
161
} ;
133
162
134
163
interface IDisputeTimeline {
@@ -138,15 +167,30 @@ interface IDisputeTimeline {
138
167
const DisputeTimeline : React . FC < IDisputeTimeline > = ( { arbitrable } ) => {
139
168
const { id } = useParams ( ) ;
140
169
const { data : disputeDetails } = useDisputeDetailsQuery ( id ) ;
170
+ const { data : votingHistory } = useVotingHistory ( id ) ;
141
171
const items = useItems ( disputeDetails , arbitrable ) ;
142
172
173
+ const transactionExplorerLink = useMemo ( ( ) => {
174
+ return getTxnExplorerLink ( disputeDetails ?. dispute ?. rulingTransactionHash ?? "" ) ;
175
+ } , [ disputeDetails ] ) ;
176
+
143
177
return (
144
178
< Container >
145
179
{ items && < StyledTimeline { ...{ items } } /> }
146
- { disputeDetails ?. dispute ?. ruled && items && (
180
+ { disputeDetails ?. dispute ?. ruled && (
147
181
< EnforcementContainer >
148
182
< StyledCalendarIcon />
149
- < small > Enforcement: { items . at ( - 1 ) ?. subtitle } </ small >
183
+ < small >
184
+ Enforcement:{ " " }
185
+ { disputeDetails . dispute . rulingTimestamp ? (
186
+ < ExternalLink to = { transactionExplorerLink } rel = "noopener noreferrer" target = "_blank" >
187
+ { formatDate ( disputeDetails . dispute . rulingTimestamp ) }
188
+ </ ExternalLink >
189
+ ) : (
190
+ < Skeleton height = { 16 } width = { 56 } />
191
+ ) } { " " }
192
+ / { votingHistory ?. dispute ?. rounds . at ( - 1 ) ?. court . name }
193
+ </ small >
150
194
</ EnforcementContainer >
151
195
) }
152
196
</ Container >
0 commit comments