Files
Arcrun/landing/app/mira/layout.tsx
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

97 lines
2.9 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
// Mira 子應用 layout
// SDD: polaris/mira/.agents/specs/mira-app/design.md §5.5
// 規範:白名單 user 進得去;非白名單 user 看到「即將開放」頁
// middleware 已做未登入跳 /loginredirect=/mira 檢查(不在這裡重做)
import { useEffect, useState } from 'react';
import SiteNav from '../components/SiteNav';
import { MATRIX_APPS } from '../components/apps';
import MiraSidebar from './_shared/MiraSidebar';
import MiraChatDock from './_shared/MiraChatDock';
import './mira.css';
const API_BASE = process.env.NEXT_PUBLIC_API_BASE ?? 'https://cypher.arcrun.dev';
type Me = { email: string; display_name: string; api_key: string };
const MIRA = MATRIX_APPS.find(a => a.id === 'mira');
const ALLOWED = new Set(MIRA?.allowlist_emails ?? []);
export default function MiraLayout({ children }: { children: React.ReactNode }) {
const [me, setMe] = useState<Me | null | undefined>(undefined);
useEffect(() => {
fetch(`${API_BASE}/me`, { credentials: 'include' })
.then(r => r.ok ? r.json() as Promise<Me> : null)
.then(u => setMe(u))
.catch(() => setMe(null));
}, []);
if (me === undefined) {
return (
<>
<SiteNav currentPath="/mira" />
<div className="flex-1 flex items-center justify-center text-[#666]">載入中…</div>
</>
);
}
if (me === null) {
// 理論上 middleware 已擋住,但保險
if (typeof window !== 'undefined') {
window.location.href = '/login?redirect=/mira';
}
return null;
}
if (!ALLOWED.has(me.email)) {
return (
<>
<SiteNav currentPath="/mira" />
<BetaBlocked email={me.email} />
</>
);
}
return (
<>
<div className="mira-topnav-sticky">
<SiteNav currentPath="/mira" />
</div>
<div className="mira-app mira-shell">
<MiraSidebar />
<div className="mira-shell-content">{children}</div>
<MiraChatDock />
</div>
</>
);
}
function BetaBlocked({ email }: { email: string }) {
return (
<main className="flex-1 flex items-center justify-center px-6">
<div className="max-w-md text-center space-y-4">
<div className="text-6xl mb-2">🌊</div>
<h1 className="text-3xl font-bold text-white">Mira 仍封測中</h1>
<p className="text-[#888] leading-relaxed">
Mira arcrun 的個人化 KM 河道,目前僅開放給少數測試用戶。
</p>
<p className="text-sm text-[#555]">
你登入的帳號是 <span className="font-mono text-[#888]">{email}</span>
不在白名單內。準備好對外開放時會公告。
</p>
<div className="pt-4">
<a
href="/dashboard"
className="inline-block bg-indigo-600 hover:bg-indigo-500 text-white px-5 py-2 rounded-md text-sm font-medium transition-colors"
>
Dashboard
</a>
</div>
</div>
</main>
);
}