Files
wooo 1e082333af
All checks were successful
2026 World Cup Quant Platform - Production Deployment / Code Quality, Security Gate & Testing (push) Successful in 4m25s
2026 World Cup Quant Platform - Production Deployment / Deploy to Production VM via Gitea CD (push) Successful in 5m22s
fix: type missing product pages
2026-06-18 15:28:30 +08:00

72 lines
3.5 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.
import Link from 'next/link';
const ANALYTICS_BACKEND = process.env.ANALYTICS_BACKEND_URL || 'http://127.0.0.1:8000';
type AgentVerificationCheck = {
agent: string;
role: string;
status_label: string;
evidence?: string[];
};
type AgentVerificationResponse = {
overall_label?: string;
production_ready?: boolean;
checks?: AgentVerificationCheck[];
};
type GeminiUsageResponse = {
estimated_cost_usd?: number;
cap_usd?: number;
};
async function fetchJson<T>(path: string): Promise<T> {
const response = await fetch(`${ANALYTICS_BACKEND}/analytics/${path}`, { cache: 'no-store' });
if (!response.ok) throw new Error(`${path} 暫時無法回應`);
return response.json() as Promise<T>;
}
export default async function AgentVerificationPage() {
let verification: AgentVerificationResponse | null = null;
let usage: GeminiUsageResponse | null = null;
let error = '';
try {
[verification, usage] = await Promise.all([
fetchJson<AgentVerificationResponse>('agent-verification'),
fetchJson<GeminiUsageResponse>('gemini-usage'),
]);
} catch (err) {
error = err instanceof Error ? err.message : 'AI 驗證資料暫時無法讀取';
}
const checks = verification?.checks ?? [];
return (
<div className="space-y-6">
<section className="rounded-[2rem] border border-[#e7c89b] bg-[#fff8e6]/95 p-6 md:p-8">
<p className="dot-matrix text-sm font-bold text-[#b83822]">AI </p>
<h1 className="mt-3 text-4xl font-black text-[#3f2f25]">Codex + Gemini + NemoTron + </h1>
<p className="mt-3 max-w-3xl text-sm leading-7 text-[#6f4f3c]">AI </p>
</section>
{error ? <p className="rounded-2xl border border-[#e7a49a] bg-[#fff0e8] p-4 text-sm font-bold text-[#b83822]">{error}</p> : null}
<section className="grid gap-4 md:grid-cols-3">
{[
['整體狀態', verification?.overall_label ?? '-', 'AI 復核結論'],
['可否正式上線', verification?.production_ready ? '可' : '不可', '仍需量化閘門'],
['Gemini 費用', usage ? `$${Number(usage.estimated_cost_usd ?? 0).toFixed(4)} / $${Number(usage.cap_usd ?? 5).toFixed(2)}` : '-', '超過上限會暫停'],
].map(([label, value, helper]) => <article key={label} className="panel-glow rounded-2xl p-5"><p className="text-xs font-semibold tracking-[0.2em] text-[#8a6b58]">{helper}</p><p className="mt-3 text-2xl font-black text-[#7d2a15]">{value}</p><p className="mt-1 text-sm text-[#6f4f3c]">{label}</p></article>)}
</section>
<section className="grid gap-4 lg:grid-cols-2">
{checks.map((item) => (
<article key={item.agent} className="rounded-3xl border border-[#eadcb9] bg-white/75 p-5">
<p className="dot-matrix text-sm font-bold text-[#7d2a15]">{item.agent}</p>
<h2 className="mt-2 text-xl font-black text-[#3f2f25]">{item.role}</h2>
<p className="mt-2 rounded-full bg-[#fff8e6] px-3 py-1 text-xs font-black text-[#7d2a15]">{item.status_label}</p>
<ul className="mt-3 space-y-2 text-sm leading-6 text-[#7a5b46]">{(item.evidence ?? []).map((line) => <li key={line}>{line}</li>)}</ul>
</article>
))}
</section>
<Link href="/recommendation-readiness" className="inline-flex rounded-full bg-[#d1432d] px-5 py-3 text-sm font-black text-white"></Link>
</div>
);
}