import { useCallback, useEffect, useState } from "react"; import { Loader2, AlertTriangle, Save, Check, TrendingUp, Coins, Package, Gift, Brain, Shield, Terminal, RotateCcw, Server, X, } from "lucide-react"; import { cn } from "../lib/utils"; import { useSettings, type GameSettings, type GuildSettings, type SettingsMeta, } from "../lib/useSettings"; // --------------------------------------------------------------------------- // Helpers // --------------------------------------------------------------------------- type SettingsSection = | "guild" | "leveling" | "economy" | "inventory" | "lootdrop" | "trivia" | "moderation" | "commands"; const sections: { key: SettingsSection; label: string; icon: React.ComponentType<{ className?: string }>; }[] = [ { key: "guild", label: "Guild", icon: Server }, { key: "leveling", label: "Leveling", icon: TrendingUp }, { key: "economy", label: "Economy", icon: Coins }, { key: "inventory", label: "Inventory", icon: Package }, { key: "lootdrop", label: "Lootdrops", icon: Gift }, { key: "trivia", label: "Trivia", icon: Brain }, { key: "moderation", label: "Moderation", icon: Shield }, { key: "commands", label: "Commands", icon: Terminal }, ]; function formatMs(ms: number): string { if (ms >= 86_400_000) return `${ms / 86_400_000}h`; if (ms >= 60_000) return `${ms / 60_000} min`; return `${ms / 1_000}s`; } // --------------------------------------------------------------------------- // Reusable field components // --------------------------------------------------------------------------- function Field({ label, hint, children, }: { label: string; hint?: string; children: React.ReactNode; }) { return (
{children} {hint &&

{hint}

}
); } function NumberInput({ value, onChange, min, max, step, className, }: { value: number; onChange: (v: number) => void; min?: number; max?: number; step?: number; className?: string; }) { return ( onChange(Number(e.target.value))} min={min} max={max} step={step} className={cn( "w-full bg-input border border-border rounded-md px-3 py-2 text-sm font-mono text-foreground", "focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/30", "transition-colors", className )} /> ); } function StringInput({ value, onChange, placeholder, className, }: { value: string; onChange: (v: string) => void; placeholder?: string; className?: string; }) { return ( onChange(e.target.value)} placeholder={placeholder} className={cn( "w-full bg-input border border-border rounded-md px-3 py-2 text-sm font-mono text-foreground", "focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/30", "transition-colors", className )} /> ); } function TextArea({ value, onChange, placeholder, rows = 3, }: { value: string; onChange: (v: string) => void; placeholder?: string; rows?: number; }) { return (