mancala/apps/frontend/src/routes/Home.tsx
Halit Aksoy d444447425 feat(frontend): offer the tutorial to newcomers and a practice game
The home page shows newcomers a banner to start the lessons; it goes away for
good after Not now, a lesson or a game. The lessons end with a practice game
against the Easy bot with hints on.
2026-10-16 14:55:51 +03:00

78 lines
2.8 KiB
TypeScript

import * as React from "react";
import { FunctionComponent, useEffect, useState } from "react";
import { LiveGameSummary } from "@mancala/core";
import { AuthUser, BotLevel, Theme } from "@mancala/core";
import AppHeader from "../components/headerbar/AppHeader";
import PageContainer from "../components/PageContainer";
import { PlusIcon } from "../components/Icons";
import BotLevelMenu from "../components/BotLevelMenu";
import ActiveGameBanner from "../components/home/ActiveGameBanner";
import TutorialBanner from "../components/home/TutorialBanner";
import LiveGamesSection from "../components/home/LiveGamesSection";
import RecentGamesSection from "../components/home/RecentGamesSection";
import PopularGamesSection from "../components/home/PopularGamesSection";
import "../components/home/Home.css";
import { Context } from "../context/context";
import { useNavigate } from "react-router-dom";
import Util from "../util/Util";
import { useTranslation } from "react-i18next";
const Home: FunctionComponent<{
context: Context,
userKey?: string,
authUser?: AuthUser,
theme: Theme,
}> = ({ context, userKey, authUser, theme }) => {
const navigate = useNavigate();
const [activeGame, setActiveGame] = useState<LiveGameSummary | null>(null);
useEffect(() => {
if (!authUser) return;
let disposed = false;
context.authService.getAccessToken()
.then((token) => context.gameStore.getActiveGame(token))
.then((game) => !disposed && setActiveGame(game))
.catch((error) => console.error("(Home) Could not load the active game", error));
return () => { disposed = true; };
}, [authUser?.id]);
const { t } = useTranslation();
const onNewGameClick = () => {
if(Util.checkConnectionAndMaybeAlert(context, t)) return;
navigate("/loby")
};
const onBotLevelChosen = (level: BotLevel) => {
if(Util.checkConnectionAndMaybeAlert(context, t)) return;
navigate(`/loby?bot=${level}`)
};
return (
<PageContainer>
<AppHeader context={context} authUser={authUser}>
<BotLevelMenu context={context} onChoose={onBotLevelChosen} />
<button className="btn pri ic-m" aria-label={t("NewGame")} onClick={onNewGameClick}>
<PlusIcon /><span className="hide-m">{t("NewGame")}</span>
</button>
</AppHeader>
<main className="wrap">
<TutorialBanner context={context} />
{activeGame && authUser && (
<ActiveGameBanner
game={activeGame}
userId={authUser.id}
onContinue={() => navigate(`/game/${activeGame.id}`)} />
)}
<LiveGamesSection context={context} />
<PopularGamesSection context={context} />
{authUser && <RecentGamesSection context={context} userId={authUser.id} />}
</main>
</PageContainer>
);
};
export default Home;