Add MyForm element

This commit is contained in:
Kalle (Sendou) 2021-12-05 13:29:39 +02:00
parent 236ed75391
commit 2b689abb3e
4 changed files with 73 additions and 54 deletions

27
app/components/MyForm.tsx Normal file
View File

@ -0,0 +1,27 @@
import { Form, FormProps, useTransition } from "remix";
interface MyFormProps extends FormProps {
hiddenFields?: Record<string, string>;
}
/**
* Wrapper around Remix's Form that has default method of "post",
* creates <input type="hidden"> elements for each key/value pair in hiddenFields
* and disables the form when it's submitting.
*/
export function MyForm(props: MyFormProps) {
const { hiddenFields, children, ...rest } = props;
const transition = useTransition();
return (
<Form 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>
</Form>
);
}

View File

@ -1,22 +1,22 @@
import type { ActionFunction, LinksFunction, LoaderFunction } from "remix";
import {
json,
useLoaderData,
redirect,
Form,
useNavigate,
useLoaderData,
useMatches,
useNavigate,
useTransition,
} from "remix";
import type { LoaderFunction, LinksFunction, ActionFunction } from "remix";
import invariant from "tiny-invariant";
import { Button } from "~/components/Button";
import { MyForm } from "~/components/MyForm";
import {
FindTournamentByNameForUrlI,
findTournamentWithInviteCodes,
joinTeam,
} from "~/services/tournament";
import styles from "~/styles/tournament-join-team.css";
import invariant from "tiny-invariant";
import { getUser, requireUser } from "~/utils";
import { Button } from "~/components/Button";
export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: styles }];
@ -165,13 +165,12 @@ function Contents({ data }: { data: ResponseObject }) {
<div>
{data.inviterName} invited you to join {data.teamName} for this
tournament. Accept invite?
<Form method="post">
<input
type="hidden"
name="tournamentId"
value={parentRouteData.id}
/>
<input type="hidden" name="inviteCode" value={data.inviteCode} />
<MyForm
hiddenFields={{
tournamentId: parentRouteData.id,
inviteCode: data.inviteCode,
}}
>
<div className="tournament__join-team__buttons">
<Button
type="submit"
@ -190,7 +189,7 @@ function Contents({ data }: { data: ResponseObject }) {
</Button>
)}
</div>
</Form>
</MyForm>
</div>
);
default:

View File

@ -1,7 +1,6 @@
import { Prisma } from ".prisma/client";
import {
ActionFunction,
Form,
LinksFunction,
redirect,
useActionData,
@ -13,6 +12,7 @@ import {
import invariant from "tiny-invariant";
import { Button } from "~/components/Button";
import ErrorMessage from "~/components/ErrorMessage";
import { MyForm } from "~/components/MyForm";
import {
createTournamentTeam,
FindTournamentByNameForUrlI,
@ -119,47 +119,40 @@ export default function RegisterPage() {
<div className="tournament__register__container">
<h2 className="tournament__register__header">Register now</h2>
<div className="tournament__register__content">
<Form method="post">
<fieldset disabled={transition.state !== "idle"}>
<label htmlFor="teamName">Team name</label>
<input
type="hidden"
name="tournamentId"
value={tournamentData.id}
/>
<input
name="teamName"
id="teamName"
defaultValue={actionData?.fields?.teamName}
required
minLength={TEAM_NAME_MIN_LENGTH}
maxLength={TEAM_NAME_MAX_LENGTH}
data-cy="team-name-input"
/>
<ErrorMessage errorMsg={actionData?.fieldErrors?.teamName} />
<div className="tournament__register__buttons-container">
<MyForm hiddenFields={{ tournamentId: tournamentData.id }}>
<label htmlFor="teamName">Team name</label>
<input
name="teamName"
id="teamName"
defaultValue={actionData?.fields?.teamName}
required
minLength={TEAM_NAME_MIN_LENGTH}
maxLength={TEAM_NAME_MAX_LENGTH}
data-cy="team-name-input"
/>
<ErrorMessage errorMsg={actionData?.fieldErrors?.teamName} />
<div className="tournament__register__buttons-container">
<Button
type="submit"
data-cy="register-submit-button"
loading={transition.state !== "idle"}
loadingText="Submitting..."
>
Submit
</Button>
{transition.state === "idle" && (
<Button
type="submit"
data-cy="register-submit-button"
loading={transition.state !== "idle"}
loadingText="Submitting..."
variant="outlined"
type="button"
onClick={() =>
navigate(location.pathname.replace("/register", ""))
}
>
Submit
Cancel
</Button>
{transition.state === "idle" && (
<Button
variant="outlined"
type="button"
onClick={() =>
navigate(location.pathname.replace("/register", ""))
}
>
Cancel
</Button>
)}
</div>
</fieldset>
</Form>
)}
</div>
</MyForm>
</div>
</div>
);

View File

@ -155,7 +155,7 @@ label {
}
fieldset {
all: unset;
all: inherit;
}
select {