All checks were successful
ci/woodpecker/push/ci Pipeline was successful
Co-authored-by: Jason Woltje <jason@diversecanvas.com> Co-committed-by: Jason Woltje <jason@diversecanvas.com>
90 lines
2.4 KiB
TypeScript
90 lines
2.4 KiB
TypeScript
'use client';
|
|
|
|
import { useRouter } from 'next/navigation';
|
|
import { signOut, useSession } from '@/lib/auth-client';
|
|
import { ThemeToggle } from './theme-toggle';
|
|
import { useSidebar } from './sidebar-context';
|
|
|
|
function MenuIcon(): React.JSX.Element {
|
|
return (
|
|
<svg
|
|
width="16"
|
|
height="16"
|
|
viewBox="0 0 16 16"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth="1.5"
|
|
>
|
|
<path d="M2 4h12M2 8h12M2 12h12" />
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
export function Topbar(): React.ReactElement {
|
|
const { data: session } = useSession();
|
|
const router = useRouter();
|
|
const { isMobile, mobileOpen, setMobileOpen, toggleCollapsed } = useSidebar();
|
|
|
|
async function handleSignOut(): Promise<void> {
|
|
await signOut();
|
|
router.replace('/login');
|
|
}
|
|
|
|
function handleSidebarToggle(): void {
|
|
if (isMobile) {
|
|
setMobileOpen(!mobileOpen);
|
|
return;
|
|
}
|
|
|
|
toggleCollapsed();
|
|
}
|
|
|
|
return (
|
|
<header
|
|
className="app-header justify-between border-b px-4 md:px-6"
|
|
style={{
|
|
height: 'var(--topbar-h)',
|
|
background: 'color-mix(in srgb, var(--surface) 88%, transparent)',
|
|
borderBottomColor: 'var(--border)',
|
|
}}
|
|
>
|
|
<div className="flex items-center gap-3">
|
|
<button
|
|
type="button"
|
|
onClick={handleSidebarToggle}
|
|
className="btn-ghost rounded-lg border p-2"
|
|
style={{ borderColor: 'var(--border)', color: 'var(--text-2)' }}
|
|
aria-label="Toggle sidebar"
|
|
>
|
|
<MenuIcon />
|
|
</button>
|
|
<div className="hidden sm:block">
|
|
<div className="text-sm font-medium text-[var(--text)]">Workspace</div>
|
|
<div className="text-xs text-[var(--muted)]">Unified agent operations</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex items-center gap-3">
|
|
<ThemeToggle />
|
|
{session?.user ? (
|
|
<>
|
|
<span className="hidden text-sm text-[var(--text-2)] sm:block">
|
|
{session.user.name ?? session.user.email}
|
|
</span>
|
|
<button
|
|
type="button"
|
|
onClick={handleSignOut}
|
|
className="rounded-md px-3 py-1.5 text-sm transition-colors"
|
|
style={{ color: 'var(--muted)' }}
|
|
>
|
|
Sign out
|
|
</button>
|
|
</>
|
|
) : (
|
|
<span className="text-sm text-[var(--muted)]">Not signed in</span>
|
|
)}
|
|
</div>
|
|
</header>
|
|
);
|
|
}
|