CI / build (push) Successful in 4m26s
Adds a Postgres-backed quotes domain (poems/quotes/favorites) exposed as five agent-native actions (list-quotes, get-random-quote, create-quote, toggle-favorite, list-favorites) callable from both chat and the React UI via useActionQuery/useActionMutation. Moves the primary UI from chat to a mobile-first Quotes/Favorites experience (chat moves to /chat), adds manual OpenTelemetry instrumentation exporting traces/metrics/logs over OTLP, and wires a local Docker Postgres for shared state.
63 lines
2.0 KiB
TypeScript
63 lines
2.0 KiB
TypeScript
import { AgentToggleButton } from "@agent-native/core/client/agent-chat";
|
|
import { useT } from "@agent-native/core/client/i18n";
|
|
import {
|
|
useHeaderTitle,
|
|
useHeaderActions,
|
|
} from "@agent-native/toolkit/app-shell";
|
|
import { IconMenu2 } from "@tabler/icons-react";
|
|
import { useLocation } from "react-router";
|
|
|
|
import { APP_TITLE } from "@/lib/app-config";
|
|
|
|
const pageTitleKeys: Record<string, string> = {
|
|
"/": "navigation.quotes",
|
|
"/favorites": "navigation.favorites",
|
|
"/chat": "navigation.chat",
|
|
"/observability": "navigation.observability",
|
|
"/agent": "settings.agentTitle",
|
|
"/settings": "navigation.settings",
|
|
};
|
|
|
|
function resolveTitle(pathname: string, t: (key: string) => string): string {
|
|
if (pageTitleKeys[pathname]) return t(pageTitleKeys[pathname]);
|
|
if (pathname.startsWith("/extensions")) return t("navigation.extensions");
|
|
return APP_TITLE;
|
|
}
|
|
|
|
interface HeaderProps {
|
|
onOpenMobileSidebar?: () => void;
|
|
}
|
|
|
|
export function Header({ onOpenMobileSidebar }: HeaderProps) {
|
|
const location = useLocation();
|
|
const t = useT();
|
|
const title = useHeaderTitle();
|
|
const actions = useHeaderActions();
|
|
|
|
return (
|
|
<header className="flex h-12 items-center gap-3 border-b border-border bg-background px-4 lg:px-6 shrink-0">
|
|
{onOpenMobileSidebar && (
|
|
<button
|
|
type="button"
|
|
onClick={onOpenMobileSidebar}
|
|
aria-label={t("navigation.openNavigation")}
|
|
className="flex h-9 w-9 cursor-pointer items-center justify-center rounded-md text-muted-foreground hover:text-foreground hover:bg-accent md:hidden"
|
|
>
|
|
<IconMenu2 className="h-4 w-4" />
|
|
</button>
|
|
)}
|
|
<div className="flex items-center gap-3 flex-1 min-w-0">
|
|
{title ?? (
|
|
<h1 className="text-lg font-semibold tracking-tight truncate">
|
|
{resolveTitle(location.pathname, t)}
|
|
</h1>
|
|
)}
|
|
</div>
|
|
<div className="flex items-center gap-2 shrink-0">
|
|
{actions}
|
|
<AgentToggleButton />
|
|
</div>
|
|
</header>
|
|
);
|
|
}
|