From 8410898372fef5e052ff37c9c3027e43116da2c3 Mon Sep 17 00:00:00 2001 From: Kalle <38327916+Sendouc@users.noreply.github.com> Date: Mon, 7 Feb 2022 22:24:17 +0200 Subject: [PATCH] Submit score --- app/components/play/MapList.tsx | 61 ++++++++++++++++++++++++++------- app/models/LFGMatch.server.ts | 24 +++++++++++++ app/routes/play/match.$id.tsx | 16 +++++++-- app/styles/play-match.css | 6 ++++ 4 files changed, 92 insertions(+), 15 deletions(-) diff --git a/app/components/play/MapList.tsx b/app/components/play/MapList.tsx index 6ace143ac..78407f2bf 100644 --- a/app/components/play/MapList.tsx +++ b/app/components/play/MapList.tsx @@ -2,16 +2,14 @@ import { Mode } from "@prisma/client"; import clsx from "clsx"; import clone from "just-clone"; import { useState } from "react"; +import { Form } from "remix"; import { scoreValid } from "~/core/play/validators"; +import { Button } from "../Button"; import { ModeImage } from "../ModeImage"; const NO_RESULT = "NO_RESULT"; -export function MapList({ - mapList, - canSubmitScore, - groupIds, -}: { +interface MapListProps { mapList: { name: string; mode: Mode; @@ -21,8 +19,11 @@ export function MapList({ our: string; their: string; }; -}) { - const [winners, setWinners] = useState([]); +} +export function MapList({ mapList, canSubmitScore, groupIds }: MapListProps) { + const [winners, setWinners] = useState( + new Array(5).fill(null).map(() => "5f31654d-977b-402b-817a-6f20cd933aa5") + ); const updateWinners = (winnerId: string, index: number) => { const newWinners = clone(winners); @@ -39,11 +40,6 @@ export function MapList({ setWinners(newWinners); }; - // TODO: not properly handling scores getting reported after conclusion - const warningText = scoreValid(winners, mapList.length) - ? undefined - : "Report more maps to submit the score"; - return (

    Map list

    @@ -75,7 +71,46 @@ export function MapList({ ); })} -
    {warningText}
    + {canSubmitScore && }
); } + +function Submitter({ + mapList, + winners, +}: { + mapList: MapListProps["mapList"]; + winners: string[]; +}) { + // TODO: not properly handling scores getting reported after conclusion + const warningText = scoreValid(winners, mapList.length) + ? undefined + : "Report more maps to submit the score"; + + if (warningText) { + return
{warningText}
; + } + + const ids = Array.from(new Set(winners)); + const score = winners.reduce( + (acc: [number, number], winnerId) => { + if (winnerId === ids[0]) acc[0]++; + else acc[1]++; + + return acc; + }, + [0, 0] + ); + + return ( +
+
+ + +
+
+ ); +} diff --git a/app/models/LFGMatch.server.ts b/app/models/LFGMatch.server.ts index 6cc0c0322..e3835ce5f 100644 --- a/app/models/LFGMatch.server.ts +++ b/app/models/LFGMatch.server.ts @@ -18,3 +18,27 @@ export function findById(id: string) { }, }); } + +export function reportScore({ + matchId, + winnerIds, +}: { + matchId: string; + 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(",")} + ) as lfg2(lfg_group_match_id, "order", winner_id) + where lfg2.lfg_group_match_id = lfg."lfgGroupMatchId" and lfg2.order = lfg.order; +`); + // 1) update scores DONE + // 2) update skill + // 3) update team skill? + // 4) if already reported error if different +} diff --git a/app/routes/play/match.$id.tsx b/app/routes/play/match.$id.tsx index 2d6dfd46f..3a2ca68c3 100644 --- a/app/routes/play/match.$id.tsx +++ b/app/routes/play/match.$id.tsx @@ -25,6 +25,7 @@ import { makeTitle, parseRequestFormData, requireUser, + safeJSONParse, UserLean, validate, } from "~/utils"; @@ -52,7 +53,11 @@ const matchActionSchema = z.union([ _action: z.literal("LOOK_AGAIN"), }), z.object({ - _action: z.literal("PLACEHOLDER"), + _action: z.literal("REPORT_SCORE"), + winnerIds: z.preprocess( + safeJSONParse, + z.array(z.string().uuid()).min(5).max(9) + ), }), ]); @@ -67,7 +72,14 @@ export const action: ActionFunction = async ({ request, context }) => { validate(ownGroup, "No active group"); switch (data._action) { - case "PLACEHOLDER": + case "REPORT_SCORE": { + validate(ownGroup.matchId, "No match for the group"); + await LFGMatch.reportScore({ + matchId: ownGroup.matchId, + winnerIds: data.winnerIds, + }); + break; + } case "LOOK_AGAIN": { validate(!ownGroup.ranked, "Score reporting required"); await LFGGroup.setInactive(ownGroup.id); diff --git a/app/styles/play-match.css b/app/styles/play-match.css index 422a0c1dd..bfd865e85 100644 --- a/app/styles/play-match.css +++ b/app/styles/play-match.css @@ -115,3 +115,9 @@ margin-block-start: var(--s-4); text-align: center; } + +.play-match__score-submit-button { + display: flex; + justify-content: center; + margin-block-start: var(--s-4); +}