Remove MyForm component

This commit is contained in:
Kalle (Sendou) 2021-12-11 10:38:15 +02:00
parent e08a0f529b
commit cdd59b139d
8 changed files with 31 additions and 65 deletions

View File

@ -50,7 +50,7 @@ You can give a variation as a flag to the seeding script changing what exactly i
- [x] Captain can remove players from roster
- [x] Add info about architecture to README
- [ ] Move away from MyForm
- [x] Move away from MyForm
- [x] Make description mandatory + overview tab
- [x] Captain can check in
- [x] Admin can check teams in / out

View File

@ -1,31 +0,0 @@
import { Form, FormProps, useFetcher, useTransition } from "remix";
interface MyFormProps extends FormProps {
hiddenFields?: Record<string, string>;
fetcher?: ReturnType<typeof useFetcher>;
}
/**
* Wrapper around Remix's Form that has default method of "post",
* creates <input type="hidden"> elements for each key/value pair in hiddenFields,
* automatically uses fetcher.Form when action is provided
* and disables the form when it's submitting.
*/
export function MyForm(props: MyFormProps) {
const { hiddenFields, children, fetcher, ...rest } = props;
const FormComponent = fetcher ? fetcher.Form : Form;
const transition = useTransition();
return (
<FormComponent method="post" {...rest}>
<fieldset disabled={transition.state !== "idle"}>
{hiddenFields &&
Object.entries(hiddenFields).map(([key, value]) => (
<input key={key} type="hidden" name={key} value={value} />
))}
{children}
</fieldset>
</FormComponent>
);
}

View File

@ -10,7 +10,6 @@ import { Button } from "../Button";
import { AlertIcon } from "../icons/Alert";
import { ErrorIcon } from "../icons/Error";
import { SuccessIcon } from "../icons/Success";
import { MyForm } from "../MyForm";
import { ActionSectionWrapper } from "./ActionSectionWrapper";
export function ActionSectionBeforeStartContent({
@ -109,10 +108,10 @@ export function ActionSectionBeforeStartContent({
<AlertIcon /> Check-in closes in less than a minute
</>
)}
<MyForm
<fetcher.Form
method="post"
action={`/api/tournamentTeam/${ownTeam.id}/check-in`}
className="tournament__action-section__button-container"
fetcher={fetcher}
>
<Button
variant="outlined"
@ -122,7 +121,7 @@ export function ActionSectionBeforeStartContent({
>
Check-in
</Button>
</MyForm>
</fetcher.Form>
</ActionSectionWrapper>
);
}

View File

@ -19,7 +19,6 @@ import * as React from "react";
import { useFetcher, useMatches } from "remix";
import { Alert } from "~/components/Alert";
import { Button } from "~/components/Button";
import { MyForm } from "~/components/MyForm";
import { TOURNAMENT_TEAM_ROSTER_MIN_SIZE } from "~/constants";
import { checkInHasStarted } from "~/core/tournament/utils";
import type { FindTournamentByNameForUrlI } from "~/services/tournament";
@ -27,7 +26,7 @@ import type { Unpacked } from "~/utils";
import { useTimeoutState } from "~/utils/hooks";
// TODO: https://docs.dndkit.com/presets/sortable#drag-overlay
// TODO: what if returns error? check other APIs too
// TODO: what if returns error? check other APIs too -> add Cypress test
export function AdminTeamControls() {
const seedsFetcher = useFetcher();
const [, parentRoute] = useMatches();
@ -224,10 +223,10 @@ function SortableRow({
function CheckOutButton({ teamId }: { teamId: string }) {
const fetcher = useFetcher();
return (
<MyForm
<fetcher.Form
method="post"
action={`/api/tournamentTeam/${teamId}/check-out`}
className="tournament__action-section__button-container"
fetcher={fetcher}
>
<Button
tiny
@ -238,17 +237,17 @@ function CheckOutButton({ teamId }: { teamId: string }) {
>
Check-out
</Button>
</MyForm>
</fetcher.Form>
);
}
function CheckInButton({ teamId }: { teamId: string }) {
const fetcher = useFetcher();
return (
<MyForm
<fetcher.Form
method="post"
action={`/api/tournamentTeam/${teamId}/check-in`}
className="tournament__action-section__button-container"
fetcher={fetcher}
>
<Button
tiny
@ -259,6 +258,6 @@ function CheckInButton({ teamId }: { teamId: string }) {
>
Check-in
</Button>
</MyForm>
</fetcher.Form>
);
}

View File

@ -1,7 +1,6 @@
import { useFetcher } from "remix";
import { useUser } from "~/utils/hooks";
import { Button } from "../Button";
import { MyForm } from "../MyForm";
export function TeamRoster({
team,
@ -79,10 +78,9 @@ function DeleteFromRosterButton({
}) {
const fetcher = useFetcher();
return (
<MyForm
action={`/api/tournamentTeam/${teamId}/remove-player/${playerId}`}
<fetcher.Form
method="delete"
fetcher={fetcher}
action={`/api/tournamentTeam/${teamId}/remove-player/${playerId}`}
>
<Button
variant="destructive"
@ -92,6 +90,6 @@ function DeleteFromRosterButton({
>
Remove
</Button>
</MyForm>
</fetcher.Form>
);
}

View File

@ -1,4 +1,4 @@
import type { ActionFunction, LinksFunction, LoaderFunction } from "remix";
import { ActionFunction, Form, LinksFunction, LoaderFunction } from "remix";
import {
json,
redirect,
@ -9,7 +9,6 @@ import {
} from "remix";
import invariant from "tiny-invariant";
import { Button } from "~/components/Button";
import { MyForm } from "~/components/MyForm";
import {
FindTournamentByNameForUrlI,
findTournamentWithInviteCodes,
@ -169,12 +168,13 @@ function Contents({ data }: { data: Data }) {
<div>
{data.inviterName} invited you to join {data.teamName} for this
tournament. Accept invite?
<MyForm
hiddenFields={{
tournamentId: parentRouteData.id,
inviteCode: data.inviteCode,
}}
>
<Form method="post">
<input
type="hidden"
name="tournamentId"
value={parentRouteData.id}
/>
<input type="hidden" name="inviteCode" value={data.inviteCode} />
<div className="tournament__join-team__buttons">
<Button
type="submit"
@ -193,7 +193,7 @@ function Contents({ data }: { data: Data }) {
</Button>
)}
</div>
</MyForm>
</Form>
</div>
);
default:

View File

@ -1,7 +1,7 @@
import { Prisma } from ".prisma/client";
import * as React from "react";
import {
ActionFunction,
Form,
json,
LinksFunction,
LoaderFunction,
@ -13,7 +13,6 @@ import invariant from "tiny-invariant";
import { Alert } from "~/components/Alert";
import { Button } from "~/components/Button";
import ErrorMessage from "~/components/ErrorMessage";
import { MyForm } from "~/components/MyForm";
import { TeamRoster } from "~/components/tournament/TeamRoster";
import { TOURNAMENT_TEAM_ROSTER_MAX_SIZE } from "~/constants";
import {
@ -157,7 +156,8 @@ export default function ManageRosterPage() {
</div>
{trustingUsers.length > 0 && (
<div className="tournament__manage-roster__actions__section">
<MyForm hiddenFields={{ teamId: ownTeam.id }}>
<Form method="post">
<input type="hidden" name="teamId" value={ownTeam.id} />
<label htmlFor="userId">
Add players you previously played with
</label>
@ -182,7 +182,7 @@ export default function ManageRosterPage() {
>
Add to roster
</Button>
</MyForm>
</Form>
</div>
)}
</div>

View File

@ -1,6 +1,7 @@
import { Prisma } from ".prisma/client";
import {
ActionFunction,
Form,
LinksFunction,
redirect,
useActionData,
@ -12,7 +13,6 @@ import {
import invariant from "tiny-invariant";
import { Button } from "~/components/Button";
import ErrorMessage from "~/components/ErrorMessage";
import { MyForm } from "~/components/MyForm";
import {
createTournamentTeam,
FindTournamentByNameForUrlI,
@ -120,7 +120,8 @@ export default function RegisterPage() {
<div className="tournament__register__container">
<h2 className="tournament__register__header">Register now</h2>
<div className="tournament__register__content">
<MyForm hiddenFields={{ tournamentId: tournamentData.id }}>
<Form method="post">
<input type="hidden" name="tournamentId" value={tournamentData.id} />
<label htmlFor="teamName">Team name</label>
<input
name="teamName"
@ -153,7 +154,7 @@ export default function RegisterPage() {
</Button>
)}
</div>
</MyForm>
</Form>
</div>
</div>
);