43 lines
1.7 KiB
TypeScript
43 lines
1.7 KiB
TypeScript
|
|
import * as React from "react";
|
|||
|
|
import { FunctionComponent } from "react";
|
|||
|
|
import { getPlayerDisplayName, PlayerSummary } from "@mancala/core";
|
|||
|
|
import { useTranslation } from "react-i18next";
|
|||
|
|
import { Link } from "react-router-dom";
|
|||
|
|
import MiniBoard, { getStores } from "./MiniBoard";
|
|||
|
|
|
|||
|
|
// A game as a card: the players with the score, a mini board, a status pill and details. Links to the game.
|
|||
|
|
const GameCard: FunctionComponent<{
|
|||
|
|
id: string,
|
|||
|
|
player1: PlayerSummary,
|
|||
|
|
player2: PlayerSummary,
|
|||
|
|
board: number[],
|
|||
|
|
// Show player 2's side at the bottom.
|
|||
|
|
revert?: boolean,
|
|||
|
|
status: string,
|
|||
|
|
// Class of the status pill: "live", "win", "lose" or "".
|
|||
|
|
statusKind: string,
|
|||
|
|
details: string,
|
|||
|
|
}> = ({ id, player1, player2, board, revert, status, statusKind, details }) => {
|
|||
|
|
const { t } = useTranslation();
|
|||
|
|
const name = (player: PlayerSummary) => getPlayerDisplayName(player, t) ?? t("Anonymous");
|
|||
|
|
const [bottomPlayer, topPlayer] = revert ? [player2, player1] : [player1, player2];
|
|||
|
|
const stores = getStores(board, revert);
|
|||
|
|
return (
|
|||
|
|
<Link className="card" to={`/game/${id}`}
|
|||
|
|
aria-label={`${name(topPlayer)} ${stores.top} – ${stores.bottom} ${name(bottomPlayer)}, ${status}`}>
|
|||
|
|
<div className="vs">
|
|||
|
|
<span className="pn">{name(topPlayer)}</span>
|
|||
|
|
<span className="score">{`${stores.top} – ${stores.bottom}`}</span>
|
|||
|
|
<span className="pn r">{name(bottomPlayer)}</span>
|
|||
|
|
</div>
|
|||
|
|
<MiniBoard board={board} revert={revert} />
|
|||
|
|
<div className="meta">
|
|||
|
|
<span className={"pill " + statusKind}>{status}</span>
|
|||
|
|
<span>{details}</span>
|
|||
|
|
</div>
|
|||
|
|
</Link>
|
|||
|
|
);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
export default GameCard;
|