37 lines
2.5 KiB
TypeScript
37 lines
2.5 KiB
TypeScript
import Link from 'next/link';
|
||
|
||
const ANALYTICS_BACKEND = process.env.ANALYTICS_BACKEND_URL || 'http://127.0.0.1:8000';
|
||
|
||
async function getMatches() {
|
||
const response = await fetch(`${ANALYTICS_BACKEND}/analytics/matches`, { cache: 'no-store' });
|
||
if (!response.ok) throw new Error('賽程 API 暫時無法回應');
|
||
return response.json();
|
||
}
|
||
|
||
function taipeiDate(value: string) {
|
||
return new Intl.DateTimeFormat('zh-TW', { timeZone: 'Asia/Taipei', month: '2-digit', day: '2-digit', weekday: 'short' }).format(new Date(value));
|
||
}
|
||
|
||
function taipeiTime(value: string) {
|
||
return new Intl.DateTimeFormat('zh-TW', { timeZone: 'Asia/Taipei', hour: '2-digit', minute: '2-digit', hour12: false }).format(new Date(value));
|
||
}
|
||
|
||
export default async function SchedulePage() {
|
||
let matches: any[] = [];
|
||
let error = '';
|
||
try { matches = await getMatches(); } catch (err) { error = err instanceof Error ? err.message : '賽程暫時無法讀取'; }
|
||
const grouped = matches.reduce<Record<string, any[]>>((acc, match) => {
|
||
const key = taipeiDate(match.kickoff_utc);
|
||
acc[key] = [...(acc[key] ?? []), match];
|
||
return acc;
|
||
}, {});
|
||
|
||
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]">完整賽程表</p><h1 className="mt-3 text-4xl font-black text-[#3f2f25]">依台北時間排序的全部賽事</h1><p className="mt-3 text-sm leading-7 text-[#6f4f3c]">保留世界盃開踢日起所有日期,完賽結果也會持續保留,方便回看推薦與賽果校準。</p></section>
|
||
{error ? <p className="rounded-2xl border border-[#e7a49a] bg-[#fff0e8] p-4 text-sm font-bold text-[#b83822]">{error}</p> : null}
|
||
{Object.entries(grouped).map(([date, rows]) => <section key={date} className="rounded-3xl border border-[#eadcb9] bg-white/75 p-5"><h2 className="dot-matrix text-lg font-bold text-[#7d2a15]">{date}|{rows.length} 場</h2><div className="mt-4 grid gap-3">{rows.map((match) => <Link key={match.match_id} href={`/matches/${match.match_id}`} className="rounded-2xl border border-[#eadcb9] bg-[#fff8e6] p-4 transition hover:border-[#b83822]"><p className="font-black text-[#3f2f25]">{taipeiTime(match.kickoff_utc)}|{match.home_team} vs {match.away_team}</p><p className="mt-1 text-sm text-[#7a5b46]">{match.status}|{match.home_score ?? '-'} : {match.away_score ?? '-'}|{match.venue_city ?? '場地待定'}</p></Link>)}</div></section>)}
|
||
</div>
|
||
);
|
||
}
|