diff --git a/app/features/user-page/routes/u.$identifier.art.tsx b/app/features/user-page/routes/u.$identifier.art.tsx index 899d29070..e4d171b44 100644 --- a/app/features/user-page/routes/u.$identifier.art.tsx +++ b/app/features/user-page/routes/u.$identifier.art.tsx @@ -1,6 +1,5 @@ import type { ActionFunction, LoaderFunctionArgs } from "@remix-run/node"; import type { UserPageLoaderData } from "./u.$identifier"; -import { userParamsSchema } from "./u.$identifier"; import { type SendouRouteHandle, notFoundIfFalsy, @@ -24,6 +23,7 @@ import { deleteArt } from "~/features/art/queries/deleteArt.server"; import { artsByUserId } from "~/features/art/queries/artsByUserId.server"; import { ART_SOURCES, type ArtSource } from "~/features/art/art-types"; import { ArtGrid } from "~/features/art/components/ArtGrid"; +import { userParamsSchema } from "../user-page-schemas.server"; export const handle: SendouRouteHandle = { i18n: ["art"], diff --git a/app/features/user-page/routes/u.$identifier.builds.tsx b/app/features/user-page/routes/u.$identifier.builds.tsx index 2e9697d41..29981b372 100644 --- a/app/features/user-page/routes/u.$identifier.builds.tsx +++ b/app/features/user-page/routes/u.$identifier.builds.tsx @@ -17,13 +17,14 @@ import { } from "~/utils/remix"; import { userNewBuildPage } from "~/utils/urls"; import { actualNumber, id } from "~/utils/zod"; -import { userParamsSchema, type UserPageLoaderData } from "./u.$identifier"; +import { type UserPageLoaderData } from "./u.$identifier"; import type { MainWeaponId } from "~/modules/in-game-lists"; import { mainWeaponIds } from "~/modules/in-game-lists"; import { WeaponImage } from "~/components/Image"; import { useSearchParamState } from "~/hooks/useSearchParamState"; import * as BuildRepository from "~/features/builds/BuildRepository.server"; import * as UserRepository from "~/features/user-page/UserRepository.server"; +import { userParamsSchema } from "../user-page-schemas.server"; const buildsActionSchema = z.object({ buildToDeleteId: z.preprocess(actualNumber, id), diff --git a/app/features/user-page/routes/u.$identifier.edit.tsx b/app/features/user-page/routes/u.$identifier.edit.tsx index 7dabb70c5..32654912b 100644 --- a/app/features/user-page/routes/u.$identifier.edit.tsx +++ b/app/features/user-page/routes/u.$identifier.edit.tsx @@ -48,7 +48,8 @@ import { undefinedToNull, weaponSplId, } from "~/utils/zod"; -import { userParamsSchema, type UserPageLoaderData } from "./u.$identifier"; +import { type UserPageLoaderData } from "./u.$identifier"; +import { userParamsSchema } from "../user-page-schemas.server"; import "~/styles/u-edit.css"; diff --git a/app/features/user-page/routes/u.$identifier.seasons.tsx b/app/features/user-page/routes/u.$identifier.seasons.tsx index 4043ea833..fe1c28340 100644 --- a/app/features/user-page/routes/u.$identifier.seasons.tsx +++ b/app/features/user-page/routes/u.$identifier.seasons.tsx @@ -8,7 +8,6 @@ import { import clsx from "clsx"; import * as React from "react"; import invariant from "tiny-invariant"; -import { z } from "zod"; import { Avatar } from "~/components/Avatar"; import Chart from "~/components/Chart"; import { @@ -57,23 +56,18 @@ import { databaseTimestampToDate } from "~/utils/dates"; import { cutToNDecimalPlaces, roundToNDecimalPlaces } from "~/utils/number"; import { type SendouRouteHandle, notFoundIfFalsy } from "~/utils/remix"; import { sendouQMatchPage, userSeasonsPage } from "~/utils/urls"; -import { userParamsSchema, type UserPageLoaderData } from "./u.$identifier"; +import { type UserPageLoaderData } from "./u.$identifier"; import * as UserRepository from "~/features/user-page/UserRepository.server"; import { ordinalToSp } from "~/features/mmr/mmr-utils"; +import { + seasonsSearchParamsSchema, + userParamsSchema, +} from "../user-page-schemas.server"; export const handle: SendouRouteHandle = { i18n: ["user"], }; -export const seasonsSearchParamsSchema = z.object({ - page: z.coerce.number().default(1), - info: z.enum(["weapons", "stages", "mates", "enemies"]).optional(), - season: z.coerce - .number() - .optional() - .refine((nth) => !nth || allSeasons(new Date()).includes(nth)), -}); - export const loader = async ({ params, request }: LoaderFunctionArgs) => { const { identifier } = userParamsSchema.parse(params); const parsedSearchParams = seasonsSearchParamsSchema.safeParse( diff --git a/app/features/user-page/routes/u.$identifier.tsx b/app/features/user-page/routes/u.$identifier.tsx index 1cca93718..dfbb12e8a 100644 --- a/app/features/user-page/routes/u.$identifier.tsx +++ b/app/features/user-page/routes/u.$identifier.tsx @@ -6,7 +6,6 @@ import type { import { Outlet, useLoaderData, useLocation } from "@remix-run/react"; import * as React from "react"; import invariant from "tiny-invariant"; -import { z } from "zod"; import { Main } from "~/components/Main"; import { SubNav, SubNavLink } from "~/components/SubNav"; import { userTopPlacements } from "~/features/top-search"; @@ -33,6 +32,7 @@ import * as UserRepository from "~/features/user-page/UserRepository.server"; import * as BuildRepository from "~/features/builds/BuildRepository.server"; import { countArtByUserId } from "~/features/art/queries/countArtByUserId.server"; import { findVods } from "~/features/vods/queries/findVods.server"; +import { userParamsSchema } from "../user-page-schemas.server"; import "~/styles/u.css"; @@ -64,8 +64,6 @@ export const handle: SendouRouteHandle = { }, }; -export const userParamsSchema = z.object({ identifier: z.string() }); - export type UserPageLoaderData = SerializeFrom; export const loader = async ({ params, request }: LoaderFunctionArgs) => { diff --git a/app/features/user-page/user-page-schemas.server.ts b/app/features/user-page/user-page-schemas.server.ts new file mode 100644 index 000000000..9438e74c2 --- /dev/null +++ b/app/features/user-page/user-page-schemas.server.ts @@ -0,0 +1,13 @@ +import { z } from "zod"; +import { allSeasons } from "../mmr/season"; + +export const userParamsSchema = z.object({ identifier: z.string() }); + +export const seasonsSearchParamsSchema = z.object({ + page: z.coerce.number().default(1), + info: z.enum(["weapons", "stages", "mates", "enemies"]).optional(), + season: z.coerce + .number() + .optional() + .refine((nth) => !nth || allSeasons(new Date()).includes(nth)), +});