1
- import { useEffect , useState } from "react" ;
2
- import LocalDateTime from "../LocalDateTime" ;
3
- import { Spinner } from "react-bootstrap" ;
1
+ import React , { useEffect , useState } from "react" ;
2
+ import { Spinner , Table } from "react-bootstrap" ;
4
3
import { formatProcessDuration } from "../../utils" ;
4
+ import CopyableHash from "../CopyableHash" ;
5
+ import IconBadge from "../IconBadge" ;
6
+ import LocalDateTime from "../LocalDateTime" ;
5
7
6
8
import styles from "./styles.module.css" ;
7
9
@@ -17,6 +19,13 @@ const certificateChainValidationEvents = {
17
19
started : "CertificateChainValidationStarted" ,
18
20
certificateValidated : "CertificateValidated" ,
19
21
done : "CertificateChainValidated" ,
22
+ unknown : "Unknown" ,
23
+ } ;
24
+
25
+ const eventPosition = {
26
+ beforeTable : 1 ,
27
+ inTable : 2 ,
28
+ afterTable : 3 ,
20
29
} ;
21
30
22
31
export default function CertificateVerifier ( {
@@ -81,16 +90,23 @@ export default function CertificateVerifier({
81
90
function clientEventListener ( e ) {
82
91
const event = e . data ;
83
92
let message = < > </ > ;
93
+ let position = eventPosition . afterTable ;
84
94
85
95
switch ( event . type ) {
86
96
case certificateChainValidationEvents . started :
97
+ position = eventPosition . beforeTable ;
87
98
message = < > The certificate chain validation has started...</ > ;
88
99
break ;
89
100
case certificateChainValidationEvents . certificateValidated :
101
+ position = eventPosition . inTable ;
90
102
message = (
91
103
< >
92
- A certificate has been validated, hash:{ " " }
93
- < strong > { event . payload . certificate_hash } </ strong >
104
+ < td >
105
+ < CopyableHash hash = { event . payload . certificate_hash } />
106
+ </ td >
107
+ < td >
108
+ < IconBadge tooltip = "Valid Certificate" variant = "success" icon = "mithril" />
109
+ </ td >
94
110
</ >
95
111
) ;
96
112
break ;
@@ -108,7 +124,7 @@ export default function CertificateVerifier({
108
124
109
125
setVerificationEvents ( ( existingEvents ) => [
110
126
...existingEvents ,
111
- { id : nextVerifyEventId ++ , message : message } ,
127
+ { id : nextVerifyEventId ++ , position : position , message : message } ,
112
128
] ) ;
113
129
}
114
130
@@ -138,15 +154,39 @@ export default function CertificateVerifier({
138
154
{ /*don't remove: this span is needed for a css trick to ensure scroll start at top */ }
139
155
< span />
140
156
< div >
141
- { verificationEvents . map ( ( evt ) => (
142
- < div key = { evt . id } > { evt . message } </ div >
143
- ) ) }
157
+ { verificationEvents
158
+ . filter ( ( evt ) => evt . position === eventPosition . beforeTable )
159
+ . map ( ( evt ) => (
160
+ < div key = { evt . id } > { evt . message } </ div >
161
+ ) ) }
162
+ < Table className = "my-2" responsive striped >
163
+ < thead >
164
+ < tr >
165
+ < th > Certificate hash</ th >
166
+ < th > Valid</ th >
167
+ </ tr >
168
+ </ thead >
169
+ < tbody >
170
+ { verificationEvents
171
+ . filter ( ( evt ) => evt . position === eventPosition . inTable )
172
+ . map ( ( evt ) => (
173
+ < tr key = { evt . id } > { evt . message } </ tr >
174
+ ) ) }
175
+ </ tbody >
176
+ </ Table >
177
+ { verificationEvents
178
+ . filter ( ( evt ) => evt . position === eventPosition . afterTable )
179
+ . map ( ( evt ) => (
180
+ < div key = { evt . id } > { evt . message } </ div >
181
+ ) ) }
144
182
{ validationError !== undefined && (
145
- < div >
146
- < i className = "text-danger bi bi-x-circle-fill" > </ i > Invalid certificate chain:
147
- < br />
148
- { validationError . message }
149
- </ div >
183
+ < tr >
184
+ < td colSpan = { 2 } >
185
+ < i className = "text-danger bi bi-x-circle-fill" > </ i > Invalid certificate chain:
186
+ < br />
187
+ { validationError . message }
188
+ </ td >
189
+ </ tr >
150
190
) }
151
191
</ div >
152
192
</ div >
0 commit comments