Match over info UI

This commit is contained in:
Kalle 2022-02-08 17:49:40 +02:00
parent 3913eea1a9
commit 4f4473b355
4 changed files with 106 additions and 19 deletions

View File

@ -21,9 +21,7 @@ interface MapListProps {
};
}
export function MapList({ mapList, canSubmitScore, groupIds }: MapListProps) {
const [winners, setWinners] = useState<string[]>(
new Array(5).fill(null).map(() => "5f31654d-977b-402b-817a-6f20cd933aa5")
);
const [winners, setWinners] = useState<string[]>([]);
const updateWinners = (winnerId: string, index: number) => {
const newWinners = clone(winners);

View File

@ -24,20 +24,20 @@ export function findById(id: string) {
}
export function reportScore({
matchId,
winnerIds,
UNSAFE_matchId,
UNSAFE_winnerIds,
}: {
matchId: string;
winnerIds: string[];
UNSAFE_matchId: string;
UNSAFE_winnerIds: string[];
}) {
// https://stackoverflow.com/a/26715934
return db.$executeRawUnsafe(`
update "LfgGroupMatchStage" as lfg set
"winnerGroupId" = lfg2.winner_id
from (values
${winnerIds
.map((winnerId, i) => `('${matchId}', ${i + 1}, '${winnerId}')`)
.join(",")}
${UNSAFE_winnerIds.map(
(winnerId, i) => `('${UNSAFE_matchId}', ${i + 1}, '${winnerId}')`
).join(",")}
) as lfg2(lfg_group_match_id, "order", winner_id)
where lfg2.lfg_group_match_id = lfg."lfgGroupMatchId" and lfg2.order = lfg.order;
`);

View File

@ -1,4 +1,5 @@
import { Mode } from "@prisma/client";
import clsx from "clsx";
import {
ActionFunction,
Form,
@ -14,6 +15,8 @@ import invariant from "tiny-invariant";
import { z } from "zod";
import { Avatar } from "~/components/Avatar";
import { Button } from "~/components/Button";
import { CheckmarkIcon } from "~/components/icons/Checkmark";
import { ModeImage } from "~/components/ModeImage";
import { MapList } from "~/components/play/MapList";
import { DISCORD_URL } from "~/constants";
import * as LFGGroup from "~/models/LFGGroup.server";
@ -75,8 +78,8 @@ export const action: ActionFunction = async ({ request, context }) => {
case "REPORT_SCORE": {
validate(ownGroup.matchId, "No match for the group");
await LFGMatch.reportScore({
matchId: ownGroup.matchId,
winnerIds: data.winnerIds,
UNSAFE_matchId: ownGroup.matchId,
UNSAFE_winnerIds: data.winnerIds,
});
break;
}
@ -111,7 +114,7 @@ interface LFGMatchLoaderData {
winner?: number;
}[];
/** The final score. Shown if match is concluded */
score?: [number, number];
scores?: [number, number];
}
export const loader: LoaderFunction = async ({ params, context }) => {
@ -154,7 +157,7 @@ export const loader: LoaderFunction = async ({ params, context }) => {
})),
};
});
const score = match.stages[0].winnerGroupId
const scores = match.stages[0].winnerGroupId
? match.stages.reduce(
(acc: [number, number], stage) => {
if (!stage.winnerGroupId) return acc;
@ -170,7 +173,7 @@ export const loader: LoaderFunction = async ({ params, context }) => {
isRanked,
isOwnMatch,
groups,
score,
scores,
mapList: match.stages
.map(({ stage, winnerGroupId }) => {
const winner = () => {
@ -183,7 +186,7 @@ export const loader: LoaderFunction = async ({ params, context }) => {
winner: winner(),
};
})
.filter((stage) => !score || typeof stage.winner === "number"),
.filter((stage) => !scores || typeof stage.winner === "number"),
});
};
@ -199,7 +202,7 @@ export default function LFGMatchPage() {
return (
<div
key={i}
className="play-match__waves-section play-match__players"
className="play-match__waves-section play-match__team-info"
>
{g.members.map((user) => (
<div key={user.id} className="play-match__player">
@ -209,6 +212,15 @@ export default function LFGMatchPage() {
</span>
</div>
))}
{data.scores && (
<div
className={clsx("play-match__score", {
winner: data.scores[i] === Math.max(...data.scores),
})}
>
{data.scores[i]}
</div>
)}
</div>
);
})}
@ -220,6 +232,37 @@ export default function LFGMatchPage() {
<code>#match-meetup</code> channel.
</div>
)}
{data.scores && (
<div className="play-match__played-map-list">
{data.mapList.map((stage) => {
return (
<>
<div
className={clsx("play-match__checkmark", "left", {
invisible: stage.winner === 0,
})}
>
<CheckmarkIcon />
</div>
<div className="play-match__played-stage">
<ModeImage
className="play-match__played-mode"
mode={stage.mode}
/>
{stage.name}
</div>
<div
className={clsx("play-match__checkmark", {
invisible: stage.winner === 1,
})}
>
<CheckmarkIcon />
</div>
</>
);
})}
</div>
)}
</div>
{!data.isRanked && (
<div className="play-match__waves-button">
@ -239,7 +282,7 @@ export default function LFGMatchPage() {
</Form>
</div>
)}
{!data.score && (
{!data.scores && (
<MapList
mapList={data.mapList}
canSubmitScore={data.isCaptain}

View File

@ -24,7 +24,42 @@
margin-block-start: var(--s-8);
}
.play-match__players {
.play-match__played-map-list {
display: grid;
justify-content: center;
font-size: var(--fonts-sm);
font-weight: var(--semi-bold);
gap: var(--s-2);
grid-template-columns: 4rem max-content 4rem;
margin-block-start: var(--s-4);
text-align: center;
}
.play-match__checkmark {
display: grid;
width: 2rem;
color: var(--theme-success);
place-items: center;
}
.play-match__checkmark.left {
margin-left: auto;
}
.play-match__played-stage {
display: flex;
flex-direction: column;
align-items: center;
padding: var(--s-1);
background-color: var(--bg-darker);
border-radius: var(--rounded);
}
.play-match__played-mode {
width: 1.5rem;
}
.play-match__team-info {
display: grid;
max-width: 14rem;
flex: 1;
@ -46,6 +81,17 @@
font-size: var(--fonts-xs);
}
.play-match__score {
border-radius: var(--rounded);
font-size: var(--fonts-lg);
font-weight: var(--bold);
grid-column: 1 / 3;
}
.play-match__score.winner {
background-color: var(--theme-transparent);
}
.play-match__waves-button {
display: flex;
justify-content: center;