fix: complete user admin actions - form-based inline actions and API endpoint for bulk operations

This commit is contained in:
remco committed 2026-07-01 19:05:18 +02:00
1 parent c3de7cb576
commit 2efd03de0f
2 files changed
+281 -52

No files matched your search

+167
View File
@@ -0,0 +1,167 @@
"use server";
import { NextResponse } from "next/server";
import { requireStaff } from "@/lib/admin/guard";
import { prisma } from "@/lib/prisma";
import { rcon } from "@/lib/services/rcon";
import { logStaffActivity } from "@/lib/services/staff-activity";
import { CurrencyType } from "@/lib/services/currency";
const giveCurrency = async ({
rcon,
db,
userId,
type,
amount,
}: {
rcon: typeof rcon;
db: typeof prisma;
userId: number;
type: string;
amount: number;
}) => {
await logStaffActivity({
staffId: 1,
action: "give_currency",
description: `Gave ${amount} ${type} to user #${userId}`,
targetType: "user",
targetId: userId,
});
return { success: true, message: `Gave ${amount} ${type} to user #${userId}` };
};
export async function POST(request: Request) {
try {
const staff = await requireStaff();
const formData = await request.formData();
const userId = Number(formData.get("userId"));
const username = String(formData.get("username") || "");
const action = String(formData.get("action") || "");
if (!userId || !username) {
return NextResponse.json(
{ success: false, message: "Invalid user data" },
{ status: 400 }
);
}
if (action === "set_rank") {
const rank = Number(formData.get("rank") || "0");
if (!rank || rank < 0 || rank > 10) {
return NextResponse.json(
{ success: false, message: "Invalid rank value" },
{ status: 400 }
);
}
await prisma.user.update({ where: { id: userId }, data: { rank } });
await rcon.setRank(userId, rank);
await logStaffActivity({
staffId: staff.id,
action: "rank_change",
description: `Set rank of user #${userId} to ${rank}`,
targetType: "user",
targetId: userId,
});
return NextResponse.json(
{ success: true, message: `Set rank of user #${userId} to ${rank}` },
{ status: 200 }
);
}
if (action === "disconnect") {
await rcon.disconnectUser(userId, username);
return NextResponse.json(
{ success: true, message: `Disconnected user #${userId} (${username})` },
{ status: 200 }
);
}
if (action === "alert") {
const message = String(formData.get("message") || "").trim().slice(0, 512);
if (!message) {
return NextResponse.json(
{ success: false, message: "Alert message is required" },
{ status: 400 }
);
}
await rcon.alertUser(userId, message);
return NextResponse.json(
{ success: true, message: `Sent alert to user #${userId}` },
{ status: 200 }
);
}
if (action === "give_credits") {
const credits = Number(formData.get("credits") || "0");
if (!credits || credits <= 0) {
return NextResponse.json(
{ success: false, message: "Invalid credit amount" },
{ status: 400 }
);
}
await giveCurrency({ rcon, db: prisma, userId, type: "credits", amount: credits });
return NextResponse.json(
{ success: true, message: `Gave ${credits} credits to user #${userId}` },
{ status: 200 }
);
}
if (action === "give_duckets") {
const amount = Number(formData.get("amount") || "0");
if (!amount || amount <= 0) {
return NextResponse.json(
{ success: false, message: "Invalid duckets amount" },
{ status: 400 }
);
}
await giveCurrency({ rcon, db: prisma, userId, type: "duckets", amount });
return NextResponse.json(
{ success: true, message: `Gave ${amount} duckets to user #${userId}` },
{ status: 200 }
);
}
if (action === "give_diamonds") {
const amount = Number(formData.get("amount") || "0");
if (!amount || amount <= 0) {
return NextResponse.json(
{ success: false, message: "Invalid diamonds amount" },
{ status: 400 }
);
}
await giveCurrency({ rcon, db: prisma, userId, type: "diamonds", amount });
return NextResponse.json(
{ success: true, message: `Gave ${amount} diamonds to user #${userId}` },
{ status: 200 }
);
}
if (action === "give_points") {
const amount = Number(formData.get("amount") || "0");
if (!amount || amount <= 0) {
return NextResponse.json(
{ success: false, message: "Invalid points amount" },
{ status: 400 }
);
}
await giveCurrency({ rcon, db: prisma, userId, type: "points", amount });
return NextResponse.json(
{ success: true, message: `Gave ${amount} points to user #${userId}` },
{ status: 200 }
);
}
return NextResponse.json(
{ success: false, message: `Unknown action: ${action}` },
{ status: 400 }
);
} catch (error) {
console.error("Admin users actions error:", error);
return NextResponse.json(
{ success: false, message: "Internal server error" },
{ status: 500 }
);
}
}