Files
buzz/app/(ui)/admin/tl/[ver]/actions.ts
T
dmgnr 8c14999c59
Build and Push Image / build-backend (push) Successful in 6m13s
Build and Push Image / build-frontend (push) Successful in 7m33s
Build and Push Image / push (push) Successful in 1m16s
feat(admin): tierlist editor
2026-08-06 03:00:13 +07:00

83 lines
2.3 KiB
TypeScript

"use server";
import { and, eq, isNull, or } from "drizzle-orm";
import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
import { actionLog } from "@/lib/api";
import { adminCheck } from "@/lib/auth";
import { db } from "@/lib/db";
import { tierlistBadges } from "@/lib/db/schema";
import { midpointOrder, normalizedOrders } from "../components/order";
function sameIds(left: string[], right: string[]) {
if (left.length !== right.length) return false;
const a = [...left].sort();
const b = [...right].sort();
return a.every((id, index) => id === b[index]);
}
export async function reorderBadges(args: {
typeId: string;
activeId: string;
ids: string[];
}) {
if (!(await adminCheck())) redirect("/login");
const { typeId, activeId, ids } = args;
await db.transaction(async (tx) => {
const badges = await tx
.select()
.from(tierlistBadges)
.where(or(isNull(tierlistBadges.type), eq(tierlistBadges.type, typeId)))
.orderBy(tierlistBadges.order, tierlistBadges.id);
const visibleIds = badges.map((badge) => badge.id);
if (!sameIds(visibleIds, ids)) {
throw new Error("Badge order is out of date. Refresh and try again.");
}
const index = ids.indexOf(activeId);
if (index === -1) throw new Error("Moved badge is missing.");
const prev =
index > 0
? badges.find((badge) => badge.id === ids[index - 1])
: undefined;
const next =
index < ids.length - 1
? badges.find((badge) => badge.id === ids[index + 1])
: undefined;
const nextOrder = midpointOrder(prev?.order, next?.order);
if (nextOrder == null) {
for (const item of normalizedOrders(ids)) {
await tx
.update(tierlistBadges)
.set({ order: item.order })
.where(eq(tierlistBadges.id, item.id));
}
} else {
await tx
.update(tierlistBadges)
.set({ order: nextOrder })
.where(
and(
eq(tierlistBadges.id, activeId),
or(isNull(tierlistBadges.type), eq(tierlistBadges.type, typeId)),
),
);
}
});
await actionLog(`Reordered tierlist badges for ${typeId}`, {
typeId,
activeId,
ids,
});
revalidatePath(`/admin/tl/${typeId}`);
revalidatePath(`/tl/${typeId}`);
}