The AI trust layer between agents: identity, agreements, safeguards, and outcome intelligence for A2A.
Commit 4bfaf3cc
4bfaf3cca6a5Merged
aryaamin <[email protected]> · 2 months ago · 2 files · ~2 modified
Description
feat: add persistent dashboard theme toggle
Details
- Commit
- 4bfaf3cca6a5
- Parent
- 791506c0dbc6
apps/dashboard/src/main.tsxmodifiedView file
@@ -9,8 +9,10 @@
99
type Auth0User = { sub: string; name?: string; email?: string; picture?: string };1010
type AuthSession = { user: Auth0User };1111
type AuthTransaction = { state: string; nonce: string; verifier: string };12+
type Theme = 'dark' | 'light';1213
1314
const authTransactionKey = 'openclasp.auth0.transaction';15+
const themeKey = 'openclasp.theme.v1';1416
1517
type DashboardData = {1618
agents: Record<string, any>[];@@ -113,8 +115,15 @@
113115
return pages.includes(value as Page) ? (value as Page) : 'dashboard';114116
}115117
118+
function initialTheme(): Theme {119+
const saved = localStorage.getItem(themeKey);120+
if (saved === 'dark' || saved === 'light') return saved;121+
return matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';122+
}123+
116124
function App() {117125
const [session, setSession] = useState<AuthSession | null>();126+
const [theme, setTheme] = useState<Theme>(initialTheme);118127
const [page, setPage] = useState<Page>(route());119128
const [data, setData] = useState<DashboardData>(emptyData);120129
const [settings, setSettings] = useState<Settings>(defaultSettings);@@ -135,6 +144,11 @@
135144
}, []);136145
137146
useEffect(() => {147+
document.documentElement.dataset.theme = theme;148+
localStorage.setItem(themeKey, theme);149+
}, [theme]);150+
151+
useEffect(() => {138152
const onPopState = () => setPage(route());139153
addEventListener('popstate', onPopState);140154
return () => removeEventListener('popstate', onPopState);@@ -183,6 +197,14 @@
183197
<Nav page="connect" active={page} onClick={navigate} label="Connect" glyph="+" />184198
<Nav page="settings" active={page} onClick={navigate} label="Settings" glyph="⚙" />185199
</nav>200+
<button201+
className="themeSwitch"202+
onClick={() => setTheme((current) => (current === 'dark' ? 'light' : 'dark'))}203+
aria-label={`Switch to ${theme === 'dark' ? 'light' : 'dark'} theme`}204+
>205+
<span>{theme === 'dark' ? '☼' : '◐'}</span>206+
{theme === 'dark' ? 'Light theme' : 'Dark theme'}207+
</button>186208
<div className="privacyStamp">187209
<span className="liveDot" />188210
<div>apps/dashboard/src/styles.cssmodifiedView file
Loading diff…