mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-09 04:36:02 -05:00
Calendar.new loader to different file
This commit is contained in:
87
app/features/calendar/loaders/calendar.new.server.ts
Normal file
87
app/features/calendar/loaders/calendar.new.server.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import type { LoaderFunctionArgs } from "@remix-run/node";
|
||||
import { json, redirect } from "@remix-run/node";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import * as BadgeRepository from "~/features/badges/BadgeRepository.server";
|
||||
import * as CalendarRepository from "~/features/calendar/CalendarRepository.server";
|
||||
import { tournamentFromDB } from "~/features/tournament-bracket/core/Tournament.server";
|
||||
import { i18next } from "~/modules/i18n/i18next.server";
|
||||
import { canEditCalendarEvent } from "~/permissions";
|
||||
import { validate } from "~/utils/remix";
|
||||
import { makeTitle } from "~/utils/strings";
|
||||
import { tournamentBracketsPage } from "~/utils/urls";
|
||||
import { canAddNewEvent } from "../calendar-utils";
|
||||
import { canCreateTournament } from "../calendar-utils.server";
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const t = await i18next.getFixedT(request);
|
||||
const user = await requireUser(request);
|
||||
const url = new URL(request.url);
|
||||
|
||||
validate(canAddNewEvent(user), "Not authorized", 401);
|
||||
|
||||
const eventWithTournament = async (key: string) => {
|
||||
const eventId = Number(url.searchParams.get(key));
|
||||
const event = Number.isNaN(eventId)
|
||||
? undefined
|
||||
: await CalendarRepository.findById({
|
||||
id: eventId,
|
||||
includeMapPool: true,
|
||||
includeTieBreakerMapPool: true,
|
||||
includeBadgePrizes: true,
|
||||
});
|
||||
|
||||
if (!event) return;
|
||||
|
||||
// special tags that are added automatically
|
||||
const tags = event?.tags?.filter(
|
||||
(tag) => tag !== "BADGE" && tag !== "FULL_TOURNAMENT",
|
||||
);
|
||||
|
||||
if (!event?.tournamentId) return { ...event, tags, tournamentCtx: null };
|
||||
|
||||
return {
|
||||
...event,
|
||||
tags,
|
||||
tournamentCtx: (
|
||||
await tournamentFromDB({
|
||||
tournamentId: event.tournamentId,
|
||||
user,
|
||||
})
|
||||
).ctx,
|
||||
};
|
||||
};
|
||||
|
||||
const eventToEdit = await eventWithTournament("eventId");
|
||||
const canEditEvent =
|
||||
eventToEdit && canEditCalendarEvent({ user, event: eventToEdit });
|
||||
|
||||
// no editing tournament after the start
|
||||
if (
|
||||
eventToEdit &&
|
||||
eventToEdit.tournamentCtx?.inProgressBrackets &&
|
||||
eventToEdit.tournamentCtx.inProgressBrackets.length > 0
|
||||
) {
|
||||
return redirect(
|
||||
tournamentBracketsPage({ tournamentId: eventToEdit.tournamentCtx.id }),
|
||||
);
|
||||
}
|
||||
|
||||
const userCanCreateTournament = canCreateTournament(user);
|
||||
|
||||
return json({
|
||||
managedBadges: await BadgeRepository.findManagedByUserId(user.id),
|
||||
recentEventsWithMapPools:
|
||||
await CalendarRepository.findRecentMapPoolsByAuthorId(user.id),
|
||||
eventToEdit: canEditEvent ? eventToEdit : undefined,
|
||||
eventToCopy:
|
||||
userCanCreateTournament && !eventToEdit
|
||||
? await eventWithTournament("copyEventId")
|
||||
: undefined,
|
||||
recentTournaments:
|
||||
userCanCreateTournament && !eventToEdit
|
||||
? await CalendarRepository.findRecentTournamentsByAuthorId(user.id)
|
||||
: undefined,
|
||||
title: makeTitle([canEditEvent ? "Edit" : "New", t("pages.calendar")]),
|
||||
canCreateTournament: userCanCreateTournament,
|
||||
});
|
||||
};
|
||||
@@ -1,9 +1,4 @@
|
||||
import type {
|
||||
LoaderFunctionArgs,
|
||||
MetaFunction,
|
||||
SerializeFrom,
|
||||
} from "@remix-run/node";
|
||||
import { json, redirect } from "@remix-run/node";
|
||||
import type { MetaFunction, SerializeFrom } from "@remix-run/node";
|
||||
import { Form, useLoaderData } from "@remix-run/react";
|
||||
import clsx from "clsx";
|
||||
import * as React from "react";
|
||||
@@ -28,28 +23,21 @@ import { TrashIcon } from "~/components/icons/Trash";
|
||||
import { CALENDAR_EVENT } from "~/constants";
|
||||
import type { Tables } from "~/db/tables";
|
||||
import type { Badge as BadgeType, CalendarEventTag } from "~/db/types";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import * as BadgeRepository from "~/features/badges/BadgeRepository.server";
|
||||
import * as CalendarRepository from "~/features/calendar/CalendarRepository.server";
|
||||
import { MapPool } from "~/features/map-list-generator/core/map-pool";
|
||||
import { tournamentFromDB } from "~/features/tournament-bracket/core/Tournament.server";
|
||||
import {
|
||||
BRACKET_NAMES,
|
||||
type TournamentFormatShort,
|
||||
} from "~/features/tournament/tournament-constants";
|
||||
import { useIsMounted } from "~/hooks/useIsMounted";
|
||||
import { i18next } from "~/modules/i18n/i18next.server";
|
||||
import type { RankedModeShort } from "~/modules/in-game-lists";
|
||||
import { canEditCalendarEvent } from "~/permissions";
|
||||
import { isDefined, nullFilledArray } from "~/utils/arrays";
|
||||
import {
|
||||
databaseTimestampToDate,
|
||||
getDateAtNextFullHour,
|
||||
getDateWithHoursOffset,
|
||||
} from "~/utils/dates";
|
||||
import { validate, type SendouRouteHandle } from "~/utils/remix";
|
||||
import { makeTitle, pathnameFromPotentialURL } from "~/utils/strings";
|
||||
import { tournamentBracketsPage } from "~/utils/urls";
|
||||
import { type SendouRouteHandle } from "~/utils/remix";
|
||||
import { pathnameFromPotentialURL } from "~/utils/strings";
|
||||
import {
|
||||
REG_CLOSES_AT_OPTIONS,
|
||||
type RegClosesAtOption,
|
||||
@@ -59,19 +47,18 @@ import {
|
||||
bracketProgressionToShortTournamentFormat,
|
||||
calendarEventMaxDate,
|
||||
calendarEventMinDate,
|
||||
canAddNewEvent,
|
||||
datesToRegClosesAt,
|
||||
regClosesAtToDisplayName,
|
||||
validateFollowUpBrackets,
|
||||
} from "../calendar-utils";
|
||||
import { canCreateTournament } from "../calendar-utils.server";
|
||||
import { Tags } from "../components/Tags";
|
||||
|
||||
import "~/styles/calendar-new.css";
|
||||
import "~/styles/maps.css";
|
||||
|
||||
import { loader } from "../loaders/calendar.new.server";
|
||||
import { action } from "../actions/calendar.new.server";
|
||||
export { action };
|
||||
export { loader, action };
|
||||
|
||||
export const meta: MetaFunction = (args) => {
|
||||
const data = args.data as SerializeFrom<typeof loader> | null;
|
||||
@@ -85,80 +72,6 @@ export const handle: SendouRouteHandle = {
|
||||
i18n: ["calendar", "game-misc"],
|
||||
};
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const t = await i18next.getFixedT(request);
|
||||
const user = await requireUser(request);
|
||||
const url = new URL(request.url);
|
||||
|
||||
validate(canAddNewEvent(user), "Not authorized", 401);
|
||||
|
||||
const eventWithTournament = async (key: string) => {
|
||||
const eventId = Number(url.searchParams.get(key));
|
||||
const event = Number.isNaN(eventId)
|
||||
? undefined
|
||||
: await CalendarRepository.findById({
|
||||
id: eventId,
|
||||
includeMapPool: true,
|
||||
includeTieBreakerMapPool: true,
|
||||
includeBadgePrizes: true,
|
||||
});
|
||||
|
||||
if (!event) return;
|
||||
|
||||
// special tags that are added automatically
|
||||
const tags = event?.tags?.filter(
|
||||
(tag) => tag !== "BADGE" && tag !== "FULL_TOURNAMENT",
|
||||
);
|
||||
|
||||
if (!event?.tournamentId) return { ...event, tags, tournamentCtx: null };
|
||||
|
||||
return {
|
||||
...event,
|
||||
tags,
|
||||
tournamentCtx: (
|
||||
await tournamentFromDB({
|
||||
tournamentId: event.tournamentId,
|
||||
user,
|
||||
})
|
||||
).ctx,
|
||||
};
|
||||
};
|
||||
|
||||
const eventToEdit = await eventWithTournament("eventId");
|
||||
const canEditEvent =
|
||||
eventToEdit && canEditCalendarEvent({ user, event: eventToEdit });
|
||||
|
||||
// no editing tournament after the start
|
||||
if (
|
||||
eventToEdit &&
|
||||
eventToEdit.tournamentCtx?.inProgressBrackets &&
|
||||
eventToEdit.tournamentCtx.inProgressBrackets.length > 0
|
||||
) {
|
||||
return redirect(
|
||||
tournamentBracketsPage({ tournamentId: eventToEdit.tournamentCtx.id }),
|
||||
);
|
||||
}
|
||||
|
||||
const userCanCreateTournament = canCreateTournament(user);
|
||||
|
||||
return json({
|
||||
managedBadges: await BadgeRepository.findManagedByUserId(user.id),
|
||||
recentEventsWithMapPools:
|
||||
await CalendarRepository.findRecentMapPoolsByAuthorId(user.id),
|
||||
eventToEdit: canEditEvent ? eventToEdit : undefined,
|
||||
eventToCopy:
|
||||
userCanCreateTournament && !eventToEdit
|
||||
? await eventWithTournament("copyEventId")
|
||||
: undefined,
|
||||
recentTournaments:
|
||||
userCanCreateTournament && !eventToEdit
|
||||
? await CalendarRepository.findRecentTournamentsByAuthorId(user.id)
|
||||
: undefined,
|
||||
title: makeTitle([canEditEvent ? "Edit" : "New", t("pages.calendar")]),
|
||||
canCreateTournament: userCanCreateTournament,
|
||||
});
|
||||
};
|
||||
|
||||
const useBaseEvent = () => {
|
||||
const { eventToEdit, eventToCopy } = useLoaderData<typeof loader>();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user