11import { useState , useRef , useEffect } from 'react' ;
22import type { ServiceInfo , InfraInfo } from '@/types' ;
3+ import { useTheme } from '@/hooks/useTheme' ;
34
45interface HeaderProps {
56 services : ServiceInfo [ ] ;
@@ -30,6 +31,7 @@ export default function Header({
3031} : HeaderProps ) {
3132 const [ dropdownOpen , setDropdownOpen ] = useState ( false ) ;
3233 const dropdownRef = useRef < HTMLDivElement > ( null ) ;
34+ const { theme, cycleTheme } = useTheme ( ) ;
3335
3436 const running = services . filter ( s => s . status === 'running' ) . length ;
3537 const healthy = services . filter ( s => s . health === 'healthy' ) . length ;
@@ -69,6 +71,8 @@ export default function Header({
6971 buttonClass += 'bg-success/10 text-success ring-1 ring-success/20 hover:bg-success/20' ;
7072 }
7173
74+ const themeTitle = theme === 'system' ? 'Theme: System' : theme === 'light' ? 'Theme: Light' : 'Theme: Dark' ;
75+
7276 return (
7377 < header className = "flex items-center justify-between border-b border-border bg-surface px-5 py-2.5" >
7478 < div className = "flex items-center gap-3" >
@@ -126,7 +130,7 @@ export default function Header({
126130 className = { `flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs/4 transition-colors ${
127131 stack === activeStack
128132 ? 'bg-accent/10 font-medium text-accent-light'
129- : 'text-text-secondary hover:bg-white /5'
133+ : 'text-text-secondary hover:bg-hover /5'
130134 } `}
131135 >
132136 { stack === activeStack && < span className = "size-1.5 rounded-full bg-accent" /> }
@@ -173,7 +177,7 @@ export default function Header({
173177
174178 < button
175179 onClick = { onToggleNotifications }
176- className = { `rounded-xs p-1.5 transition-colors hover:bg-white /5 ${
180+ className = { `rounded-xs p-1.5 transition-colors hover:bg-hover /5 ${
177181 notificationsEnabled ? 'text-warning' : 'text-text-muted hover:text-text-secondary'
178182 } `}
179183 title = { notificationsEnabled ? 'Disable notifications' : 'Enable notifications' }
@@ -198,10 +202,43 @@ export default function Header({
198202 ) }
199203 </ button >
200204
205+ { /* Theme toggle */ }
206+ < button
207+ onClick = { cycleTheme }
208+ className = "rounded-xs p-1.5 text-text-muted transition-colors hover:bg-hover/5 hover:text-text-secondary"
209+ title = { themeTitle }
210+ >
211+ { theme === 'system' ? (
212+ < svg className = "size-4" fill = "none" viewBox = "0 0 24 24" strokeWidth = { 1.5 } stroke = "currentColor" >
213+ < path
214+ strokeLinecap = "round"
215+ strokeLinejoin = "round"
216+ d = "M9 17.25v1.007a3 3 0 0 1-.879 2.122L7.5 21h9l-.621-.621A3 3 0 0 1 15 18.257V17.25m6-12V15a2.25 2.25 0 0 1-2.25 2.25H5.25A2.25 2.25 0 0 1 3 15V5.25A2.25 2.25 0 0 1 5.25 3h13.5A2.25 2.25 0 0 1 21 5.25Z"
217+ />
218+ </ svg >
219+ ) : theme === 'light' ? (
220+ < svg className = "size-4" fill = "none" viewBox = "0 0 24 24" strokeWidth = { 1.5 } stroke = "currentColor" >
221+ < path
222+ strokeLinecap = "round"
223+ strokeLinejoin = "round"
224+ d = "M12 3v2.25m6.364.386-1.591 1.591M21 12h-2.25m-.386 6.364-1.591-1.591M12 18.75V21m-4.773-4.227-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0Z"
225+ />
226+ </ svg >
227+ ) : (
228+ < svg className = "size-4" fill = "none" viewBox = "0 0 24 24" strokeWidth = { 1.5 } stroke = "currentColor" >
229+ < path
230+ strokeLinecap = "round"
231+ strokeLinejoin = "round"
232+ d = "M21.752 15.002A9.72 9.72 0 0 1 18 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 0 0 3 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 0 0 9.002-5.998Z"
233+ />
234+ </ svg >
235+ ) }
236+ </ button >
237+
201238 { onNavigateConfig && (
202239 < button
203240 onClick = { onNavigateConfig }
204- className = "rounded-xs p-1.5 text-text-muted transition-colors hover:bg-white /5 hover:text-text-secondary"
241+ className = "rounded-xs p-1.5 text-text-muted transition-colors hover:bg-hover /5 hover:text-text-secondary"
205242 title = "Config Management"
206243 >
207244 < svg className = "size-4" fill = "none" viewBox = "0 0 24 24" strokeWidth = { 1.5 } stroke = "currentColor" >
0 commit comments