Files
unibus/web/src/App.tsx
T
egutierrez d33ca6278a feat(web): SPA de chat (React + Vite + Mantine v9)
Cliente web sobre el gateway (REST + SSE). El navegador no habla NATS ni
cripto: el peer Go del gateway lo hace.

- Pantalla de conexión: gateway URL + identidad (persistidas en localStorage).
- Navbar: crear room (con toggle de cifrado E2E), unirse por id, lista de rooms.
- Centro: mensajes en vivo por SSE, burbujas con autor y hora, composer.
- Lateral: miembros (rol owner), invitar por peer conectado, expulsar (owner).
- Mantine v9 (createTheme + MantineProvider), @tabler/icons-react, layout con
  AppShell/Stack/Group; sin Tailwind ni CSS manual. React 19 (peer dep de v9).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 18:43:10 +02:00

30 lines
882 B
TypeScript

import { useState } from "react";
import { GatewayClient } from "./api";
import type { Peer } from "./types";
import { ConnectScreen } from "./components/ConnectScreen";
import { ChatLayout } from "./components/ChatLayout";
// Connection holds the live gateway client plus the identity it connected as.
interface Connection {
client: GatewayClient;
peer: Peer;
}
// App is the root: it shows the connect screen until the user picks a gateway
// URL and a peer name, then swaps to the full chat layout. Disconnecting drops
// back to the connect screen.
export function App() {
const [conn, setConn] = useState<Connection | null>(null);
if (!conn) {
return <ConnectScreen onConnect={(client, peer) => setConn({ client, peer })} />;
}
return (
<ChatLayout
client={conn.client}
peer={conn.peer}
onDisconnect={() => setConn(null)}
/>
);
}