multica/apps/web/app/app-header.tsx
Naiyuan Qing dacbfa9e3d refactor(ui): purify Chat component and move header to app layouts
- Remove all props from Chat (showHeader, headerActions) making it a
  zero-config pure chat component with only connection input, messages,
  and send functionality
- Create AppHeader client component for web app with brand, theme
  toggle, disconnect button, and useHubInit
- Add disconnect button to desktop layout header
- Add reset() action to hub store to eliminate duplicated state reset
- Remove unused token field from gateway store
- Remove dead code: connection-bar.tsx
- Guard handleConnect against empty deviceId race condition

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 20:31:24 +08:00

54 lines
1.5 KiB
TypeScript

"use client";
import {
useHubInit,
useGatewayStore,
useHubStore,
clearConnection,
} from "@multica/store";
import { Button } from "@multica/ui/components/ui/button";
import { ThemeToggle } from "./theme-toggle";
export function AppHeader({ children }: { children: React.ReactNode }) {
useHubInit();
const gwState = useGatewayStore((s) => s.connectionState);
const hubId = useGatewayStore((s) => s.hubId);
const activeAgentId = useHubStore((s) => s.activeAgentId);
const isConnected = gwState === "registered" && !!hubId && !!activeAgentId;
const handleDisconnect = () => {
useGatewayStore.getState().disconnect();
useHubStore.getState().reset();
clearConnection();
};
return (
<>
<header>
<div className="flex items-center justify-between px-4 py-2 max-w-4xl mx-auto">
<div className="flex items-center gap-2.5">
<img src="/icon.png" alt="Multica" className="size-6 rounded-md" />
<span className="text-sm tracking-wide font-[family-name:var(--font-brand)]">
Multica
</span>
</div>
<div className="flex items-center gap-1">
<ThemeToggle />
{isConnected && (
<Button
variant="ghost"
size="sm"
onClick={handleDisconnect}
className="text-xs text-muted-foreground"
>
Disconnect
</Button>
)}
</div>
</div>
</header>
{children}
</>
);
}