import React, { useState, useEffect } from 'react'; import { ShadeProvider, IdentityCard, SessionList, PrekeyStock, RecentActivity, ServerStatus, FingerprintCompare, } from '@shade/widgets'; import { Login } from './Login.js'; const STORAGE_KEY = 'shade-dashboard-config'; interface DashboardConfig { observerUrl: string; token: string; } export function App(): React.ReactElement { const [config, setConfig] = useState(null); useEffect(() => { // Determine the default observer URL: assume dashboard is served from // the same origin as the observer, so the API is at the parent path const defaultUrl = window.location.origin + window.location.pathname.replace(/\/dashboard\/?$/, ''); try { const stored = window.localStorage.getItem(STORAGE_KEY); if (stored) { const parsed = JSON.parse(stored) as DashboardConfig; if (parsed.observerUrl && parsed.token) { setConfig(parsed); return; } } } catch {} // Show login screen setConfig({ observerUrl: defaultUrl, token: '' }); }, []); function handleLogin(observerUrl: string, token: string): void { const cfg = { observerUrl, token }; window.localStorage.setItem(STORAGE_KEY, JSON.stringify(cfg)); setConfig(cfg); } function handleLogout(): void { window.localStorage.removeItem(STORAGE_KEY); setConfig({ observerUrl: window.location.origin, token: '' }); } if (!config) { return
Loading…
; } if (!config.token) { return ; } return ( ); } function DashboardLayout({ onLogout }: { onLogout: () => void }): React.ReactElement { return (

Shade Observer

Live debugger for your Signal Protocol deployment
); }