feat(admin): organize command center controls and diagnostics
This commit is contained in:
@@ -28,6 +28,7 @@ export function CommandocentrumControls() {
|
||||
const t = useTranslations("pages.admin.commandocentrum");
|
||||
const { run, isPending } = useServerAction();
|
||||
|
||||
const [category, setCategory] = useState("hotel");
|
||||
const [hotelMessage, setHotelMessage] = useState("");
|
||||
const [disconnect, setDisconnect] = useState({ userId: "", username: "" });
|
||||
const [alert, setAlert] = useState({ userId: "", message: "" });
|
||||
@@ -46,10 +47,30 @@ export function CommandocentrumControls() {
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<section className="mt-6">
|
||||
<h2 className="admin-section-title">{t("emulatorControls")}</h2>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
|
||||
<section id="commands" className="my-6 scroll-mt-4 space-y-4">
|
||||
<h2 className="admin-section-title">{t("emulatorControls")}</h2>
|
||||
<fieldset
|
||||
className="flex flex-wrap gap-2"
|
||||
aria-label={t("commandCategories")}
|
||||
>
|
||||
{["hotel", "players", "rewards", "advanced"].map((group) => (
|
||||
<Button
|
||||
key={group}
|
||||
type="button"
|
||||
variant={category === group ? "default" : "outline"}
|
||||
aria-pressed={category === group}
|
||||
disabled={isPending}
|
||||
onClick={() => setCategory(group)}
|
||||
>
|
||||
{t(`groups.${group}`)}
|
||||
</Button>
|
||||
))}
|
||||
</fieldset>
|
||||
<p className="text-sm text-[var(--admin-text-muted)]" role="status">
|
||||
{isPending ? t("executing") : t("chooseCommand")}
|
||||
</p>
|
||||
<div className="grid grid-cols-1 gap-4 lg:grid-cols-2 xl:grid-cols-3">
|
||||
{category === "hotel" && (
|
||||
<div className="admin-card">
|
||||
<h3 className="text-sm font-bold text-[var(--admin-text)] mb-2">
|
||||
{t("updateCatalog")}
|
||||
@@ -71,7 +92,8 @@ export function CommandocentrumControls() {
|
||||
{t("updateCatalog")}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
)}
|
||||
{category === "hotel" && (
|
||||
<div className="admin-card">
|
||||
<h3 className="text-sm font-bold text-[var(--admin-text)] mb-2">
|
||||
{t("updateWordFilter")}
|
||||
@@ -93,7 +115,8 @@ export function CommandocentrumControls() {
|
||||
{t("updateWordFilter")}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
)}
|
||||
{category === "hotel" && (
|
||||
<div className="admin-card">
|
||||
<h3 className="text-sm font-bold text-[var(--admin-text)] mb-2">
|
||||
{t("updateNavigator")}
|
||||
@@ -115,50 +138,44 @@ export function CommandocentrumControls() {
|
||||
{t("updateNavigator")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="admin-card mt-6">
|
||||
<h3 className="text-sm font-bold text-[var(--admin-text)] mb-2">
|
||||
{t("hotelAlert")}
|
||||
</h3>
|
||||
<p className="text-xs text-[var(--admin-text-muted)] mb-3">
|
||||
{t("hotelAlertDesc")}
|
||||
</p>
|
||||
<div className="flex gap-2">
|
||||
<input
|
||||
value={hotelMessage}
|
||||
onChange={(e) => setHotelMessage(e.target.value)}
|
||||
required
|
||||
maxLength={512}
|
||||
placeholder={t("messageToBroadcast")}
|
||||
className="flex-1 min-w-[220px]"
|
||||
disabled={isPending}
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
variant="destructive"
|
||||
disabled={isPending || !hotelMessage.trim()}
|
||||
onClick={() =>
|
||||
run(() => hotelAlert({ message: hotelMessage }), {
|
||||
successMessage: "Hotel alert sent.",
|
||||
errorMessage: RCON_ERROR,
|
||||
onSuccess: () => setHotelMessage(""),
|
||||
})
|
||||
}
|
||||
>
|
||||
{t("sendAlert")}
|
||||
</Button>
|
||||
)}
|
||||
{category === "hotel" && (
|
||||
<div className="admin-card">
|
||||
<h3 className="text-sm font-bold text-[var(--admin-text)] mb-2">
|
||||
{t("hotelAlert")}
|
||||
</h3>
|
||||
<p className="text-xs text-[var(--admin-text-muted)] mb-3">
|
||||
{t("hotelAlertDesc")}
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<input
|
||||
value={hotelMessage}
|
||||
onChange={(e) => setHotelMessage(e.target.value)}
|
||||
required
|
||||
maxLength={512}
|
||||
aria-label={t("messageToBroadcast")}
|
||||
placeholder={t("messageToBroadcast")}
|
||||
className="flex-1 min-w-0 w-full sm:w-auto"
|
||||
disabled={isPending}
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
variant="destructive"
|
||||
disabled={isPending || !hotelMessage.trim()}
|
||||
onClick={() =>
|
||||
run(() => hotelAlert({ message: hotelMessage }), {
|
||||
successMessage: "Hotel alert sent.",
|
||||
errorMessage: RCON_ERROR,
|
||||
onSuccess: () => setHotelMessage(""),
|
||||
})
|
||||
}
|
||||
>
|
||||
{t("sendAlert")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="mt-6">
|
||||
<h2 className="admin-section-title">{t("userActions")}</h2>
|
||||
<p className="text-xs text-[var(--admin-text-muted)] mb-4">
|
||||
{t("userActionsDesc")}
|
||||
</p>
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
|
||||
)}
|
||||
{category === "players" && (
|
||||
<div className="admin-card">
|
||||
<h3 className="text-sm font-bold text-[var(--admin-text)] mb-2">
|
||||
{t("actions.disconnect")}
|
||||
@@ -170,6 +187,7 @@ export function CommandocentrumControls() {
|
||||
<input
|
||||
type="number"
|
||||
min={1}
|
||||
aria-label={t("userId")}
|
||||
placeholder={t("userId")}
|
||||
value={disconnect.userId}
|
||||
onChange={(e) =>
|
||||
@@ -180,6 +198,7 @@ export function CommandocentrumControls() {
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
aria-label={t("usernameRequired")}
|
||||
placeholder={t("usernameRequired")}
|
||||
value={disconnect.username}
|
||||
onChange={(e) =>
|
||||
@@ -215,7 +234,8 @@ export function CommandocentrumControls() {
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)}
|
||||
{category === "players" && (
|
||||
<div className="admin-card">
|
||||
<h3 className="text-sm font-bold text-[var(--admin-text)] mb-2">
|
||||
{t("actions.alert")}
|
||||
@@ -227,6 +247,7 @@ export function CommandocentrumControls() {
|
||||
<input
|
||||
type="number"
|
||||
min={1}
|
||||
aria-label={t("userId")}
|
||||
placeholder={t("userId")}
|
||||
value={alert.userId}
|
||||
onChange={(e) =>
|
||||
@@ -237,6 +258,7 @@ export function CommandocentrumControls() {
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
aria-label={t("alertMessage")}
|
||||
placeholder={t("alertMessage")}
|
||||
value={alert.message}
|
||||
onChange={(e) =>
|
||||
@@ -270,7 +292,8 @@ export function CommandocentrumControls() {
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)}
|
||||
{category === "players" && (
|
||||
<div className="admin-card">
|
||||
<h3 className="text-sm font-bold text-[var(--admin-text)] mb-2">
|
||||
{t("forwardToRoom")}
|
||||
@@ -282,6 +305,7 @@ export function CommandocentrumControls() {
|
||||
<input
|
||||
type="number"
|
||||
min={1}
|
||||
aria-label={t("userId")}
|
||||
placeholder={t("userId")}
|
||||
value={forward.userId}
|
||||
onChange={(e) =>
|
||||
@@ -293,6 +317,7 @@ export function CommandocentrumControls() {
|
||||
<input
|
||||
type="number"
|
||||
min={1}
|
||||
aria-label={t("roomId")}
|
||||
placeholder={t("roomId")}
|
||||
value={forward.roomId}
|
||||
onChange={(e) =>
|
||||
@@ -325,9 +350,8 @@ export function CommandocentrumControls() {
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4 mt-4">
|
||||
)}
|
||||
{category === "rewards" && (
|
||||
<div className="admin-card">
|
||||
<h3 className="text-sm font-bold text-[var(--admin-text)] mb-2">
|
||||
{t("giveCredits")}
|
||||
@@ -339,6 +363,7 @@ export function CommandocentrumControls() {
|
||||
<input
|
||||
type="number"
|
||||
min={1}
|
||||
aria-label={t("userId")}
|
||||
placeholder={t("userId")}
|
||||
value={credits.userId}
|
||||
onChange={(e) =>
|
||||
@@ -350,6 +375,7 @@ export function CommandocentrumControls() {
|
||||
<input
|
||||
type="number"
|
||||
min={1}
|
||||
aria-label={t("amount")}
|
||||
placeholder={t("amount")}
|
||||
value={credits.credits}
|
||||
onChange={(e) =>
|
||||
@@ -382,7 +408,8 @@ export function CommandocentrumControls() {
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)}
|
||||
{category === "rewards" && (
|
||||
<div className="admin-card">
|
||||
<h3 className="text-sm font-bold text-[var(--admin-text)] mb-2">
|
||||
{t("giveDuckets")}
|
||||
@@ -394,6 +421,7 @@ export function CommandocentrumControls() {
|
||||
<input
|
||||
type="number"
|
||||
min={1}
|
||||
aria-label={t("userId")}
|
||||
placeholder={t("userId")}
|
||||
value={duckets.userId}
|
||||
onChange={(e) =>
|
||||
@@ -405,6 +433,7 @@ export function CommandocentrumControls() {
|
||||
<input
|
||||
type="number"
|
||||
min={1}
|
||||
aria-label={t("amount")}
|
||||
placeholder={t("amount")}
|
||||
value={duckets.amount}
|
||||
onChange={(e) =>
|
||||
@@ -437,7 +466,8 @@ export function CommandocentrumControls() {
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)}
|
||||
{category === "rewards" && (
|
||||
<div className="admin-card">
|
||||
<h3 className="text-sm font-bold text-[var(--admin-text)] mb-2">
|
||||
{t("giveDiamonds")}
|
||||
@@ -449,6 +479,7 @@ export function CommandocentrumControls() {
|
||||
<input
|
||||
type="number"
|
||||
min={1}
|
||||
aria-label={t("userId")}
|
||||
placeholder={t("userId")}
|
||||
value={diamonds.userId}
|
||||
onChange={(e) =>
|
||||
@@ -460,6 +491,7 @@ export function CommandocentrumControls() {
|
||||
<input
|
||||
type="number"
|
||||
min={1}
|
||||
aria-label={t("amount")}
|
||||
placeholder={t("amount")}
|
||||
value={diamonds.amount}
|
||||
onChange={(e) =>
|
||||
@@ -492,9 +524,8 @@ export function CommandocentrumControls() {
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4 mt-4">
|
||||
)}
|
||||
{category === "rewards" && (
|
||||
<div className="admin-card">
|
||||
<h3 className="text-sm font-bold text-[var(--admin-text)] mb-2">
|
||||
{t("giveBadge")}
|
||||
@@ -506,6 +537,7 @@ export function CommandocentrumControls() {
|
||||
<input
|
||||
type="number"
|
||||
min={1}
|
||||
aria-label={t("userId")}
|
||||
placeholder={t("userId")}
|
||||
value={badge.userId}
|
||||
onChange={(e) =>
|
||||
@@ -516,6 +548,7 @@ export function CommandocentrumControls() {
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
aria-label={t("badgeCode")}
|
||||
placeholder={t("badgeCode")}
|
||||
value={badge.badge}
|
||||
onChange={(e) =>
|
||||
@@ -549,7 +582,8 @@ export function CommandocentrumControls() {
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)}
|
||||
{category === "players" && (
|
||||
<div className="admin-card">
|
||||
<h3 className="text-sm font-bold text-[var(--admin-text)] mb-2">
|
||||
{t("setMotto")}
|
||||
@@ -561,6 +595,7 @@ export function CommandocentrumControls() {
|
||||
<input
|
||||
type="number"
|
||||
min={1}
|
||||
aria-label={t("userId")}
|
||||
placeholder={t("userId")}
|
||||
value={motto.userId}
|
||||
onChange={(e) =>
|
||||
@@ -571,6 +606,7 @@ export function CommandocentrumControls() {
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
aria-label={t("newMotto")}
|
||||
placeholder={t("newMotto")}
|
||||
value={motto.motto}
|
||||
onChange={(e) =>
|
||||
@@ -604,7 +640,8 @@ export function CommandocentrumControls() {
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)}
|
||||
{category === "players" && (
|
||||
<div className="admin-card">
|
||||
<h3 className="text-sm font-bold text-[var(--admin-text)] mb-2">
|
||||
{t("setRank")}
|
||||
@@ -616,6 +653,7 @@ export function CommandocentrumControls() {
|
||||
<input
|
||||
type="number"
|
||||
min={1}
|
||||
aria-label={t("userId")}
|
||||
placeholder={t("userId")}
|
||||
value={rank.userId}
|
||||
onChange={(e) =>
|
||||
@@ -628,6 +666,7 @@ export function CommandocentrumControls() {
|
||||
type="number"
|
||||
min={0}
|
||||
max={10}
|
||||
aria-label={t("rankPlaceholder")}
|
||||
placeholder={t("rankPlaceholder")}
|
||||
value={rank.rank}
|
||||
onChange={(e) =>
|
||||
@@ -660,9 +699,8 @@ export function CommandocentrumControls() {
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4 mt-4">
|
||||
)}
|
||||
{category === "advanced" && (
|
||||
<div className="admin-card">
|
||||
<h3 className="text-sm font-bold text-[var(--admin-text)] mb-2">
|
||||
{t("executeCommand")}
|
||||
@@ -674,6 +712,7 @@ export function CommandocentrumControls() {
|
||||
<input
|
||||
type="number"
|
||||
min={1}
|
||||
aria-label={t("userId")}
|
||||
placeholder={t("userId")}
|
||||
value={command.userId}
|
||||
onChange={(e) =>
|
||||
@@ -684,6 +723,7 @@ export function CommandocentrumControls() {
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
aria-label={t("commandPlaceholder")}
|
||||
placeholder={t("commandPlaceholder")}
|
||||
value={command.command}
|
||||
onChange={(e) =>
|
||||
@@ -719,7 +759,8 @@ export function CommandocentrumControls() {
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)}
|
||||
{category === "rewards" && (
|
||||
<div className="admin-card">
|
||||
<h3 className="text-sm font-bold text-[var(--admin-text)] mb-2">
|
||||
{t("sendGift")}
|
||||
@@ -731,6 +772,7 @@ export function CommandocentrumControls() {
|
||||
<input
|
||||
type="number"
|
||||
min={1}
|
||||
aria-label={t("userId")}
|
||||
placeholder={t("userId")}
|
||||
value={gift.userId}
|
||||
onChange={(e) =>
|
||||
@@ -742,6 +784,7 @@ export function CommandocentrumControls() {
|
||||
<input
|
||||
type="number"
|
||||
min={1}
|
||||
aria-label={t("furniId")}
|
||||
placeholder={t("furniId")}
|
||||
value={gift.itemId}
|
||||
onChange={(e) =>
|
||||
@@ -752,6 +795,7 @@ export function CommandocentrumControls() {
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
aria-label={t("giftMessage")}
|
||||
placeholder={t("giftMessage")}
|
||||
value={gift.message}
|
||||
onChange={(e) =>
|
||||
@@ -791,8 +835,8 @@ export function CommandocentrumControls() {
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user