refactor(cms): separate dashboard data and editor components with focused UX fixes
CI / check (push) Successful in 1m32s
CI / deploy (push) Successful in 1m20s
CI / e2e (push) Successful in 21s

This commit is contained in:
Simo committed 2026-09-05 18:46:03 +02:00
1 parent 3ae4f21217
commit e17346ab9f
11 files changed
+1212 -1118

No files matched your search

File diff suppressed because it is too large. Load diff
@@ -0,0 +1,56 @@
"use client";
import { cn } from "@/lib/utils";
/* ─── Helpers ────────────────────────────────────────────── */
export function categorizePerms(keys: string[]) {
const commands: string[] = [];
const account: string[] = [];
const other: string[] = [];
for (const key of keys.sort()) {
if (key.startsWith("cmd_") || key === "kiss_cmd") commands.push(key);
else if (key.startsWith("acc_")) account.push(key);
else other.push(key);
}
return { commands, account, other };
}
/* ─── Tri-state Toggle ───────────────────────────────────── */
export function PermToggle({
value,
maxValue,
onChange,
}: {
value: string;
maxValue: number;
onChange: (v: string) => void;
}) {
const values = Array.from({ length: Math.max(1, maxValue) + 1 }, (_, i) =>
String(i),
);
return (
<div className="flex gap-0.5 shrink-0">
{values.map((v) => (
<button
key={v}
type="button"
aria-pressed={v === value}
aria-label={`Permission value ${v}`}
onClick={() => onChange(v)}
className={cn(
"w-7 h-6 text-[11px] font-mono rounded transition-all font-medium",
v === value
? v === "0"
? "bg-[var(--admin-text-muted)] text-[var(--color-surface-text-readable)] shadow-sm"
: v === "1"
? "bg-[var(--admin-success)] text-[var(--admin-success-foreground)] shadow-sm"
: "bg-[var(--admin-warning)] text-[var(--admin-warning-foreground)] shadow-sm"
: "bg-muted/60 text-muted-foreground/40 hover:bg-muted hover:text-muted-foreground",
)}
>
{v}
</button>
))}
</div>
);
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,41 @@
interface RankData {
id: number;
rank_name: string;
badge: string;
level: number;
prefix: string;
prefix_color: string;
hidden_rank: string;
log_commands: string;
room_effect: number;
auto_credits_amount: number;
auto_pixels_amount: number;
auto_gotw_amount: number;
auto_points_amount: number;
permissions: Record<string, string>;
permissionMaxValues: Record<string, number>;
}
interface RankUser {
id: number;
username: string;
look: string;
}
interface CmsRoleData {
id: number;
slug: string;
title: string;
permissionSlugs: string[];
}
interface CmsPermission {
id: number;
slug: string;
title: string;
}
export interface RankEditorProps {
rank: RankData;
users: RankUser[];
totalUsers: number;
cmsRole: CmsRoleData | null;
allCmsPermissions: CmsPermission[];
}
File diff suppressed because it is too large. Load diff
+77
View File
@@ -0,0 +1,77 @@
export interface UserPrefix {
id: number;
user_id: number;
text: string;
color: string;
icon: string;
effect: string;
active: boolean;
created_at: string;
username?: string;
}
export interface BlacklistWord {
id: number;
word: string;
created_at: string;
}
export interface PrefixSettings {
max_length: string;
min_rank_to_buy: string;
price_credits: string;
price_points: string;
points_type: string;
}
export interface PrefixFormData {
username: string;
text: string;
color: string;
icon: string;
effect: string;
active: boolean;
}
export const PRESET_EFFECTS = [
{ id: "", label: "None" },
{ id: "glow", label: "✨ Glow" },
{ id: "shadow", label: "🌑 Shadow" },
{ id: "italic", label: "𝑰 Italic" },
{ id: "outline", label: "🔲 Outline" },
{ id: "pulse", label: "💫 Pulse" },
{ id: "bold-glow", label: "💡 Neon" },
];
export const PRESET_ICONS = [
{ emoji: "", label: "None" },
{ emoji: "👑", label: "Crown" },
{ emoji: "⭐", label: "Star" },
{ emoji: "❤️", label: "Heart" },
{ emoji: "💎", label: "Diamond" },
{ emoji: "🔥", label: "Fire" },
{ emoji: "⚡", label: "Lightning" },
{ emoji: "🛡️", label: "Shield" },
{ emoji: "💀", label: "Skull" },
{ emoji: "🎵", label: "Music" },
{ emoji: "💠", label: "Gem" },
{ emoji: "⚔️", label: "Swords" },
{ emoji: "🏆", label: "Trophy" },
{ emoji: "🚀", label: "Rocket" },
{ emoji: "👻", label: "Ghost" },
{ emoji: "🐾", label: "Paw" },
{ emoji: "🍃", label: "Leaf" },
{ emoji: "😎", label: "Cool" },
{ emoji: "🐺", label: "Wolf" },
{ emoji: "🦁", label: "Lion" },
{ emoji: "🐉", label: "Dragon" },
{ emoji: "🦄", label: "Unicorn" },
{ emoji: "🌙", label: "Moon" },
{ emoji: "☀️", label: "Sun" },
{ emoji: "❄️", label: "Snow" },
{ emoji: "🌹", label: "Rose" },
{ emoji: "🎮", label: "Controller" },
{ emoji: "💰", label: "Money" },
{ emoji: "🔮", label: "Orb" },
{ emoji: "🏴‍☠️", label: "Pirate" },
];
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff