Admin page: Refresh plus tiers

This commit is contained in:
Kalle 2023-01-29 12:04:55 +02:00
parent f15a5f539c
commit a507ea10ee
4 changed files with 70 additions and 18 deletions

View File

@ -0,0 +1,9 @@
insert into
"PlusTier" ("userId", "tier")
select
"userId",
"tier"
from
"FreshPlusTier"
where
"tier" is not null

View File

@ -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();
});

View File

@ -0,0 +1,2 @@
delete from
"PlusTier"

View File

@ -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() {
<Main className="stack lg">
<Impersonate />
<MigrateUser />
<RefreshPlusTiers />
{process.env.NODE_ENV !== "production" && <Seed />}
</Main>
);
@ -130,6 +146,7 @@ function MigrateUser() {
const [oldUserId, setOldUserId] = React.useState<number>();
const [newUserId, setNewUserId] = React.useState<number>();
const transition = useTransition();
const fetcher = useFetcher();
const submitButtonText =
transition.state === "submitting"
@ -139,7 +156,7 @@ function MigrateUser() {
: "Migrate";
return (
<Form className="stack md" method="post">
<fetcher.Form className="stack md" method="post">
<h2>Migrate user data</h2>
<div className="stack horizontal md">
<div>
@ -162,14 +179,16 @@ function MigrateUser() {
</div>
</div>
<div className="stack horizontal md">
<Button
<SubmitButton
type="submit"
disabled={!oldUserId || !newUserId || transition.state !== "idle"}
_action="MIGRATE"
state={fetcher.state}
>
{submitButtonText}
</Button>
</SubmitButton>
</div>
</Form>
</fetcher.Form>
);
}
@ -188,4 +207,17 @@ function Seed() {
);
}
function RefreshPlusTiers() {
const fetcher = useFetcher();
return (
<fetcher.Form method="post">
<h2>Refresh Plus Tiers</h2>
<SubmitButton type="submit" _action="REFRESH" state={fetcher.state}>
Refresh
</SubmitButton>
</fetcher.Form>
);
}
export const CatchBoundary = Catcher;