sendou.ink/app/components/match-page/MatchBannerBottomRow.tsx
Kalle 2b5b1b1948
Some checks are pending
E2E Tests / e2e (push) Waiting to run
Tests and checks on push / run-checks-and-tests (push) Waiting to run
Updates translation progress / update-translation-progress-issue (push) Waiting to run
New match page (#3032)
2026-05-04 18:15:10 +03:00

103 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import clsx from "clsx";
import { MousePointerClick } from "lucide-react";
import { useTranslation } from "react-i18next";
import type { ModeShort } from "~/modules/in-game-lists/types";
import type { CommonUser } from "~/utils/kysely.server";
import { Avatar } from "../Avatar";
import { ModeImage } from "../Image";
import styles from "./MatchBannerBottomRow.module.css";
interface MatchBannerBottomRowProps {
games: Array<{ mode: ModeShort | null; winner?: "ALPHA" | "BRAVO" }>;
activeRosters: {
alpha: CommonUser[] | null;
bravo: CommonUser[] | null;
} | null;
}
export function MatchBannerBottomRow({
games,
activeRosters,
}: MatchBannerBottomRowProps) {
return (
<div className={styles.root}>
<ModeProgress games={games} />
<ActiveRosters activeRosters={activeRosters} />
</div>
);
}
function ModeProgress({ games }: Pick<MatchBannerBottomRowProps, "games">) {
const knownModes = games.flatMap((game) => (game.mode ? [game.mode] : []));
const allSameMode =
knownModes.length === games.length &&
games.length > 1 &&
knownModes.every((mode) => mode === knownModes[0]);
if (allSameMode) {
return (
<div className={styles.modeProgress}>
<div
className={styles.mode}
data-testid={`mode-progress-${knownModes[0]}`}
>
<ModeImage mode={knownModes[0]} size={16} />
</div>
<div className={styles.modeCount}>×{games.length}</div>
</div>
);
}
return (
<div className={styles.modeProgress}>
{games.map((game, i) =>
game.mode ? (
<div
key={i}
className={styles.mode}
data-testid={`mode-progress-${game.mode}`}
>
<ModeImage mode={game.mode} size={16} />
</div>
) : (
<div
key={i}
className={clsx(styles.mode, styles.modePlaceholder)}
data-testid="mode-progress-banned"
>
<MousePointerClick size={16} />
</div>
),
)}
</div>
);
}
function Roster({ users }: { users: CommonUser[] }) {
return (
<div className={styles.team}>
{users.map((user) => (
<Avatar key={user.id} user={user} size="xxs" />
))}
</div>
);
}
function ActiveRosters({
activeRosters,
}: Pick<MatchBannerBottomRowProps, "activeRosters">) {
const { t } = useTranslation(["q"]);
if (!activeRosters?.alpha || !activeRosters.bravo) {
return null;
}
return (
<div className={styles.activeRosters}>
<Roster users={activeRosters.alpha} />
<div className={styles.vs}>{t("q:match.banner.vs")}</div>
<Roster users={activeRosters.bravo} />
</div>
);
}