add supply
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
"use server";
|
||||
|
||||
import { cookies } from "next/headers";
|
||||
import { redirect } from "next/navigation";
|
||||
import { ADMIN_SESSION_COOKIE } from "@/lib/auth/session";
|
||||
import { applyCoinsDeltaToRcBalance } from "@/lib/coins-rc";
|
||||
import {
|
||||
buildDashboardHref,
|
||||
type AdminDashboardTab,
|
||||
} from "@/lib/dashboard-search-url";
|
||||
import { createAdminSupabase } from "@/lib/supabase/admin";
|
||||
import { normalizeLedgerPageSize } from "@/lib/ledger-table-view";
|
||||
|
||||
const SYSTEM_ACCOUNT_ID = 1;
|
||||
|
||||
function parsePositiveCoins(raw: FormDataEntryValue | null): bigint | null {
|
||||
if (raw == null) return null;
|
||||
const s = String(raw).trim();
|
||||
if (!/^[1-9]\d*$/.test(s)) return null;
|
||||
try {
|
||||
return BigInt(s);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function addSystemSupply(formData: FormData) {
|
||||
const cookieStore = await cookies();
|
||||
if (cookieStore.get(ADMIN_SESSION_COOKIE)?.value !== "1") {
|
||||
redirect("/login");
|
||||
}
|
||||
|
||||
const tabRaw = String(formData.get("tab") ?? "");
|
||||
const tab: AdminDashboardTab =
|
||||
tabRaw === "matches"
|
||||
? "matches"
|
||||
: tabRaw === "players"
|
||||
? "players"
|
||||
: tabRaw === "matchmaker"
|
||||
? "matchmaker"
|
||||
: tabRaw === "ledger"
|
||||
? "ledger"
|
||||
: "dashboard";
|
||||
|
||||
const highlightRaw = String(formData.get("highlightId") ?? "").trim();
|
||||
const participantRaw = String(formData.get("participantRaw") ?? "").trim();
|
||||
const highlightId = highlightRaw === "" ? null : highlightRaw;
|
||||
const participant =
|
||||
participantRaw === "" ? null : participantRaw;
|
||||
|
||||
const ledgerFromRaw = String(formData.get("ledgerFrom") ?? "").trim();
|
||||
const ledgerToRaw = String(formData.get("ledgerTo") ?? "").trim();
|
||||
const ledgerPageRaw = String(formData.get("ledgerPage") ?? "").trim();
|
||||
const ledgerPageSizeRaw = String(
|
||||
formData.get("ledgerPageSize") ?? "",
|
||||
).trim();
|
||||
const ledgerSortRaw = String(formData.get("ledgerSort") ?? "").trim();
|
||||
const ledgerOrderRaw = String(formData.get("ledgerOrder") ?? "").trim();
|
||||
const ledgerPageNum =
|
||||
ledgerPageRaw === "" ? NaN : Number.parseInt(ledgerPageRaw, 10);
|
||||
|
||||
const base = {
|
||||
tab,
|
||||
highlightId,
|
||||
participantRaw: participant,
|
||||
...(tab === "ledger"
|
||||
? {
|
||||
ledgerFrom: ledgerFromRaw || null,
|
||||
ledgerTo: ledgerToRaw || null,
|
||||
ledgerPage:
|
||||
Number.isInteger(ledgerPageNum) && ledgerPageNum > 1
|
||||
? ledgerPageNum
|
||||
: null,
|
||||
ledgerSort: ledgerSortRaw || null,
|
||||
ledgerOrder:
|
||||
ledgerOrderRaw === "desc"
|
||||
? ("desc" as const)
|
||||
: ledgerOrderRaw === "asc"
|
||||
? ("asc" as const)
|
||||
: null,
|
||||
ledgerPageSize: normalizeLedgerPageSize(
|
||||
ledgerPageSizeRaw === "" ? null : ledgerPageSizeRaw,
|
||||
),
|
||||
}
|
||||
: {}),
|
||||
};
|
||||
|
||||
const parsedCoins = parsePositiveCoins(formData.get("supplyAmount"));
|
||||
if (parsedCoins == null) {
|
||||
redirect(
|
||||
buildDashboardHref({
|
||||
...base,
|
||||
supplyError: true,
|
||||
}),
|
||||
);
|
||||
}
|
||||
const coins = parsedCoins;
|
||||
|
||||
const supabase = createAdminSupabase();
|
||||
if (!supabase) {
|
||||
redirect(
|
||||
buildDashboardHref({
|
||||
...base,
|
||||
supplyError: true,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
const { data: sysRow, error: fetchErr } = await supabase
|
||||
.from("users")
|
||||
.select("id, rc")
|
||||
.eq("id", SYSTEM_ACCOUNT_ID)
|
||||
.maybeSingle();
|
||||
|
||||
if (fetchErr || !sysRow) {
|
||||
redirect(
|
||||
buildDashboardHref({
|
||||
...base,
|
||||
supplyError: true,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
const currentRc = sysRow.rc as number | null;
|
||||
|
||||
const { error: insertErr } = await supabase.from("transactions").insert({
|
||||
from: null,
|
||||
to: SYSTEM_ACCOUNT_ID,
|
||||
amount: coins.toString(),
|
||||
remarks: "supply",
|
||||
match_id: null,
|
||||
});
|
||||
|
||||
if (insertErr) {
|
||||
redirect(
|
||||
buildDashboardHref({
|
||||
...base,
|
||||
supplyError: true,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
const newRc = applyCoinsDeltaToRcBalance(currentRc, coins);
|
||||
|
||||
const { error: updateErr } = await supabase
|
||||
.from("users")
|
||||
.update({ rc: newRc })
|
||||
.eq("id", SYSTEM_ACCOUNT_ID);
|
||||
|
||||
if (updateErr) {
|
||||
redirect(
|
||||
buildDashboardHref({
|
||||
...base,
|
||||
supplyError: true,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
redirect(buildDashboardHref(base));
|
||||
}
|
||||
@@ -55,6 +55,7 @@ export default async function Home({
|
||||
participant?: string | string[];
|
||||
edit?: string | string[];
|
||||
saveError?: string | string[];
|
||||
supplyErr?: string | string[];
|
||||
mklog?: string | string[];
|
||||
lfrom?: string | string[];
|
||||
lto?: string | string[];
|
||||
@@ -80,6 +81,7 @@ export default async function Home({
|
||||
const participantRaw = firstSearchParam(sp.participant);
|
||||
const editRaw = firstSearchParam(sp.edit);
|
||||
const saveError = firstSearchParam(sp.saveError) === "1";
|
||||
const supplyError = firstSearchParam(sp.supplyErr) === "1";
|
||||
const editIdNum =
|
||||
editRaw != null && editRaw !== "" ? Number(editRaw) : NaN;
|
||||
|
||||
@@ -272,6 +274,7 @@ export default async function Home({
|
||||
ledgerOrder={ledgerSortOrderView}
|
||||
ledgerFrom={ledgerFrom}
|
||||
ledgerTo={ledgerTo}
|
||||
supplyError={supplyError}
|
||||
/>
|
||||
{editUser ? (
|
||||
<EditUserCcRcOverlay
|
||||
|
||||
Reference in New Issue
Block a user