11import  React ,  {  useMemo  }  from  "react" ; 
22import  styled ,  {  useTheme  }  from  "styled-components" ; 
33
4- import  {  responsiveSize  }  from  "styles/responsiveSize" ; 
5- 
4+ import  Skeleton  from  "react-loading-skeleton" ; 
65import  {  useParams  }  from  "react-router-dom" ; 
76
87import  {  _TimelineItem1 ,  CustomTimeline  }  from  "@kleros/ui-components-library" ; 
98
109import  CalendarIcon  from  "svgs/icons/calendar.svg" ; 
1110import  ClosedCaseIcon  from  "svgs/icons/check-circle-outline.svg" ; 
11+ import  NewTabIcon  from  "svgs/icons/new-tab.svg" ; 
1212
1313import  {  Periods  }  from  "consts/periods" ; 
1414import  {  usePopulatedDisputeData  }  from  "hooks/queries/usePopulatedDisputeData" ; 
@@ -19,9 +19,14 @@ import { DisputeDetailsQuery, useDisputeDetailsQuery } from "queries/useDisputeD
1919import  {  useVotingHistory  }  from  "queries/useVotingHistory" ; 
2020
2121import  {  ClassicRound  }  from  "src/graphql/graphql" ; 
22+ import  {  getTxnExplorerLink  }  from  "src/utils" ; 
23+ 
24+ import  {  responsiveSize  }  from  "styles/responsiveSize" ; 
2225
2326import  {  StyledClosedCircle  }  from  "components/StyledIcons/ClosedCircleIcon" ; 
2427
28+ import  {  ExternalLink  }  from  "../ExternalLink" ; 
29+ 
2530const  Container  =  styled . div ` 
2631  display: flex; 
2732  position: relative; 
@@ -50,6 +55,18 @@ const StyledCalendarIcon = styled(CalendarIcon)`
5055  height: 14px; 
5156` ; 
5257
58+ const  StyledNewTabIcon  =  styled ( NewTabIcon ) ` 
59+   margin-bottom: 2px; 
60+   path { 
61+     fill: ${ ( {  theme } )  =>  theme . primaryBlue }  
62+   } 
63+   :hover { 
64+     path { 
65+       fill: ${ ( {  theme } )  =>  theme . secondaryBlue }  
66+     } 
67+   } 
68+ ` ; 
69+ 
5370const  formatDate  =  ( date : string )  =>  { 
5471  const  options : Intl . DateTimeFormatOptions  =  {  year : "numeric" ,  month : "long" ,  day : "numeric"  } ; 
5572  const  startingDate  =  new  Date ( parseInt ( date )  *  1000 ) ; 
@@ -67,6 +84,9 @@ const useItems = (disputeDetails?: DisputeDetailsQuery, arbitrable?: `0x${string
6784  const  localRounds : ClassicRound [ ]  =  getLocalRounds ( votingHistory ?. dispute ?. disputeKitDispute )  as  ClassicRound [ ] ; 
6885  const  rounds  =  votingHistory ?. dispute ?. rounds ; 
6986  const  theme  =  useTheme ( ) ; 
87+   const  txnExplorerLink  =  useMemo ( ( )  =>  { 
88+     return  getTxnExplorerLink ( votingHistory ?. dispute ?. transactionHash  ??  "" ) ; 
89+   } ,  [ votingHistory ] ) ; 
7090
7191  return  useMemo < TimelineItems  |  undefined > ( ( )  =>  { 
7292    const  dispute  =  disputeDetails ?. dispute ; 
@@ -119,7 +139,11 @@ const useItems = (disputeDetails?: DisputeDetailsQuery, arbitrable?: `0x${string
119139        [ 
120140          { 
121141            title : "Dispute created" , 
122-             party : "" , 
142+             party : ( 
143+               < ExternalLink  to = { txnExplorerLink }  rel = "noopener noreferrer"  target = "_blank" > 
144+                 < StyledNewTabIcon  /> 
145+               </ ExternalLink > 
146+             ) , 
123147            subtitle : formatDate ( votingHistory ?. dispute ?. createdAt ) , 
124148            rightSided : true , 
125149            variant : theme . secondaryPurple , 
@@ -128,7 +152,7 @@ const useItems = (disputeDetails?: DisputeDetailsQuery, arbitrable?: `0x${string
128152      ) ; 
129153    } 
130154    return ; 
131-   } ,  [ disputeDetails ,  disputeData ,  localRounds ,  theme ] ) ; 
155+   } ,  [ disputeDetails ,  disputeData ,  localRounds ,  theme ,   rounds ,   votingHistory ,   txnExplorerLink ] ) ; 
132156} ; 
133157
134158interface  IDisputeTimeline  { 
@@ -138,15 +162,30 @@ interface IDisputeTimeline {
138162const  DisputeTimeline : React . FC < IDisputeTimeline >  =  ( {  arbitrable } )  =>  { 
139163  const  {  id }  =  useParams ( ) ; 
140164  const  {  data : disputeDetails  }  =  useDisputeDetailsQuery ( id ) ; 
165+   const  {  data : votingHistory  }  =  useVotingHistory ( id ) ; 
141166  const  items  =  useItems ( disputeDetails ,  arbitrable ) ; 
142167
168+   const  transactionExplorerLink  =  useMemo ( ( )  =>  { 
169+     return  getTxnExplorerLink ( disputeDetails ?. dispute ?. rulingTransactionHash  ??  "" ) ; 
170+   } ,  [ disputeDetails ] ) ; 
171+ 
143172  return  ( 
144173    < Container > 
145174      { items  &&  < StyledTimeline  { ...{  items } }  /> } 
146-       { disputeDetails ?. dispute ?. ruled  &&  items   &&   ( 
175+       { disputeDetails ?. dispute ?. ruled  &&  ( 
147176        < EnforcementContainer > 
148177          < StyledCalendarIcon  /> 
149-           < small > Enforcement: { items . at ( - 1 ) ?. subtitle } </ small > 
178+           < small > 
179+             Enforcement:{ " " } 
180+             { disputeDetails . dispute . rulingTimestamp  ? ( 
181+               < ExternalLink  to = { transactionExplorerLink }  rel = "noopener noreferrer"  target = "_blank" > 
182+                 { formatDate ( disputeDetails . dispute . rulingTimestamp ) } 
183+               </ ExternalLink > 
184+             )  : ( 
185+               < Skeleton  height = { 16 }  width = { 56 }  /> 
186+             ) } { " " } 
187+             / { votingHistory ?. dispute ?. rounds . at ( - 1 ) ?. court . name } 
188+           </ small > 
150189        </ EnforcementContainer > 
151190      ) } 
152191    </ Container > 
0 commit comments