83 lines
2.3 KiB
TypeScript
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}`);
|
|
}
|