'use client'; // 九宮格 App Launcher(受 Google Apps menu 啟發) // 規範:matrix/identity/.agents/specs/identity/design.md §2.5 // 非白名單 user 看到 mira 等受限 app 顯示為灰色 + tooltip「即將開放」 import { useEffect, useRef, useState } from 'react'; import { MATRIX_APPS, isAppAccessible, type AppEntry } from './apps'; export default function AppLauncher({ userEmail }: { userEmail: string | null }) { const [open, setOpen] = useState(false); const ref = useRef(null); useEffect(() => { if (!open) return; const onClickOutside = (e: MouseEvent) => { if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false); }; document.addEventListener('mousedown', onClickOutside); return () => document.removeEventListener('mousedown', onClickOutside); }, [open]); return (
{open && (
{MATRIX_APPS.map(app => ( setOpen(false)} /> ))}
)}
); } function AppTile({ app, userEmail, onClose, }: { app: AppEntry; userEmail: string | null; onClose: () => void; }) { const accessible = isAppAccessible(app, userEmail); const tooltip = !accessible ? (app.locked_tooltip ?? '即將開放') : (app.description ?? ''); if (!accessible) { return (
{app.icon ?? '📦'} {app.name}
); } return ( {app.icon ?? '📦'} {app.name} ); }