locale second stage
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState, useCallback } from "react";
|
||||
import { useEffect, useState, useCallback, useMemo, use } from "react";
|
||||
import { GroupId, GroupTable, Match, Team, ThirdPlaceRow } from "@/lib/types";
|
||||
import { ThirdAssignment } from "@/lib/bracket";
|
||||
import { getDictionary, Locale, Dictionary } from "@/lib/i18n";
|
||||
import Groups from "./components/Groups";
|
||||
import ThirdPlace from "./components/ThirdPlace";
|
||||
import Bracket from "./components/Bracket";
|
||||
@@ -24,7 +25,9 @@ interface ApiData {
|
||||
|
||||
type Tab = "groups" | "groupfixtures" | "kofixtures" | "thirds" | "bracket" | "sim";
|
||||
|
||||
export default function Home() {
|
||||
export default function Home({ params }: { params: Promise<{ locale: string }> }) {
|
||||
const { locale } = use(params) as { locale: Locale };
|
||||
const dict = useMemo(() => getDictionary(locale), [locale]);
|
||||
const [data, setData] = useState<ApiData | null>(null);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [tab, setTab] = useState<Tab>("kofixtures");
|
||||
@@ -33,7 +36,7 @@ export default function Home() {
|
||||
|
||||
const load = useCallback(async () => {
|
||||
try {
|
||||
const res = await fetch("/api/matches", { cache: "no-store" });
|
||||
const res = await fetch(`/api/matches?locale=${locale}`, { cache: "no-store" });
|
||||
if (!res.ok) {
|
||||
const body = await res.json().catch(() => ({}));
|
||||
throw new Error(body.detail || `Fehler ${res.status}`);
|
||||
@@ -43,7 +46,7 @@ export default function Home() {
|
||||
} catch (e) {
|
||||
setError(e instanceof Error ? e.message : "Verbindung fehlgeschlagen");
|
||||
}
|
||||
}, []);
|
||||
}, [locale]);
|
||||
|
||||
useEffect(() => {
|
||||
load();
|
||||
@@ -67,37 +70,37 @@ export default function Home() {
|
||||
<div className="wrap masthead-inner">
|
||||
<div className="brand">
|
||||
<span className="brand-mark">WM <span className="accent">26</span></span>
|
||||
<span className="brand-sub">USA · Kanada · Mexiko</span>
|
||||
<span className="brand-sub">{dict.header.hostCountries}</span>
|
||||
</div>
|
||||
<span className="status-pill">
|
||||
<span className={`dot ${anyLive ? "live" : data ? "on" : ""}`} />
|
||||
{error
|
||||
? "Feed offline"
|
||||
? dict.status.feedOffline
|
||||
: data
|
||||
? anyLive ? "Live" : `Aktualisiert ${new Date(data.updatedAt).toLocaleTimeString("de-DE")}`
|
||||
: "Lade Daten…"}
|
||||
? anyLive ? dict.status.live : dict.status.updated(new Date(data.updatedAt).toLocaleTimeString(locale === "en" ? "en-US" : "de-DE"))
|
||||
: dict.status.loading}
|
||||
</span>
|
||||
<nav className="tabs masthead-tabs">
|
||||
<button className={`tab ${tab === "kofixtures" ? "active" : ""}`} onClick={() => setTab("kofixtures")}>
|
||||
K.O.-Spiele
|
||||
{dict.nav.koFixtures}
|
||||
</button>
|
||||
<button className={`tab ${tab === "groups" ? "active" : ""}`} onClick={() => setTab("groups")}>
|
||||
Gruppen
|
||||
{dict.nav.groups}
|
||||
</button>
|
||||
<button
|
||||
className={`tab ${tab === "groupfixtures" ? "active" : ""}`}
|
||||
onClick={() => { if (!fixturesGroup) setFixturesGroup("A"); setTab("groupfixtures"); }}
|
||||
>
|
||||
{fixturesGroup ? `Gruppenspiele – ${fixturesGroup}` : "Gruppenspiele"}
|
||||
{fixturesGroup ? dict.nav.groupFixtures(fixturesGroup) : dict.nav.groupFixturesNoGroup}
|
||||
</button>
|
||||
<button className={`tab ${tab === "thirds" ? "active" : ""}`} onClick={() => setTab("thirds")}>
|
||||
Drittplatzierte
|
||||
{dict.nav.thirdPlace}
|
||||
</button>
|
||||
<button className={`tab ${tab === "bracket" ? "active" : ""}`} onClick={() => setTab("bracket")}>
|
||||
K.o.-Baum
|
||||
{dict.nav.bracket}
|
||||
</button>
|
||||
<button className={`tab ${tab === "sim" ? "active" : ""}`} onClick={() => setTab("sim")}>
|
||||
Simulation
|
||||
{dict.nav.simulation}
|
||||
</button>
|
||||
</nav>
|
||||
</div>
|
||||
@@ -108,9 +111,7 @@ export default function Home() {
|
||||
<section className="section">
|
||||
{error && (
|
||||
<div className="notice err">
|
||||
Die Live-Feeds sind gerade nicht erreichbar: {error}.
|
||||
Prüfe den <code>FOOTBALL_DATA_TOKEN</code> und die Netzwerkfreigabe des Servers.
|
||||
Die Seite versucht es automatisch erneut.
|
||||
{dict.error.feedUnreachable}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -121,32 +122,32 @@ export default function Home() {
|
||||
)}
|
||||
|
||||
{data && tab === "kofixtures" && (
|
||||
<KoFixtures teams={data.teams} matches={data.matches} />
|
||||
<KoFixtures teams={data.teams} matches={data.matches} dict={dict} locale={locale} />
|
||||
)}
|
||||
{data && tab === "groups" && (
|
||||
<Groups
|
||||
tables={data.groupTablesLive} teams={data.teams} matches={data.matches}
|
||||
onOpenGroup={openGroupFixtures}
|
||||
onOpenGroup={openGroupFixtures} dict={dict} locale={locale}
|
||||
/>
|
||||
)}
|
||||
{data && tab === "groupfixtures" && fixturesGroup && (
|
||||
<Fixtures
|
||||
group={fixturesGroup} teams={data.teams} matches={data.matches}
|
||||
onSelectGroup={setFixturesGroup}
|
||||
onSelectGroup={setFixturesGroup} dict={dict} locale={locale}
|
||||
/>
|
||||
)}
|
||||
{data && tab === "thirds" && (
|
||||
<ThirdPlace rows={data.thirdTable} teams={data.teams} secureTeams={data.secureThirdTeams} />
|
||||
<ThirdPlace rows={data.thirdTable} teams={data.teams} secureTeams={data.secureThirdTeams} dict={dict} />
|
||||
)}
|
||||
{data && tab === "bracket" && (
|
||||
<Bracket
|
||||
matches={data.matches} teams={data.teams} tables={data.groupTablesLive}
|
||||
thirds={data.thirdTable} assignment={data.annexAssignment}
|
||||
annexResolved={data.annexResolved}
|
||||
annexResolved={data.annexResolved} dict={dict} locale={locale}
|
||||
/>
|
||||
)}
|
||||
{data && tab === "sim" && (
|
||||
<Simulation teams={data.teams} matches={data.matches} />
|
||||
<Simulation teams={data.teams} matches={data.matches} dict={dict} locale={locale} />
|
||||
)}
|
||||
</section>
|
||||
</main>
|
||||
@@ -182,13 +183,13 @@ export default function Home() {
|
||||
fontFamily: "var(--font-mono)", fontSize: 10,
|
||||
color: "var(--ink-faint)",
|
||||
}}>
|
||||
WM 2026 Dashboard
|
||||
{dict.footer.dashboard}
|
||||
</span>
|
||||
<span style={{
|
||||
fontFamily: "var(--font-mono)", fontSize: 9,
|
||||
color: "var(--ink-faint)", opacity: 0.5, marginTop: 8,
|
||||
}}>
|
||||
Daten: football-data.org · Polymarket Gamma API · FIFA Annex C
|
||||
{dict.footer.dataSources}
|
||||
</span>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
Reference in New Issue
Block a user