Migrate tickets and CFH lists to DataTable; confirm destructive mod actions.
Co-authored-by: Cursor <[email protected]>
This commit is contained in:
1 parent
cbdea70f83
commit
06610e9ae3
7 files changed
+622
-414
No files matched your search
@@ -19,6 +19,7 @@ import {
|
||||
quickRoomKick,
|
||||
quickUnmute,
|
||||
} from "@/actions/moderation";
|
||||
import { useConfirmDialog } from "@/components/admin/confirm-dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Input } from "@/components/ui/input";
|
||||
@@ -27,24 +28,65 @@ import { useServerAction } from "@/hooks/use-server-action";
|
||||
|
||||
export function ModActionsClient() {
|
||||
const { run, isPending } = useServerAction();
|
||||
const { confirm, dialog: confirmDialog } = useConfirmDialog();
|
||||
|
||||
// User actions
|
||||
const [userId, setUserId] = useState("");
|
||||
const [muteDuration, setMuteDuration] = useState("10");
|
||||
const [alertMessage, setAlertMessage] = useState("");
|
||||
|
||||
// Room actions
|
||||
const [roomId, setRoomId] = useState("");
|
||||
|
||||
// Broadcast
|
||||
const [broadcastMsg, setBroadcastMsg] = useState("");
|
||||
|
||||
const uid = parseInt(userId, 10);
|
||||
const rid = parseInt(roomId, 10);
|
||||
|
||||
async function handleKick() {
|
||||
const ok = await confirm({
|
||||
title: "Kick user",
|
||||
description: `Disconnect user #${uid}?`,
|
||||
confirmLabel: "Kick",
|
||||
});
|
||||
if (!ok) return;
|
||||
run(() => quickKick({ userId: uid }), {
|
||||
successMessage: "User disconnected",
|
||||
});
|
||||
}
|
||||
|
||||
async function handleRoomKick() {
|
||||
const ok = await confirm({
|
||||
title: "Kick all from room",
|
||||
description: `Kick every user from room #${rid}?`,
|
||||
confirmLabel: "Kick all",
|
||||
});
|
||||
if (!ok) return;
|
||||
run(() => quickRoomKick({ roomId: rid }), {
|
||||
successMessage: "All users kicked from room",
|
||||
});
|
||||
}
|
||||
|
||||
async function handleHotelBroadcast() {
|
||||
const ok = await confirm({
|
||||
title: "Hotel-wide alert",
|
||||
description: "Send this alert to everyone in the hotel?",
|
||||
confirmLabel: "Send",
|
||||
variant: "default",
|
||||
});
|
||||
if (!ok) return;
|
||||
run(
|
||||
() =>
|
||||
broadcastAlert({
|
||||
message: broadcastMsg.trim(),
|
||||
type: "hotel",
|
||||
}),
|
||||
{
|
||||
successMessage: "Hotel alert sent!",
|
||||
onSuccess: () => setBroadcastMsg(""),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="grid gap-6 lg:grid-cols-2">
|
||||
{/* User Actions */}
|
||||
{confirmDialog}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-sm flex items-center gap-2">
|
||||
@@ -70,11 +112,7 @@ export function ModActionsClient() {
|
||||
variant="destructive"
|
||||
size="sm"
|
||||
disabled={isPending || !uid}
|
||||
onClick={() =>
|
||||
run(() => quickKick({ userId: uid }), {
|
||||
successMessage: "User disconnected",
|
||||
})
|
||||
}
|
||||
onClick={handleKick}
|
||||
>
|
||||
{isPending ? (
|
||||
<Loader2 className="mr-1 h-3 w-3 animate-spin" />
|
||||
@@ -159,7 +197,6 @@ export function ModActionsClient() {
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Room Actions */}
|
||||
<div className="space-y-6">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
@@ -185,18 +222,13 @@ export function ModActionsClient() {
|
||||
size="sm"
|
||||
className="w-full"
|
||||
disabled={isPending || !rid}
|
||||
onClick={() =>
|
||||
run(() => quickRoomKick({ roomId: rid }), {
|
||||
successMessage: "All users kicked from room",
|
||||
})
|
||||
}
|
||||
onClick={handleRoomKick}
|
||||
>
|
||||
<Zap className="mr-1 h-3 w-3" /> Kick All From Room
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Broadcast */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-sm flex items-center gap-2">
|
||||
@@ -216,19 +248,7 @@ export function ModActionsClient() {
|
||||
<Button
|
||||
size="sm"
|
||||
disabled={isPending || !broadcastMsg.trim()}
|
||||
onClick={() => {
|
||||
run(
|
||||
() =>
|
||||
broadcastAlert({
|
||||
message: broadcastMsg.trim(),
|
||||
type: "hotel",
|
||||
}),
|
||||
{
|
||||
successMessage: "Hotel alert sent!",
|
||||
onSuccess: () => setBroadcastMsg(""),
|
||||
},
|
||||
);
|
||||
}}
|
||||
onClick={handleHotelBroadcast}
|
||||
>
|
||||
<Megaphone className="mr-1 h-3 w-3" /> Hotel Alert
|
||||
</Button>
|
||||
|
||||
Reference in new issue
Block a user