Delete tournament feature

This commit is contained in:
Kalle
2023-05-16 22:05:52 +03:00
parent 94574c2458
commit d5b74e928a
6 changed files with 61 additions and 10 deletions

View File

@@ -1,4 +1,4 @@
import { Form } from "@remix-run/react";
import { Form, useFetcher } from "@remix-run/react";
import React from "react";
import invariant from "tiny-invariant";
import { useTranslation } from "~/hooks/useTranslation";
@@ -11,12 +11,15 @@ export function FormWithConfirm({
children,
dialogHeading,
deleteButtonText,
action,
}: {
fields?: [name: string, value: string | number][];
children: React.ReactNode;
dialogHeading: string;
deleteButtonText?: string;
action?: string;
}) {
const fetcher = useFetcher();
const { t } = useTranslation(["common"]);
const [dialogOpen, setDialogOpen] = React.useState(false);
const formRef = React.useRef<HTMLFormElement>(null);
@@ -29,11 +32,17 @@ export function FormWithConfirm({
return (
<>
<Form id={id} className="hidden" ref={formRef} method="post">
<fetcher.Form
id={id}
className="hidden"
ref={formRef}
method="post"
action={action}
>
{fields?.map(([name, value]) => (
<input type="hidden" key={name} name={name} value={value} />
))}
</Form>
</fetcher.Form>
<Dialog isOpen={dialogOpen} close={closeDialog} className="text-center">
<div className="stack md">
<h2 className="text-sm">{dialogHeading}</h2>

View File

@@ -0,0 +1,4 @@
delete from
"Tournament"
where
id = @id

View File

@@ -41,6 +41,7 @@ import findAllEventsWithMapPoolsSql from "./findAllEventsWithMapPools.sql";
import findTieBreakerMapPoolByEventIdSql from "./findTieBreakerMapPoolByEventId.sql";
import deleteByIdSql from "./deleteById.sql";
import createTournamentSql from "./createTournament.sql";
import deleteTournamentByIdSql from "./deleteTournamentById.sql";
const createStm = sql.prepare(createSql);
const updateStm = sql.prepare(updateSql);
@@ -58,6 +59,7 @@ const findTieBreakerMapPoolByEventIdtm = sql.prepare(
findTieBreakerMapPoolByEventIdSql
);
const deleteByIdStm = sql.prepare(deleteByIdSql);
const deleteTournamentByIdStm = sql.prepare(deleteTournamentByIdSql);
const createTournamentStm = sql.prepare(createTournamentSql);
const createTournament = (
@@ -512,6 +514,15 @@ export function findTieBreakerMapPoolByEventId(
>;
}
export function deleteById(id: CalendarEvent["id"]) {
return deleteByIdStm.run({ id });
}
export const deleteById = sql.transaction(
({
eventId,
tournamentId,
}: {
eventId: number;
tournamentId: number | null;
}) => {
deleteByIdStm.run({ id: eventId });
if (tournamentId) deleteTournamentByIdStm.run({ id: tournamentId });
}
);

View File

@@ -30,8 +30,13 @@ import { joinTeam, leaveTeam } from "../queries/joinLeaveTeam.server";
import { TOURNAMENT } from "../tournament-constants";
import { deleteTeam } from "../queries/deleteTeam.server";
import { useUser } from "~/modules/auth";
import { calendarEditPage, tournamentPage } from "~/utils/urls";
import {
calendarEditPage,
calendarEventPage,
tournamentPage,
} from "~/utils/urls";
import { Redirect } from "~/components/Redirect";
import { FormWithConfirm } from "~/components/FormWithConfirm";
export const action: ActionFunction = async ({ request, params }) => {
const user = await requireUserId(request);
@@ -138,7 +143,9 @@ export const action: ActionFunction = async ({ request, params }) => {
return null;
};
// xxx: seed order for challonge download
export default function TournamentAdminPage() {
const { t } = useTranslation(["calendar"]);
const data = useOutletContext<TournamentLoaderData>();
const user = useUser();
@@ -151,7 +158,7 @@ export default function TournamentAdminPage() {
<AdminActions />
{isAdmin(user) ? <EnableMapList /> : null}
<DownloadParticipants />
<div className="stack items-start mt-4">
<div className="stack horizontal items-end mt-4">
<LinkButton
to={calendarEditPage(data.event.eventId)}
size="tiny"
@@ -159,6 +166,23 @@ export default function TournamentAdminPage() {
>
Edit event info
</LinkButton>
{!data.hasStarted ? (
<FormWithConfirm
dialogHeading={t("calendar:actions.delete.confirm", {
name: data.event.name,
})}
action={calendarEventPage(data.event.eventId)}
>
<Button
className="ml-auto"
size="tiny"
variant="minimal-destructive"
type="submit"
>
{t("calendar:actions.delete")}
</Button>
</FormWithConfirm>
) : null}
</div>
</div>
);

View File

@@ -58,7 +58,7 @@ export const links: LinksFunction = () => {
};
export const handle: SendouRouteHandle = {
i18n: ["tournament"],
i18n: ["tournament", "calendar"],
};
export type TournamentLoaderTeam = Unpacked<TournamentLoaderData["teams"]>;

View File

@@ -69,7 +69,10 @@ export const action: ActionFunction = async ({ params, request }) => {
})
);
db.calendarEvents.deleteById(event.eventId);
db.calendarEvents.deleteById({
eventId: event.eventId,
tournamentId: event.tournamentId,
});
return redirect(CALENDAR_PAGE);
};