1- import React , { useState , useEffect , useRef } from "react" ;
1+ import React , {
2+ useState ,
3+ useEffect ,
4+ useRef ,
5+ } from "react" ;
26import { useDeploymentLogs } from "../../../hooks/useDeploymentLogs" ;
3- import { Card , CardContent , CardHeader , CardTitle } from "../../ui/card" ;
7+ import {
8+ Card ,
9+ CardContent ,
10+ CardHeader ,
11+ CardTitle ,
12+ } from "../../ui/card" ;
413import { Terminal } from "lucide-react" ;
514
615export function formatTimeAgo ( dateStr : string ) {
@@ -16,57 +25,101 @@ export function formatTimeAgo(dateStr: string) {
1625
1726export function parseTimestamp ( raw : string ) {
1827 if ( ! raw ) return Date . now ( ) ;
19- const normalized = raw . includes ( " " ) && ! raw . includes ( "T" ) ? raw . replace ( " " , "T" ) : raw ;
28+ const normalized =
29+ raw . includes ( " " ) && ! raw . includes ( "T" )
30+ ? raw . replace ( " " , "T" )
31+ : raw ;
2032 const d = new Date ( normalized ) ;
21- return Number . isNaN ( d . getTime ( ) ) ? Date . now ( ) : d . getTime ( ) ;
33+ return Number . isNaN ( d . getTime ( ) )
34+ ? Date . now ( )
35+ : d . getTime ( ) ;
2236}
2337
24- export function depDisplayName ( projectName : string | undefined , depId : string ) {
38+ export function depDisplayName (
39+ projectName : string | undefined ,
40+ depId : string ,
41+ ) {
2542 const short = depId . slice ( 0 , 8 ) ;
2643 if ( ! projectName ) return short ;
27- const slug = projectName . toLowerCase ( ) . replace ( / [ ^ a - z 0 - 9 - ] + / g, "-" ) . replace ( / ^ - + | - + $ / g, "" ) . slice ( 0 , 63 ) ;
44+ const slug = projectName
45+ . toLowerCase ( )
46+ . replace ( / [ ^ a - z 0 - 9 - ] + / g, "-" )
47+ . replace ( / ^ - + | - + $ / g, "" )
48+ . slice ( 0 , 63 ) ;
2849 return `${ slug } -${ short } ` ;
2950}
3051
31- export function DeploymentDuration ( { deployment } : { deployment : any } ) {
52+ export function DeploymentDuration ( {
53+ deployment,
54+ } : {
55+ deployment : any ;
56+ } ) {
3257 const [ duration , setDuration ] = useState ( "" ) ;
3358
3459 useEffect ( ( ) => {
3560 const calculate = ( ) => {
36- const start = parseTimestamp ( deployment . createdAt ) ;
61+ const start = parseTimestamp (
62+ deployment . createdAt ,
63+ ) ;
3764 const status = deployment . status ;
38- const isFinished = status !== "pending" && status !== "building" && status !== "deploying" ;
39- const end = isFinished ? parseTimestamp ( deployment . updatedAt ) : Date . now ( ) ;
40-
65+ const isFinished =
66+ status !== "pending" &&
67+ status !== "building" &&
68+ status !== "deploying" ;
69+ const end = isFinished
70+ ? parseTimestamp (
71+ deployment . updatedAt ,
72+ )
73+ : Date . now ( ) ;
74+
4175 const diff = Math . max ( 0 , end - start ) ;
4276 const secs = Math . floor ( diff / 1000 ) ;
4377 if ( secs < 60 ) {
4478 setDuration ( `${ secs } s` ) ;
4579 } else {
46- const mins = Math . floor ( secs / 60 ) ;
80+ const mins = Math . floor (
81+ secs / 60 ,
82+ ) ;
4783 const remainingSecs = secs % 60 ;
48- setDuration ( `${ mins } m ${ remainingSecs } s` ) ;
84+ setDuration (
85+ `${ mins } m ${ remainingSecs } s` ,
86+ ) ;
4987 }
5088 } ;
5189
5290 calculate ( ) ;
53-
91+
5492 const status = deployment . status ;
55- const isFinished = status !== "pending" && status !== "building" && status !== "deploying" ;
93+ const isFinished =
94+ status !== "pending" &&
95+ status !== "building" &&
96+ status !== "deploying" ;
5697 if ( isFinished ) return ;
5798
58- const interval = setInterval ( calculate , 1000 ) ;
99+ const interval = setInterval (
100+ calculate ,
101+ 1000 ,
102+ ) ;
59103 return ( ) => clearInterval ( interval ) ;
60- } , [ deployment . createdAt , deployment . updatedAt , deployment . status ] ) ;
104+ } , [
105+ deployment . createdAt ,
106+ deployment . updatedAt ,
107+ deployment . status ,
108+ ] ) ;
61109
62- return < span className = "font-mono text-xs text-muted-foreground" > { duration } </ span > ;
110+ return (
111+ < span className = "font-mono text-xs text-muted-foreground" >
112+ { duration }
113+ </ span >
114+ ) ;
63115}
64116
65117function fmtLogTs ( raw : string | undefined ) {
66118 if ( ! raw ) return "" ;
67119 const d = new Date ( raw ) ;
68120 if ( Number . isNaN ( d . getTime ( ) ) ) return raw ;
69- const pad = ( n : number ) => String ( n ) . padStart ( 2 , "0" ) ;
121+ const pad = ( n : number ) =>
122+ String ( n ) . padStart ( 2 , "0" ) ;
70123 return `${ d . getFullYear ( ) } -${ pad ( d . getMonth ( ) + 1 ) } -${ pad ( d . getDate ( ) ) } ${ pad ( d . getHours ( ) ) } :${ pad ( d . getMinutes ( ) ) } :${ pad ( d . getSeconds ( ) ) } ` ;
71124}
72125
@@ -92,11 +145,18 @@ export function DeploymentLogs({
92145 < span className = "flex items-center gap-2" >
93146 < Terminal className = "h-4 w-4" />
94147 Build Logs —{ " " }
95- { deployment . id . slice ( 0 , 8 ) }
148+ { deployment . id . slice (
149+ 0 ,
150+ 8 ,
151+ ) }
96152 </ span >
97153 < span className = "text-xs font-normal text-muted-foreground flex items-center gap-2 select-none" >
98154 < span > Duration:</ span >
99- < DeploymentDuration deployment = { deployment } />
155+ < DeploymentDuration
156+ deployment = {
157+ deployment
158+ }
159+ />
100160 </ span >
101161 </ CardTitle >
102162 </ CardHeader >
@@ -115,10 +175,19 @@ export function DeploymentLogs({
115175 { logs . map ( ( log , i ) => (
116176 < div
117177 key = { i }
118- className = { `log-line ${ log . message . startsWith ( "CRITICAL" ) ? "dim " : "" } ` }
178+ className = { `log-line ${ log . message . startsWith ( "CRITICAL" ) ? "" : log . message . startsWith ( "ERROR" ) ? "error " : "" } ` }
119179 >
120180 < span className = "log-stage" >
121- [{ log . stage } ]-[{ fmtLogTs ( ( log as any ) . timestamp || log . createdAt ) } ]
181+ [{ log . stage }
182+ ]-[
183+ { fmtLogTs (
184+ (
185+ log as any
186+ )
187+ . timestamp ||
188+ log . createdAt ,
189+ ) }
190+ ]
122191 </ span >
123192 < span className = "log-msg" >
124193 { log . message }
0 commit comments