139 lines
4.6 KiB
TypeScript
139 lines
4.6 KiB
TypeScript
import { useState } from "react";
|
|
|
|
interface MemberContextMenuProps {
|
|
memberId: string;
|
|
username: string;
|
|
canKick: boolean;
|
|
canBan: boolean;
|
|
canMute: boolean;
|
|
onMessage?: () => void;
|
|
onKick?: (reason: string) => void;
|
|
onBan?: (reason: string) => void;
|
|
onMute?: (duration: string, reason: string) => void;
|
|
onClose: () => void;
|
|
}
|
|
|
|
export function MemberContextMenu({
|
|
username,
|
|
canKick,
|
|
canBan,
|
|
canMute,
|
|
onMessage,
|
|
onKick,
|
|
onBan,
|
|
onMute,
|
|
onClose,
|
|
}: MemberContextMenuProps) {
|
|
const [mode, setMode] = useState<"menu" | "kick" | "ban" | "mute">("menu");
|
|
const [reason, setReason] = useState("");
|
|
const [duration, setDuration] = useState("1h");
|
|
|
|
if (mode === "kick") {
|
|
return (
|
|
<div className="absolute z-50 bg-gb-bg border border-gb-bg-t p-3 font-mono text-xs shadow-lg min-w-[200px]">
|
|
<div className="text-gb-orange mb-2">KICK {username.toUpperCase()}</div>
|
|
<input
|
|
type="text"
|
|
value={reason}
|
|
onChange={(e) => setReason(e.target.value)}
|
|
placeholder="reason (optional)"
|
|
className="terminal-input w-full mb-2"
|
|
/>
|
|
<div className="flex gap-2">
|
|
<button onClick={() => onKick?.(reason)} className="flex-1 bg-gb-red text-gb-bg py-1 hover:bg-gb-orange">
|
|
[KICK]
|
|
</button>
|
|
<button onClick={() => setMode("menu")} className="flex-1 bg-gb-bg-t text-gb-fg py-1 hover:bg-gb-bg-s">
|
|
[BACK]
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (mode === "ban") {
|
|
return (
|
|
<div className="absolute z-50 bg-gb-bg border border-gb-bg-t p-3 font-mono text-xs shadow-lg min-w-[200px]">
|
|
<div className="text-gb-orange mb-2">BAN {username.toUpperCase()}</div>
|
|
<input
|
|
type="text"
|
|
value={reason}
|
|
onChange={(e) => setReason(e.target.value)}
|
|
placeholder="reason (optional)"
|
|
className="terminal-input w-full mb-2"
|
|
/>
|
|
<div className="flex gap-2">
|
|
<button onClick={() => onBan?.(reason)} className="flex-1 bg-gb-red text-gb-bg py-1 hover:bg-gb-orange">
|
|
[BAN]
|
|
</button>
|
|
<button onClick={() => setMode("menu")} className="flex-1 bg-gb-bg-t text-gb-fg py-1 hover:bg-gb-bg-s">
|
|
[BACK]
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (mode === "mute") {
|
|
return (
|
|
<div className="absolute z-50 bg-gb-bg border border-gb-bg-t p-3 font-mono text-xs shadow-lg min-w-[200px]">
|
|
<div className="text-gb-orange mb-2">MUTE {username.toUpperCase()}</div>
|
|
<select
|
|
value={duration}
|
|
onChange={(e) => setDuration(e.target.value)}
|
|
className="w-full mb-2 bg-gb-bg-s text-gb-fg text-xs border-none outline-none"
|
|
>
|
|
<option value="15m">15 minutes</option>
|
|
<option value="1h">1 hour</option>
|
|
<option value="6h">6 hours</option>
|
|
<option value="1d">1 day</option>
|
|
<option value="7d">7 days</option>
|
|
<option value="">permanent</option>
|
|
</select>
|
|
<input
|
|
type="text"
|
|
value={reason}
|
|
onChange={(e) => setReason(e.target.value)}
|
|
placeholder="reason (optional)"
|
|
className="terminal-input w-full mb-2"
|
|
/>
|
|
<div className="flex gap-2">
|
|
<button onClick={() => onMute?.(duration, reason)} className="flex-1 bg-gb-yellow text-gb-bg py-1 hover:bg-gb-orange">
|
|
[MUTE]
|
|
</button>
|
|
<button onClick={() => setMode("menu")} className="flex-1 bg-gb-bg-t text-gb-fg py-1 hover:bg-gb-bg-s">
|
|
[BACK]
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="absolute z-50 bg-gb-bg border border-gb-bg-t py-1 font-mono text-xs shadow-lg min-w-[140px]">
|
|
<button onClick={onMessage} className="w-full text-left px-3 py-1 hover:bg-gb-bg-t text-gb-fg">
|
|
Message
|
|
</button>
|
|
{canKick && (
|
|
<button onClick={() => setMode("kick")} className="w-full text-left px-3 py-1 hover:bg-gb-bg-t text-gb-yellow">
|
|
Kick
|
|
</button>
|
|
)}
|
|
{canMute && (
|
|
<button onClick={() => setMode("mute")} className="w-full text-left px-3 py-1 hover:bg-gb-bg-t text-gb-orange">
|
|
Mute
|
|
</button>
|
|
)}
|
|
{canBan && (
|
|
<button onClick={() => setMode("ban")} className="w-full text-left px-3 py-1 hover:bg-gb-bg-t text-gb-red">
|
|
Ban
|
|
</button>
|
|
)}
|
|
<div className="border-t border-gb-bg-t my-1" />
|
|
<button onClick={onClose} className="w-full text-left px-3 py-1 hover:bg-gb-bg-t text-gb-fg-f">
|
|
Cancel
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|