mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-07-24 20:22:15 -05:00
Add MyForm element
This commit is contained in:
parent
236ed75391
commit
2b689abb3e
27
app/components/MyForm.tsx
Normal file
27
app/components/MyForm.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ label {
|
|||
}
|
||||
|
||||
fieldset {
|
||||
all: unset;
|
||||
all: inherit;
|
||||
}
|
||||
|
||||
select {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user