Files
Arcrun/landing/app/components/SiteNav.tsx
T
uncle6me-web 5d00e71275 chore: D22 落地——docs/SDD/wiki/CLAUDE.md 進 repo(Gitea private 預設全 push)
頂層 D22 決策(leo 2026-07-03 拍板):推什麼由開發環境歸屬決定,
Gitea private=除機敏值/build 產物/.github 外全 push。
解 T1.5 卡點:雲端工人 clone 拿得到 credential-store-migration.md,可就地改寫 SDD。
機敏掃描兩輪通過(新增 189 檔約 2.1MB,node_modules/dist/wasm 照舊排除)。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 07:13:33 +08:00

83 lines
2.7 KiB
TypeScript

'use client';
import { useEffect, useState } from 'react';
import Link from 'next/link';
import AppLauncher from './AppLauncher';
const API_BASE = process.env.NEXT_PUBLIC_API_BASE ?? 'https://cypher.arcrun.dev';
type NavUser = {
display_name: string;
email: string;
avatar_url?: string;
};
export default function SiteNav({ currentPath }: { currentPath?: string }) {
const [user, setUser] = useState<NavUser | null | undefined>(undefined);
useEffect(() => {
fetch(`${API_BASE}/me`, { credentials: 'include' })
.then(r => r.ok ? r.json() as Promise<NavUser> : null)
.then(u => setUser(u))
.catch(() => setUser(null));
}, []);
const logout = async () => {
await fetch(`${API_BASE}/auth/logout`, { method: 'POST', credentials: 'include' });
window.location.href = '/';
};
const linkCls = (path: string) =>
`transition-colors text-sm ${currentPath === path ? 'text-white' : 'text-[#666] hover:text-white'}`;
return (
<nav className="flex items-center justify-between px-6 py-4 border-b border-[#1a1a1a]">
<Link href="/" className="text-white font-bold text-lg tracking-tight hover:opacity-80 transition-opacity">
arcrun
</Link>
<div className="flex items-center gap-4 text-sm">
<Link href="/integrations" className={linkCls('/integrations')}>Integrations</Link>
<Link href="/api-docs" className={linkCls('/api-docs')}>API</Link>
<a
href="https://github.com/richblack/arcrun"
target="_blank"
rel="noopener noreferrer"
className="text-[#666] hover:text-white transition-colors"
>
GitHub
</a>
{user === undefined ? (
// Loading — placeholder to prevent layout shift
<div className="w-20 h-7" />
) : user ? (
<>
<AppLauncher userEmail={user.email} />
<Link href="/dashboard" className="flex items-center gap-2 hover:opacity-80 transition-opacity">
{user.avatar_url && (
// eslint-disable-next-line @next/next/no-img-element
<img src={user.avatar_url} alt="" width={26} height={26} className="rounded-full" />
)}
<span className="text-[#aaa]">{user.display_name}</span>
</Link>
<button
onClick={logout}
className="text-[#555] hover:text-[#888] transition-colors cursor-pointer"
>
登出
</button>
</>
) : (
<Link
href="/login"
className="bg-indigo-600 hover:bg-indigo-500 text-white px-4 py-1.5 rounded-md font-medium transition-colors"
>
Get API Key
</Link>
)}
</div>
</nav>
);
}