1+ import { useState , useEffect } from 'react' ;
2+ import { Rocket , GitBranch , Clock , CheckCircle , AlertCircle , Activity , Users , Globe , Zap } from 'lucide-react' ;
3+
4+ interface DeploymentRecord {
5+ id : string ;
6+ version : string ;
7+ branch : string ;
8+ status : 'success' | 'failed' | 'building' | 'pending' ;
9+ timestamp : Date ;
10+ duration : number ;
11+ author : string ;
12+ }
13+
14+ export function DeployDashboard ( ) {
15+ const [ deployments ] = useState < DeploymentRecord [ ] > ( [
16+ {
17+ id : '1' ,
18+ version : 'v1.2.3' ,
19+ branch : 'main' ,
20+ status : 'success' ,
21+ timestamp : new Date ( Date . now ( ) - 1000 * 60 * 15 ) ,
22+ duration : 45 ,
23+ author : 'System'
24+ } ,
25+ {
26+ id : '2' ,
27+ version : 'v1.2.2' ,
28+ branch : 'main' ,
29+ status : 'success' ,
30+ timestamp : new Date ( Date . now ( ) - 1000 * 60 * 60 * 2 ) ,
31+ duration : 52 ,
32+ author : 'AI Agent'
33+ } ,
34+ {
35+ id : '3' ,
36+ version : 'v1.2.1' ,
37+ branch : 'feature/deploy-pages' ,
38+ status : 'building' ,
39+ timestamp : new Date ( Date . now ( ) - 1000 * 60 * 5 ) ,
40+ duration : 0 ,
41+ author : 'Copilot'
42+ } ,
43+ ] ) ;
44+
45+ const [ metrics , setMetrics ] = useState ( {
46+ totalDeployments : 127 ,
47+ successRate : 98.4 ,
48+ avgBuildTime : 48 ,
49+ uptime : 99.9 ,
50+ activeVisitors : 1247 ,
51+ lastDeployment : '15m ago'
52+ } ) ;
53+
54+ useEffect ( ( ) => {
55+ // Simulate real-time updates
56+ const interval = setInterval ( ( ) => {
57+ setMetrics ( prev => ( {
58+ ...prev ,
59+ activeVisitors : prev . activeVisitors + Math . floor ( Math . random ( ) * 10 - 5 ) ,
60+ avgBuildTime : prev . avgBuildTime + Math . floor ( Math . random ( ) * 4 - 2 ) ,
61+ } ) ) ;
62+ } , 5000 ) ;
63+
64+ return ( ) => clearInterval ( interval ) ;
65+ } , [ ] ) ;
66+
67+ const getStatusIcon = ( status : string ) => {
68+ switch ( status ) {
69+ case 'success' :
70+ return < CheckCircle className = "w-4 h-4 text-green-400" /> ;
71+ case 'failed' :
72+ return < AlertCircle className = "w-4 h-4 text-red-400" /> ;
73+ case 'building' :
74+ return < Activity className = "w-4 h-4 text-yellow-400 animate-pulse" /> ;
75+ default :
76+ return < Clock className = "w-4 h-4 text-slate-400" /> ;
77+ }
78+ } ;
79+
80+ const getStatusColor = ( status : string ) => {
81+ switch ( status ) {
82+ case 'success' :
83+ return 'text-green-400' ;
84+ case 'failed' :
85+ return 'text-red-400' ;
86+ case 'building' :
87+ return 'text-yellow-400' ;
88+ default :
89+ return 'text-slate-400' ;
90+ }
91+ } ;
92+
93+ const formatDuration = ( seconds : number ) => {
94+ if ( seconds === 0 ) return 'In progress...' ;
95+ const minutes = Math . floor ( seconds / 60 ) ;
96+ const remainingSeconds = seconds % 60 ;
97+ return `${ minutes } m ${ remainingSeconds } s` ;
98+ } ;
99+
100+ const formatRelativeTime = ( date : Date ) => {
101+ const now = new Date ( ) ;
102+ const diffMs = now . getTime ( ) - date . getTime ( ) ;
103+ const diffMinutes = Math . floor ( diffMs / ( 1000 * 60 ) ) ;
104+
105+ if ( diffMinutes < 1 ) return 'Just now' ;
106+ if ( diffMinutes < 60 ) return `${ diffMinutes } m ago` ;
107+
108+ const diffHours = Math . floor ( diffMinutes / 60 ) ;
109+ if ( diffHours < 24 ) return `${ diffHours } h ago` ;
110+
111+ const diffDays = Math . floor ( diffHours / 24 ) ;
112+ return `${ diffDays } d ago` ;
113+ } ;
114+
115+ return (
116+ < div className = "space-y-6" >
117+ < div className = "flex items-center justify-between" >
118+ < div >
119+ < h2 className = "text-2xl font-bold text-white" > Deploy Dashboard</ h2 >
120+ < p className = "text-slate-400 mt-1" > Monitor deployments and release management</ p >
121+ </ div >
122+ < button className = "flex items-center gap-2 px-4 py-2 bg-gradient-to-r from-purple-600 to-pink-600 rounded-lg hover:from-purple-700 hover:to-pink-700 transition-all" >
123+ < Rocket className = "w-4 h-4" />
124+ Deploy Now
125+ </ button >
126+ </ div >
127+
128+ { /* Metrics Grid */ }
129+ < div className = "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4" >
130+ < div className = "bg-slate-800/50 backdrop-blur-sm rounded-xl p-4 border border-slate-700" >
131+ < div className = "flex items-center gap-2 mb-2" >
132+ < Rocket className = "w-4 h-4 text-purple-400" />
133+ < span className = "text-xs text-slate-400" > Total Deploys</ span >
134+ </ div >
135+ < div className = "text-2xl font-bold text-white" > { metrics . totalDeployments } </ div >
136+ </ div >
137+
138+ < div className = "bg-slate-800/50 backdrop-blur-sm rounded-xl p-4 border border-slate-700" >
139+ < div className = "flex items-center gap-2 mb-2" >
140+ < CheckCircle className = "w-4 h-4 text-green-400" />
141+ < span className = "text-xs text-slate-400" > Success Rate</ span >
142+ </ div >
143+ < div className = "text-2xl font-bold text-white" > { metrics . successRate } %</ div >
144+ </ div >
145+
146+ < div className = "bg-slate-800/50 backdrop-blur-sm rounded-xl p-4 border border-slate-700" >
147+ < div className = "flex items-center gap-2 mb-2" >
148+ < Clock className = "w-4 h-4 text-blue-400" />
149+ < span className = "text-xs text-slate-400" > Avg Build Time</ span >
150+ </ div >
151+ < div className = "text-2xl font-bold text-white" > { metrics . avgBuildTime } s</ div >
152+ </ div >
153+
154+ < div className = "bg-slate-800/50 backdrop-blur-sm rounded-xl p-4 border border-slate-700" >
155+ < div className = "flex items-center gap-2 mb-2" >
156+ < Activity className = "w-4 h-4 text-green-400" />
157+ < span className = "text-xs text-slate-400" > Uptime</ span >
158+ </ div >
159+ < div className = "text-2xl font-bold text-white" > { metrics . uptime } %</ div >
160+ </ div >
161+
162+ < div className = "bg-slate-800/50 backdrop-blur-sm rounded-xl p-4 border border-slate-700" >
163+ < div className = "flex items-center gap-2 mb-2" >
164+ < Users className = "w-4 h-4 text-purple-400" />
165+ < span className = "text-xs text-slate-400" > Active Users</ span >
166+ </ div >
167+ < div className = "text-2xl font-bold text-white" > { metrics . activeVisitors . toLocaleString ( ) } </ div >
168+ </ div >
169+
170+ < div className = "bg-slate-800/50 backdrop-blur-sm rounded-xl p-4 border border-slate-700" >
171+ < div className = "flex items-center gap-2 mb-2" >
172+ < Globe className = "w-4 h-4 text-blue-400" />
173+ < span className = "text-xs text-slate-400" > Last Deploy</ span >
174+ </ div >
175+ < div className = "text-2xl font-bold text-white" > { metrics . lastDeployment } </ div >
176+ </ div >
177+ </ div >
178+
179+ { /* Current Status */ }
180+ < div className = "bg-slate-800/50 backdrop-blur-sm rounded-xl p-6 border border-slate-700" >
181+ < h3 className = "text-lg font-semibold mb-4 flex items-center gap-2" >
182+ < Zap className = "w-5 h-5 text-purple-400" />
183+ Current Status
184+ </ h3 >
185+ < div className = "grid grid-cols-1 md:grid-cols-3 gap-4" >
186+ < div className = "p-4 bg-slate-700/30 rounded-lg" >
187+ < div className = "flex items-center gap-2 mb-2" >
188+ < div className = "w-3 h-3 bg-green-400 rounded-full animate-pulse" > </ div >
189+ < span className = "text-green-400 font-medium" > Production</ span >
190+ </ div >
191+ < p className = "text-slate-300 text-sm" > Running v1.2.3</ p >
192+ < p className = "text-slate-400 text-xs" > Deployed 15m ago</ p >
193+ </ div >
194+
195+ < div className = "p-4 bg-slate-700/30 rounded-lg" >
196+ < div className = "flex items-center gap-2 mb-2" >
197+ < div className = "w-3 h-3 bg-yellow-400 rounded-full animate-pulse" > </ div >
198+ < span className = "text-yellow-400 font-medium" > Staging</ span >
199+ </ div >
200+ < p className = "text-slate-300 text-sm" > Building v1.2.4</ p >
201+ < p className = "text-slate-400 text-xs" > Started 5m ago</ p >
202+ </ div >
203+
204+ < div className = "p-4 bg-slate-700/30 rounded-lg" >
205+ < div className = "flex items-center gap-2 mb-2" >
206+ < div className = "w-3 h-3 bg-blue-400 rounded-full" > </ div >
207+ < span className = "text-blue-400 font-medium" > Development</ span >
208+ </ div >
209+ < p className = "text-slate-300 text-sm" > Ready v1.3.0-dev</ p >
210+ < p className = "text-slate-400 text-xs" > Updated 1h ago</ p >
211+ </ div >
212+ </ div >
213+ </ div >
214+
215+ { /* Recent Deployments */ }
216+ < div className = "bg-slate-800/50 backdrop-blur-sm rounded-xl p-6 border border-slate-700" >
217+ < h3 className = "text-lg font-semibold mb-4 flex items-center gap-2" >
218+ < GitBranch className = "w-5 h-5 text-purple-400" />
219+ Recent Deployments
220+ </ h3 >
221+ < div className = "space-y-3" >
222+ { deployments . map ( ( deployment ) => (
223+ < div
224+ key = { deployment . id }
225+ className = "flex items-center justify-between p-4 bg-slate-700/30 rounded-lg hover:bg-slate-700/40 transition-colors"
226+ >
227+ < div className = "flex items-center gap-4" >
228+ { getStatusIcon ( deployment . status ) }
229+ < div >
230+ < div className = "flex items-center gap-2" >
231+ < span className = "font-medium text-white" > { deployment . version } </ span >
232+ < span className = "text-xs bg-slate-600 px-2 py-1 rounded" > { deployment . branch } </ span >
233+ </ div >
234+ < div className = "flex items-center gap-4 text-sm text-slate-400" >
235+ < span > by { deployment . author } </ span >
236+ < span > { formatRelativeTime ( deployment . timestamp ) } </ span >
237+ </ div >
238+ </ div >
239+ </ div >
240+ < div className = "text-right" >
241+ < div className = { `font-medium capitalize ${ getStatusColor ( deployment . status ) } ` } >
242+ { deployment . status }
243+ </ div >
244+ < div className = "text-sm text-slate-400" >
245+ { formatDuration ( deployment . duration ) }
246+ </ div >
247+ </ div >
248+ </ div >
249+ ) ) }
250+ </ div >
251+ </ div >
252+
253+ { /* Build Pipeline */ }
254+ < div className = "bg-slate-800/50 backdrop-blur-sm rounded-xl p-6 border border-slate-700" >
255+ < h3 className = "text-lg font-semibold mb-4" > Build Pipeline</ h3 >
256+ < div className = "grid grid-cols-1 md:grid-cols-4 gap-4" >
257+ { [
258+ { name : 'Code Analysis' , status : 'complete' , duration : '12s' } ,
259+ { name : 'Build Assets' , status : 'complete' , duration : '24s' } ,
260+ { name : 'Run Tests' , status : 'complete' , duration : '8s' } ,
261+ { name : 'Deploy' , status : 'complete' , duration : '15s' } ,
262+ ] . map ( ( step , index ) => (
263+ < div key = { index } className = "p-4 bg-slate-700/30 rounded-lg" >
264+ < div className = "flex items-center justify-between mb-2" >
265+ < span className = "text-sm font-medium text-white" > { step . name } </ span >
266+ < CheckCircle className = "w-4 h-4 text-green-400" />
267+ </ div >
268+ < div className = "text-xs text-slate-400" > { step . duration } </ div >
269+ < div className = "w-full bg-slate-600 rounded-full h-2 mt-2" >
270+ < div className = "bg-green-400 h-2 rounded-full w-full" > </ div >
271+ </ div >
272+ </ div >
273+ ) ) }
274+ </ div >
275+ </ div >
276+ </ div >
277+ ) ;
278+ }
0 commit comments