@@ -240,63 +240,71 @@ export function Tokens() {
240240 < h5 className = "mb-0" > { t ( "tokens.existing_tokens" ) } </ h5 >
241241 </ Card . Header >
242242 < Card . Body >
243- { tokens . map ( ( token , index ) => (
244- < div key = { index } className = { `token-item ${ index !== tokens . length - 1 ? 'mb-4' : '' } ` } >
245- < div className = "d-flex justify-content-between align-items-start mb-2" >
246- < div >
247- < h6 className = "mb-1 fw-bold" > { token . name } </ h6 >
248- < small className = "text-muted" >
249- { t ( "tokens.created" ) } : { token . createdAt . toLocaleDateString ( ) } { token . createdAt . toLocaleTimeString ( ) }
250- </ small >
251- < br />
252- < small className = "text-muted" >
253- { t ( "tokens.last_used" ) } : { token . lastUsedAt ?
254- `${ token . lastUsedAt . toLocaleDateString ( ) } ${ token . lastUsedAt . toLocaleTimeString ( ) } ` :
255- t ( "tokens.never_used" )
256- }
257- </ small >
243+ { tokens . map ( ( token , index ) => {
244+ const isExpired = token . use_once && token . lastUsedAt !== null ;
245+ const statusVariant = isExpired ? "danger" : ( token . use_once ? "success" : "warning" ) ;
246+ const statusText = isExpired ? t ( "tokens.expired" ) : ( token . use_once ? t ( "tokens.use_once" ) : t ( "tokens.reusable" ) ) ;
247+
248+ return (
249+ < div key = { index } className = { `token-item ${ index !== tokens . length - 1 ? 'mb-4' : '' } ` } >
250+ < div className = "d-flex justify-content-between align-items-start mb-2" >
251+ < div >
252+ < h6 className = { `mb-1 fw-bold ${ isExpired ? 'text-muted' : '' } ` } > { token . name } </ h6 >
253+ < small className = "text-muted" >
254+ { t ( "tokens.created" ) } : { token . createdAt . toLocaleDateString ( ) } { token . createdAt . toLocaleTimeString ( ) }
255+ </ small >
256+ < br />
257+ < small className = "text-muted" >
258+ { token . use_once ? t ( "tokens.used" ) : t ( "tokens.last_used" ) } : { token . lastUsedAt ?
259+ `${ token . lastUsedAt . toLocaleDateString ( ) } ${ token . lastUsedAt . toLocaleTimeString ( ) } ` :
260+ t ( "tokens.never_used" )
261+ }
262+ </ small >
263+ </ div >
264+ < div className = "d-flex gap-2" >
265+ < Button
266+ variant = { statusVariant }
267+ disabled
268+ size = "sm"
269+ >
270+ { statusText }
271+ </ Button >
272+ </ div >
258273 </ div >
259- < div className = "d-flex gap-2" >
274+ < InputGroup className = "mb-2" >
275+ < Form . Control
276+ type = "text"
277+ readOnly
278+ value = { isExpired ? "••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••" : token . token }
279+ className = { `${ isExpired ? 'text-muted' : '' } ` }
280+ style = { isExpired ? { fontFamily : 'monospace' } : { } }
281+ />
282+ </ InputGroup >
283+ < div className = "d-flex flex-wrap gap-2" >
260284 < Button
261- variant = { token . use_once ? "success" : "warning" }
262- disabled
285+ variant = "secondary"
263286 size = "sm"
287+ className = "d-flex align-items-center gap-2"
288+ onClick = { ( ) => handleCopyToken ( token . token ) }
289+ disabled = { isExpired }
264290 >
265- { token . use_once ? t ( "tokens.use_once" ) : t ( "tokens.reusable" ) }
291+ < Clipboard size = { 16 } />
292+ { t ( "tokens.copy" ) }
293+ </ Button >
294+ < Button
295+ variant = "danger"
296+ size = "sm"
297+ className = "d-flex align-items-center gap-2"
298+ onClick = { ( ) => handleDeleteToken ( token . id ) }
299+ >
300+ < Trash2 size = { 16 } />
301+ { t ( "tokens.delete" ) }
266302 </ Button >
267303 </ div >
304+ { index !== tokens . length - 1 && < hr className = "mt-3" /> }
268305 </ div >
269- < InputGroup className = "mb-2" >
270- < Form . Control
271- type = "text"
272- readOnly
273- value = { token . token }
274- className = "token-txt"
275- />
276- </ InputGroup >
277- < div className = "d-flex flex-wrap gap-2" >
278- < Button
279- variant = "secondary"
280- size = "sm"
281- className = "d-flex align-items-center gap-2"
282- onClick = { ( ) => handleCopyToken ( token . token ) }
283- >
284- < Clipboard size = { 16 } />
285- { t ( "tokens.copy" ) }
286- </ Button >
287- < Button
288- variant = "danger"
289- size = "sm"
290- className = "d-flex align-items-center gap-2"
291- onClick = { ( ) => handleDeleteToken ( token . id ) }
292- >
293- < Trash2 size = { 16 } />
294- { t ( "tokens.delete" ) }
295- </ Button >
296- </ div >
297- { index !== tokens . length - 1 && < hr className = "mt-3" /> }
298- </ div >
299- ) ) }
306+ ) ;
307+ } ) }
300308 </ Card . Body >
301309 </ Card >
302310 </ Container >
0 commit comments