From bdba03a5d8d65d5c146ebab0e34ec931faabe1a2 Mon Sep 17 00:00:00 2001 From: Kalle <38327916+Sendouc@users.noreply.github.com> Date: Tue, 11 Oct 2022 20:14:32 +0300 Subject: [PATCH] Datalist on maplist page initial --- app/components/Input.tsx | 5 +- app/db/models/maps/codesByUserId.sql | 6 +++ app/db/models/maps/queries.server.ts | 8 ++++ app/routes/maps.tsx | 69 +++++++++++++++++++++------- app/styles/common.css | 4 ++ app/styles/maps.css | 3 ++ migrations/009-maps.js | 1 + 7 files changed, 78 insertions(+), 18 deletions(-) create mode 100644 app/db/models/maps/codesByUserId.sql diff --git a/app/components/Input.tsx b/app/components/Input.tsx index e364223b9..12f643dce 100644 --- a/app/components/Input.tsx +++ b/app/components/Input.tsx @@ -8,6 +8,7 @@ export function Input({ defaultValue, leftAddon, pattern, + list, "data-cy": dataCy, }: { name: string; @@ -17,6 +18,7 @@ export function Input({ defaultValue?: string; leftAddon?: string; pattern?: string; + list?: string; "data-cy"?: string; }) { return ( @@ -27,8 +29,9 @@ export function Input({ minLength={minLength} maxLength={maxLength} defaultValue={defaultValue} - data-cy={dataCy} pattern={pattern} + list={list} + data-cy={dataCy} /> ); diff --git a/app/db/models/maps/codesByUserId.sql b/app/db/models/maps/codesByUserId.sql new file mode 100644 index 000000000..1289d38a2 --- /dev/null +++ b/app/db/models/maps/codesByUserId.sql @@ -0,0 +1,6 @@ +select + "code" +from + "MapPool" +where + "ownerId" = @userId; diff --git a/app/db/models/maps/queries.server.ts b/app/db/models/maps/queries.server.ts index e1201ce75..60efcee6e 100644 --- a/app/db/models/maps/queries.server.ts +++ b/app/db/models/maps/queries.server.ts @@ -3,10 +3,12 @@ import type { MapPool, MapPoolMap, User } from "~/db/types"; import createMapPoolSql from "./createMapPool.sql"; import createMapPoolMapSql from "./createMapPoolMap.sql"; import findMapPoolByCodeSql from "./findMapPoolByCode.sql"; +import codesByUserIdSql from "./codesByUserId.sql"; const createMapPoolStm = sql.prepare(createMapPoolSql); const createMapPoolMapStm = sql.prepare(createMapPoolMapSql); const findMapPoolByCodeStm = sql.prepare(findMapPoolByCodeSql); +const codesByUserIdStm = sql.prepare(codesByUserIdSql); export const addMapPool = sql.transaction( ({ @@ -53,3 +55,9 @@ export function findMapPoolByCode(code: MapPool["code"]) { maps: Array>; }; } + +export function codesByUserId(userId: User["id"]) { + return (codesByUserIdStm.all({ userId }) as Array>).map( + ({ code }) => code + ); +} diff --git a/app/routes/maps.tsx b/app/routes/maps.tsx index bf7d51552..44d480607 100644 --- a/app/routes/maps.tsx +++ b/app/routes/maps.tsx @@ -18,12 +18,13 @@ import type { MapPool } from "~/modules/map-pool-serializer/types"; import styles from "~/styles/maps.css"; import { mapsPage, modeImageUrl, stageImageUrl } from "~/utils/urls"; import clsx from "clsx"; +import type { ShouldReloadFunction } from "@remix-run/react"; import { Form, useLoaderData, useSearchParams } from "@remix-run/react"; import { mapPoolToSerializedString, serializedStringToMapPool, } from "~/modules/map-pool-serializer"; -import { requireUser, useUser } from "~/modules/auth"; +import { getUser, requireUser, useUser } from "~/modules/auth"; import { ADMIN_DISCORD_ID, MAPS } from "~/constants"; import { Button } from "~/components/Button"; import { Input } from "~/components/Input"; @@ -45,6 +46,10 @@ import { UploadIcon } from "~/components/icons/Upload"; const AMOUNT_OF_MAPS_IN_MAP_LIST = stageIds.length * 2; +export const unstable_shouldReload: ShouldReloadFunction = ({ url }) => { + return Boolean(url.searchParams.get("code")); +}; + export const links: LinksFunction = () => { return [{ rel: "stylesheet", href: styles }]; }; @@ -53,6 +58,7 @@ export const handle = { i18n: "game-misc", }; +// xxx: check: limit how many map pools can be submitted maybe // xxx: next -> define user flow after submitting a map pool // xxx: code can't have spaces or special characters also convert upper case to lower case const mapsActionSchema = z.object({ @@ -81,13 +87,15 @@ export const action: ActionFunction = async ({ request }) => { return redirect(mapsPage(data.code)); }; -export const loader = ({ request }: LoaderArgs) => { +export const loader = async ({ request }: LoaderArgs) => { + const user = await getUser(request); const url = new URL(request.url); const code = url.searchParams.get("code"); - if (!code) return null; - - return db.maps.findMapPoolByCode(code) ?? null; + return { + mapPool: code ? db.maps.findMapPoolByCode(code) : null, + ownCodes: user ? db.maps.codesByUserId(user.id) : null, + }; }; const DEFAULT_MAP_POOL = { @@ -126,13 +134,23 @@ function useSearchParamMapPool() { const [searchParams, setSearchParams] = useSearchParams(); const mapPool = (() => { - if (data?.maps) { + if (data?.mapPool) { return { - TW: data.maps.filter((m) => m.mode === "TW").map((m) => m.stageId), - SZ: data.maps.filter((m) => m.mode === "SZ").map((m) => m.stageId), - TC: data.maps.filter((m) => m.mode === "TC").map((m) => m.stageId), - CB: data.maps.filter((m) => m.mode === "CB").map((m) => m.stageId), - RM: data.maps.filter((m) => m.mode === "RM").map((m) => m.stageId), + TW: data.mapPool.maps + .filter((m) => m.mode === "TW") + .map((m) => m.stageId), + SZ: data.mapPool.maps + .filter((m) => m.mode === "SZ") + .map((m) => m.stageId), + TC: data.mapPool.maps + .filter((m) => m.mode === "TC") + .map((m) => m.stageId), + CB: data.mapPool.maps + .filter((m) => m.mode === "CB") + .map((m) => m.stageId), + RM: data.mapPool.maps + .filter((m) => m.mode === "RM") + .map((m) => m.stageId), }; } @@ -181,10 +199,11 @@ function MapPoolSelector({ mapPool: MapPool; handleMapPoolChange: (args: { mode: ModeShort; stageId: StageId }) => void; }) { + const user = useUser(); const data = useLoaderData(); const { t } = useTranslation(["game-misc"]); - const editMode = !data; + const editMode = !data.mapPool || data.mapPool?.owner.id === user?.id; return (
@@ -240,10 +259,17 @@ function MapPoolSelector({ function MapPoolLoaderSaver({ mapPool }: { mapPool: MapPool }) { const data = useLoaderData(); - if (data) { + if (data.mapPool) { return (
- Code: {data.code} - Made by: {discordFullName(data.owner)} +
+ Code: {data.mapPool.code} - Made by:{" "} + {discordFullName(data.mapPool.owner)} +
+
+ + +
); } @@ -276,11 +302,19 @@ function MapPoolLoaderSaver({ mapPool }: { mapPool: MapPool }) { />
- + /> */} + + {data.ownCodes && ( + + {data.ownCodes.map((code) => ( + + )}