feat(frontend): add a terminal theme and three-way theme switcher
Adds the cyber theme to the console and login page, replaces the dark/light toggle with a theme switcher, and moves the login page script to /login.js so it is served under the existing CSP.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import {NavLink, Outlet, useLocation, useSearchParams} from 'react-router-dom'
|
||||
import {AlertTriangle, ChevronsLeft, ChevronsRight, LayoutDashboard, LogOut, Moon, Search, Sun} from 'lucide-react'
|
||||
import {AlertTriangle, ChevronsLeft, ChevronsRight, LayoutDashboard, LogOut, Moon, Search, Sun, Terminal} from 'lucide-react'
|
||||
import {useCallback, useEffect, useRef, useState} from 'react'
|
||||
import theCloud from '../../../../TheCloud.png'
|
||||
import {useTheme} from '@/lib/useTheme'
|
||||
@@ -157,9 +157,8 @@ function groupByGroup(services: CloudServiceDescriptor[]): Array<[string, CloudS
|
||||
export function Layout() {
|
||||
const location = useLocation()
|
||||
const activeCloud = activeCloudFromPath(location.pathname)
|
||||
const {theme, toggle} = useTheme()
|
||||
const {theme, setTheme} = useTheme()
|
||||
const {collapsed, toggle: toggleSidebar, toggleRef} = useSidebar()
|
||||
const isDark = theme === 'dark'
|
||||
const {data, isError} = useQuery({
|
||||
queryKey: ['cloud-status', activeCloud],
|
||||
queryFn: ({signal}) => getCloudStatus(activeCloud, signal),
|
||||
@@ -209,15 +208,11 @@ export function Layout() {
|
||||
<div className="shell">
|
||||
<header className="topbar">
|
||||
<TopbarSearch/>
|
||||
<button
|
||||
className="icon-btn"
|
||||
type="button"
|
||||
onClick={toggle}
|
||||
title={isDark ? 'Switch to light theme' : 'Switch to dark theme'}
|
||||
aria-label={isDark ? 'Switch to light theme' : 'Switch to dark theme'}
|
||||
>
|
||||
{isDark ? <Sun size={14} aria-hidden="true"/> : <Moon size={14} aria-hidden="true"/>}
|
||||
</button>
|
||||
<div className="theme-switcher" role="group" aria-label="Console theme">
|
||||
<button className={`icon-btn ${theme === 'dark' ? 'active' : ''}`} type="button" onClick={() => setTheme('dark')} title="Dark theme" aria-label="Dark theme" aria-pressed={theme === 'dark'}><Moon size={14} aria-hidden="true"/></button>
|
||||
<button className={`icon-btn ${theme === 'light' ? 'active' : ''}`} type="button" onClick={() => setTheme('light')} title="Light theme" aria-label="Light theme" aria-pressed={theme === 'light'}><Sun size={14} aria-hidden="true"/></button>
|
||||
<button className={`icon-btn ${theme === 'cyber' ? 'active' : ''}`} type="button" onClick={() => setTheme('cyber')} title="Terminal theme" aria-label="Terminal theme" aria-pressed={theme === 'cyber'}><Terminal size={14} aria-hidden="true"/></button>
|
||||
</div>
|
||||
<div id="topbar-status" className="topbar-status"/>
|
||||
<AccountSwitcher/>
|
||||
<button className="icon-btn" type="button" title="Sign out" aria-label="Sign out" onClick={() => void signOut()}>
|
||||
|
||||
Reference in New Issue
Block a user