o2o-triple-pick/app/match/[matchId]/page.tsx

101 lines
3.5 KiB
TypeScript

import type { Metadata } from "next";
import Link from "next/link";
import { notFound } from "next/navigation";
import Hero from "@/components/Hero";
import MatchupHUD from "@/components/MatchupHUD";
import Arena from "@/components/Arena";
import Footer from "@/components/Footer";
import { GROUP_A } from "@/lib/schedule";
import { getPredictions, getCrowd, matchUrl } from "@/lib/mockData";
import { parseLang, dict, teamShort } from "@/lib/i18n";
// L2. 경기 상세(대결) 페이지 — 6경기 정적 생성
export function generateStaticParams() {
return GROUP_A.map((m) => ({ matchId: m.matchId }));
}
export async function generateMetadata({
params,
}: {
params: Promise<{ matchId: string }>;
}): Promise<Metadata> {
const { matchId } = await params;
const match = GROUP_A.find((m) => m.matchId === matchId);
if (!match) return { title: "TriplePick 2026" };
const title = `${match.teamA.shortName} vs ${match.teamB.shortName} AI 승부예측 | TriplePick`;
const desc = `GPT·Claude·Gemini가 ${match.teamA.name} vs ${match.teamB.name}를 서로 다르게 예측했습니다. 당신의 픽을 찍고 AI와 겨뤄보세요.`;
return {
title,
description: desc,
openGraph: { title, description: desc, siteName: "TriplePick", type: "website", locale: "ko_KR" },
twitter: { card: "summary_large_image", title, description: desc },
};
}
export default async function MatchPage({
params,
searchParams,
}: {
params: Promise<{ matchId: string }>;
searchParams: Promise<{ lang?: string }>;
}) {
const { matchId } = await params;
const { lang: langParam } = await searchParams;
const lang = parseLang(langParam);
const t = dict(lang);
const match = GROUP_A.find((m) => m.matchId === matchId);
if (!match) notFound();
const predictions = getPredictions(match, lang);
const crowd = getCrowd(match);
const aShort = teamShort(match.teamA, lang);
const bShort = teamShort(match.teamB, lang);
const hook = lang === "en" ? t.hook(aShort, bShort) : match.hookText;
return (
<main className="shell">
<Hero
back
lang={lang}
share={{
url: matchUrl(match.matchId),
title: `${aShort} vs ${bShort} — TriplePick`,
text:
lang === "en"
? `${hook} — see all 3 AI picks and make yours!`
: `${hook} — AI 셋의 예측을 보고 당신의 픽을 찍어보세요!`,
}}
/>
{/* 경기별 후킹 카피 (한 줄) */}
<h1 className="mt-6 flex items-center justify-center gap-2 whitespace-nowrap text-[19px] font-extrabold leading-snug">
<span className="text-[var(--green)]"></span>
{hook}
<span className="text-[var(--green)]"></span>
</h1>
<MatchupHUD match={match} lang={lang} />
<Arena
match={match}
predictions={predictions}
crowd={crowd}
shareUrl={matchUrl(match.matchId)}
lang={lang}
/>
{/* 하단 CTA — 전체 일정으로(다른 경기 투표). ADO2 사용해보기 버튼과 동일 사양(퍼플 #A65EFF) */}
<Link
href={lang === "en" ? "/?lang=en" : "/"}
className="mt-7 flex items-center justify-center gap-1.5 rounded-full bg-[#A65EFF] px-6 py-3 text-[15px] font-extrabold text-white transition active:scale-[0.99]"
style={{ boxShadow: "0 10px 28px rgba(166,94,255,0.40)" }}
>
{t.moreMatches}
<span aria-hidden></span>
</Link>
<Footer lang={lang} />
</main>
);
}