diff --git a/app/db/models/users/fillPlusTiers.sql b/app/db/models/users/fillPlusTiers.sql new file mode 100644 index 000000000..06d31a0b7 --- /dev/null +++ b/app/db/models/users/fillPlusTiers.sql @@ -0,0 +1,9 @@ +insert into + "PlusTier" ("userId", "tier") +select + "userId", + "tier" +from + "FreshPlusTier" +where + "tier" is not null diff --git a/app/db/models/users/queries.server.ts b/app/db/models/users/queries.server.ts index 8bb1061db..350fb320b 100644 --- a/app/db/models/users/queries.server.ts +++ b/app/db/models/users/queries.server.ts @@ -22,6 +22,8 @@ import updateProfileSql from "./updateProfile.sql"; import upsertSql from "./upsert.sql"; import addUserWeaponSql from "./addUserWeapon.sql"; import deleteUserWeaponsSql from "./deleteUserWeapons.sql"; +import wipePlusTiersSql from "./wipePlusTiers.sql"; +import fillPlusTiersSql from "./fillPlusTiers.sql"; import { parseDBArray } from "~/utils/sql"; const upsertStm = sql.prepare(upsertSql); @@ -214,3 +216,10 @@ export function search(input: string) { > >; } + +const wipePlusTiersStm = sql.prepare(wipePlusTiersSql); +const fillPlusTiersStm = sql.prepare(fillPlusTiersSql); +export const refreshPlusTiers = sql.transaction(() => { + wipePlusTiersStm.run(); + fillPlusTiersStm.run(); +}); diff --git a/app/db/models/users/wipePlusTiers.sql b/app/db/models/users/wipePlusTiers.sql new file mode 100644 index 000000000..c390c0c88 --- /dev/null +++ b/app/db/models/users/wipePlusTiers.sql @@ -0,0 +1,2 @@ +delete from + "PlusTier" diff --git a/app/routes/admin.tsx b/app/routes/admin.tsx index 0357438d2..340cccb88 100644 --- a/app/routes/admin.tsx +++ b/app/routes/admin.tsx @@ -4,18 +4,14 @@ import type { MetaFunction, } from "@remix-run/node"; import { json, redirect } from "@remix-run/node"; -import { - Form, - useFetcher, - useLoaderData, - useTransition, -} from "@remix-run/react"; +import { useFetcher, useLoaderData, useTransition } from "@remix-run/react"; import * as React from "react"; import { z } from "zod"; import { Button } from "~/components/Button"; import { Catcher } from "~/components/Catcher"; import { UserCombobox } from "~/components/Combobox"; import { Main } from "~/components/Main"; +import { SubmitButton } from "~/components/SubmitButton"; import { db } from "~/db"; import { getUserId, @@ -29,6 +25,7 @@ import { type SendouRouteHandle, } from "~/utils/remix"; import { makeTitle } from "~/utils/strings"; +import { assertUnreachable } from "~/utils/types"; import { impersonateUrl, SEED_URL, STOP_IMPERSONATING_URL } from "~/utils/urls"; import { actualNumber } from "~/utils/zod"; @@ -38,10 +35,16 @@ export const meta: MetaFunction = () => { }; }; -const adminActionSchema = z.object({ - "old-user[value]": z.preprocess(actualNumber, z.number().positive()), - "new-user[value]": z.preprocess(actualNumber, z.number().positive()), -}); +const adminActionSchema = z.union([ + z.object({ + _action: z.literal("MIGRATE"), + "old-user[value]": z.preprocess(actualNumber, z.number().positive()), + "new-user[value]": z.preprocess(actualNumber, z.number().positive()), + }), + z.object({ + _action: z.literal("REFRESH"), + }), +]); export const action: ActionFunction = async ({ request }) => { const data = await parseRequestFormData({ @@ -52,10 +55,22 @@ export const action: ActionFunction = async ({ request }) => { validate(canPerformAdminActions(user)); - db.users.migrate({ - oldUserId: data["old-user[value]"], - newUserId: data["new-user[value]"], - }); + switch (data._action) { + case "MIGRATE": { + db.users.migrate({ + oldUserId: data["old-user[value]"], + newUserId: data["new-user[value]"], + }); + break; + } + case "REFRESH": { + db.users.refreshPlusTiers(); + break; + } + default: { + assertUnreachable(data); + } + } return null; }; @@ -85,6 +100,7 @@ export default function AdminPage() {
+ {process.env.NODE_ENV !== "production" && }
); @@ -130,6 +146,7 @@ function MigrateUser() { const [oldUserId, setOldUserId] = React.useState(); const [newUserId, setNewUserId] = React.useState(); const transition = useTransition(); + const fetcher = useFetcher(); const submitButtonText = transition.state === "submitting" @@ -139,7 +156,7 @@ function MigrateUser() { : "Migrate"; return ( -
+

Migrate user data

@@ -162,14 +179,16 @@ function MigrateUser() {
- +
- +
); } @@ -188,4 +207,17 @@ function Seed() { ); } +function RefreshPlusTiers() { + const fetcher = useFetcher(); + + return ( + +

Refresh Plus Tiers

+ + Refresh + +
+ ); +} + export const CatchBoundary = Catcher;