Remove rest useFetchers

This commit is contained in:
Kalle (Sendou)
2021-12-25 23:01:29 +02:00
parent 0b6a831765
commit a4d45e2577
4 changed files with 54 additions and 15 deletions

View File

@@ -0,0 +1,13 @@
export function CheckInIcon({ className }: { className?: string }) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
className={className}
viewBox="0 0 20 20"
fill="currentColor"
>
<path d="M8.707 7.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l2-2a1 1 0 00-1.414-1.414L11 7.586V3a1 1 0 10-2 0v4.586l-.293-.293z" />
<path d="M3 5a2 2 0 012-2h1a1 1 0 010 2H5v7h2l1 2h4l1-2h2V5h-1a1 1 0 110-2h1a2 2 0 012 2v10a2 2 0 01-2 2H5a2 2 0 01-2-2V5z" />
</svg>
);
}

View File

@@ -1,16 +1,17 @@
// TODO: Warning: Text content did not match. Server: "57" Client: "56"
import * as React from "react";
import { useFetcher, useLoaderData } from "remix";
import { useTransition, useLoaderData, Form } from "remix";
import {
checkInClosesDate,
TOURNAMENT_TEAM_ROSTER_MIN_SIZE,
} from "~/constants";
import { TournamentAction } from "~/routes/to/$organization.$tournament";
import type { FindTournamentByNameForUrlI } from "~/services/tournament";
import { Unpacked } from "~/utils";
import { Button } from "../Button";
import { AlertIcon } from "../icons/Alert";
import { CheckmarkIcon } from "../icons/Checkmark";
import { CheckInIcon } from "../icons/CheckIn";
import { ErrorIcon } from "../icons/Error";
import { SuccessIcon } from "../icons/Success";
import { ActionSectionWrapper } from "./ActionSectionWrapper";
@@ -20,7 +21,7 @@ export function ActionSectionBeforeStartContent({
}: {
ownTeam: Unpacked<FindTournamentByNameForUrlI["teams"]>;
}) {
const fetcher = useFetcher();
const transition = useTransition();
const tournament = useLoaderData<FindTournamentByNameForUrlI>();
const timeInMinutesBeforeCheckInCloses = () => {
@@ -111,21 +112,25 @@ export function ActionSectionBeforeStartContent({
<AlertIcon /> Check-in closes in less than a minute
</>
)}
<fetcher.Form
<Form
method="post"
action={`/api/tournamentTeam/${ownTeam.id}/check-in`}
className="tournament__action-section__button-container"
>
<input
type="hidden"
name="_action"
value={TournamentAction.CHECK_IN}
/>
<input type="hidden" name="teamId" value={ownTeam.id} />
<Button
variant="outlined-success"
loadingText="Checking in..."
variant="outlined"
type="submit"
loading={fetcher.state !== "idle"}
icon={<CheckmarkIcon />}
loading={transition.state !== "idle"}
icon={<CheckInIcon />}
>
Check-in
</Button>
</fetcher.Form>
</Form>
</ActionSectionWrapper>
);
}

View File

@@ -3,6 +3,7 @@
import {
LinksFunction,
LoaderFunction,
ActionFunction,
MetaFunction,
NavLink,
Outlet,
@@ -15,10 +16,11 @@ import { InfoBanner } from "~/components/tournament/InfoBanner";
import { isTournamentAdmin } from "~/core/tournament/permissions";
import { tournamentHasStarted } from "~/core/tournament/utils";
import {
checkIn,
findTournamentByNameForUrl,
FindTournamentByNameForUrlI,
} from "~/services/tournament";
import { makeTitle } from "~/utils";
import { makeTitle, requireUser } from "~/utils";
import type { MyCSSProperties } from "~/utils";
import { useUser } from "~/utils/hooks";
import tournamentStylesUrl from "../../styles/tournament.css";
@@ -27,6 +29,28 @@ export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: tournamentStylesUrl }];
};
export enum TournamentAction {
CHECK_IN = "CHECK_IN",
}
export const action: ActionFunction = async ({ request, context }) => {
const data = Object.fromEntries(await request.formData());
const user = requireUser(context);
switch (data._action) {
case TournamentAction.CHECK_IN: {
invariant(typeof data.teamId === "string", "Invalid type for teamId");
await checkIn({ teamId: data.teamId, userId: user.id });
break;
}
default: {
throw new Response("Bad Request", { status: 400 });
}
}
return new Response(undefined, { status: 200 });
};
export const loader: LoaderFunction = ({ params }) => {
invariant(
typeof params.organization === "string",

View File

@@ -85,10 +85,7 @@ export const action: ActionFunction = async ({
return new Response("Player deleted from team", { status: 200 });
}
default: {
return new Response(undefined, {
status: 405,
headers: { Allow: "POST, DELETE" },
});
throw new Response("Bad Request", { status: 400 });
}
}
};