feat: comprehensive CMS improvements
CI / runtime-diagnostics (push) Skipped
CI / release (push) Skipped
CI / check (push) Failing after 0s
CI / deploy (push) Skipped

- Fix DOMPurify SSR crash (use isomorphic-dompurify)
- Fix SanitizedHtml to sanitize by default
- Add auth guards to studio/catalog maintenance pages
- Add update/edit to vouchers CRUD
- Add update/edit to rare-values CRUD
- Add approve workflow to applications page
- Add edit form to guilds detail page
- Add SEO metadata to all public pages (21 pages)
- Fix mobile nav accessibility (focus trap, aria attributes)
- Fix missing labels and table accessibility
- Add dynamic imports for heavy client components (6 components)
- Fix silent error swallowing (40+ locations)
- Add content scheduling for articles (publishAt, status)
- Wire up 12 missing webhook notification triggers
- Add global search to admin panel
- Add bulk actions to admin users table
- Fix JSON formatting and a11y issues
This commit is contained in:
openhands committed 2026-09-03 16:00:32 +02:00
1 parent b810b16672
commit 30c95b1a5c
78 files changed
+2252 -134

No files matched your search

+18 -1
View File
@@ -7,6 +7,7 @@ import { db, Items, Rooms } from "@/lib/db";
import { PERMS } from "@/lib/permissions";
import { rcon } from "@/lib/services/rcon";
import { logStaffActivity } from "@/lib/services/staff-activity";
import { notify } from "@/lib/services/webhook";
export async function updateRoomItem(payload: Record<string, unknown>) {
const staff = await requirePermission(PERMS.ROOMS_EDIT);
@@ -75,11 +76,17 @@ export async function roomRconAction({
roomId: number;
action: string;
}) {
await requirePermission(PERMS.ROOMS_EDIT);
const staff = await requirePermission(PERMS.ROOMS_EDIT);
if (action === "reload") {
await rcon.send("reloadroom", { room_id: roomId });
} else if (action === "kick") {
await rcon.send("kickall", { room_id: roomId });
notify({
action: "kick",
actor: staff.username,
target: String(roomId),
details: action,
});
} else if (action === "lock") {
await rcon.send("updateroom", { room_id: roomId, state: "locked" });
} else if (action === "unlock") {
@@ -89,6 +96,11 @@ export async function roomRconAction({
export async function deleteRoom({ id }: { id: number }) {
const staff = await requirePermission(PERMS.ROOMS_DELETE);
const [room] = await db
.select({ name: Rooms.name })
.from(Rooms)
.where(eq(Rooms.id, id))
.limit(1);
await db.delete(Rooms).where(eq(Rooms.id, id));
await logStaffActivity({
staffId: staff.id,
@@ -97,6 +109,11 @@ export async function deleteRoom({ id }: { id: number }) {
targetType: "room",
targetId: id,
});
notify({
action: "room_delete",
actor: staff.username,
target: room?.name ?? `#${id}`,
});
revalidatePath("/admin/rooms");
}