Files
aurorabot/web/src/pages/settings/Systems.tsx

339 lines
21 KiB
TypeScript

import React from "react";
import { useSettingsForm } from "./SettingsLayout";
import { FormField, FormItem, FormLabel, FormControl, FormDescription } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Switch } from "@/components/ui/switch";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
import { CreditCard, Shield } from "lucide-react";
import { fromSelectValue, toSelectValue, NONE_VALUE } from "@/hooks/use-settings";
export function SystemsSettings() {
const { form, meta } = useSettingsForm();
return (
<div className="space-y-6 animate-in fade-in slide-up duration-500">
<Accordion type="multiple" className="w-full space-y-4" defaultValue={["lootdrop", "moderation"]}>
<AccordionItem value="lootdrop" className="border border-border/40 rounded-xl bg-card/30 px-4 transition-all data-[state=open]:border-primary/20 data-[state=open]:bg-card/50">
<AccordionTrigger className="hover:no-underline py-4">
<div className="flex items-center gap-2">
<div className="w-8 h-8 rounded-full bg-indigo-500/10 flex items-center justify-center text-indigo-500">
<CreditCard className="w-4 h-4" />
</div>
<span className="font-bold">Loot Drops</span>
</div>
</AccordionTrigger>
<AccordionContent className="space-y-4 pb-4">
<div className="grid grid-cols-2 gap-4">
<FormField
control={form.control}
name="lootdrop.spawnChance"
render={({ field }) => (
<FormItem>
<FormLabel>Spawn Chance (0-1)</FormLabel>
<FormControl>
<Input {...field} type="number" step="0.01" min="0" max="1" className="bg-background/50" onChange={e => field.onChange(Number(e.target.value))} />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="lootdrop.minMessages"
render={({ field }) => (
<FormItem>
<FormLabel>Min Messages</FormLabel>
<FormControl>
<Input {...field} type="number" className="bg-background/50" onChange={e => field.onChange(Number(e.target.value))} />
</FormControl>
</FormItem>
)}
/>
</div>
<div className="bg-muted/30 p-4 rounded-lg space-y-3">
<h4 className="text-xs font-bold text-muted-foreground uppercase tracking-wider">Rewards</h4>
<div className="grid grid-cols-3 gap-4">
<FormField
control={form.control}
name="lootdrop.reward.min"
render={({ field }) => (
<FormItem className="space-y-1">
<FormLabel className="text-xs">Min</FormLabel>
<FormControl>
<Input {...field} type="number" className="h-9 text-sm" onChange={e => field.onChange(Number(e.target.value))} />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="lootdrop.reward.max"
render={({ field }) => (
<FormItem className="space-y-1">
<FormLabel className="text-xs">Max</FormLabel>
<FormControl>
<Input {...field} type="number" className="h-9 text-sm" onChange={e => field.onChange(Number(e.target.value))} />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="lootdrop.reward.currency"
render={({ field }) => (
<FormItem className="space-y-1">
<FormLabel className="text-xs">Currency</FormLabel>
<FormControl>
<Input {...field} placeholder="AU" className="h-9 text-sm" />
</FormControl>
</FormItem>
)}
/>
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<FormField
control={form.control}
name="lootdrop.cooldownMs"
render={({ field }) => (
<FormItem>
<FormLabel>Cooldown (ms)</FormLabel>
<FormControl>
<Input {...field} type="number" className="bg-background/50" onChange={e => field.onChange(Number(e.target.value))} />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="lootdrop.activityWindowMs"
render={({ field }) => (
<FormItem>
<FormLabel>Activity Window (ms)</FormLabel>
<FormControl>
<Input {...field} type="number" className="bg-background/50" onChange={e => field.onChange(Number(e.target.value))} />
</FormControl>
</FormItem>
)}
/>
</div>
</AccordionContent>
</AccordionItem>
<AccordionItem value="trivia" className="border border-border/40 rounded-xl bg-card/30 px-4 transition-all data-[state=open]:border-primary/20 data-[state=open]:bg-card/50">
<AccordionTrigger className="hover:no-underline py-4">
<div className="flex items-center gap-2">
<div className="w-8 h-8 rounded-full bg-purple-500/10 flex items-center justify-center text-purple-500 text-sm">
🎯
</div>
<span className="font-bold">Trivia</span>
</div>
</AccordionTrigger>
<AccordionContent className="space-y-4 pb-4">
<div className="grid grid-cols-2 gap-4">
<FormField
control={form.control}
name="trivia.entryFee"
render={({ field }) => (
<FormItem>
<FormLabel>Entry Fee (AU)</FormLabel>
<FormControl>
<Input {...field} type="text" className="bg-background/50" placeholder="50" />
</FormControl>
<FormDescription className="text-xs">Cost to play</FormDescription>
</FormItem>
)}
/>
<FormField
control={form.control}
name="trivia.rewardMultiplier"
render={({ field }) => (
<FormItem>
<FormLabel>Reward Multiplier</FormLabel>
<FormControl>
<Input {...field} type="number" step="0.1" className="bg-background/50" onChange={e => field.onChange(Number(e.target.value))} />
</FormControl>
<FormDescription className="text-xs">multiplier</FormDescription>
</FormItem>
)}
/>
</div>
<div className="grid grid-cols-2 gap-4">
<FormField
control={form.control}
name="trivia.timeoutSeconds"
render={({ field }) => (
<FormItem>
<FormLabel>Timeout (seconds)</FormLabel>
<FormControl>
<Input {...field} type="number" className="bg-background/50" onChange={e => field.onChange(Number(e.target.value))} />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="trivia.cooldownMs"
render={({ field }) => (
<FormItem>
<FormLabel>Cooldown (ms)</FormLabel>
<FormControl>
<Input {...field} type="number" className="bg-background/50" onChange={e => field.onChange(Number(e.target.value))} />
</FormControl>
</FormItem>
)}
/>
</div>
<FormField
control={form.control}
name="trivia.difficulty"
render={({ field }) => (
<FormItem>
<FormLabel>Difficulty</FormLabel>
<Select onValueChange={field.onChange} value={field.value}>
<FormControl>
<SelectTrigger className="bg-background/50">
<SelectValue placeholder="Select difficulty" />
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectItem value="easy">Easy</SelectItem>
<SelectItem value="medium">Medium</SelectItem>
<SelectItem value="hard">Hard</SelectItem>
<SelectItem value="random">Random</SelectItem>
</SelectContent>
</Select>
</FormItem>
)}
/>
</AccordionContent>
</AccordionItem>
<AccordionItem value="moderation" className="border border-border/40 rounded-xl bg-card/30 px-4 transition-all data-[state=open]:border-primary/20 data-[state=open]:bg-card/50">
<AccordionTrigger className="hover:no-underline py-4">
<div className="flex items-center gap-2">
<div className="w-8 h-8 rounded-full bg-red-500/10 flex items-center justify-center text-red-500">
<Shield className="w-4 h-4" />
</div>
<span className="font-bold">Moderation</span>
</div>
</AccordionTrigger>
<AccordionContent className="space-y-6 pb-4">
<div className="space-y-4">
<h4 className="font-bold text-sm text-foreground/80 uppercase tracking-wider">Case Management</h4>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<FormField
control={form.control}
name="moderation.cases.dmOnWarn"
render={({ field }) => (
<FormItem className="flex flex-row items-center justify-between rounded-lg border border-border/50 bg-background/50 p-4">
<div className="space-y-0.5">
<FormLabel className="text-sm font-medium">DM on Warm</FormLabel>
<FormDescription className="text-xs">Notify via DM</FormDescription>
</div>
<FormControl>
<Switch checked={field.value} onCheckedChange={field.onChange} />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="moderation.cases.logChannelId"
render={({ field }) => (
<FormItem className="glass-card p-4 rounded-xl border border-border/50">
<FormLabel className="text-sm">Log Channel</FormLabel>
<Select onValueChange={v => field.onChange(fromSelectValue(v))} value={toSelectValue(field.value || null)}>
<FormControl>
<SelectTrigger className="bg-background/50 h-9">
<SelectValue placeholder="Select a channel" />
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectItem value={NONE_VALUE}>None</SelectItem>
{meta?.channels.filter(c => c.type === 0).map(c => (
<SelectItem key={c.id} value={c.id}>#{c.name}</SelectItem>
))}
</SelectContent>
</Select>
</FormItem>
)}
/>
</div>
<FormField
control={form.control}
name="moderation.cases.autoTimeoutThreshold"
render={({ field }) => (
<FormItem>
<FormLabel>Auto Timeout Threshold</FormLabel>
<FormControl>
<Input {...field} type="number" min="0" className="bg-background/50" onChange={e => field.onChange(e.target.value ? Number(e.target.value) : undefined)} />
</FormControl>
<FormDescription className="text-xs">Warnings before auto-timeout.</FormDescription>
</FormItem>
)}
/>
</div>
<div className="space-y-4">
<h4 className="font-bold text-sm text-foreground/80 uppercase tracking-wider">Message Pruning</h4>
<div className="grid grid-cols-2 gap-4">
<FormField
control={form.control}
name="moderation.prune.maxAmount"
render={({ field }) => (
<FormItem>
<FormLabel className="text-xs">Max Amount</FormLabel>
<FormControl>
<Input {...field} type="number" className="bg-background/50 h-9" onChange={e => field.onChange(Number(e.target.value))} />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="moderation.prune.confirmThreshold"
render={({ field }) => (
<FormItem>
<FormLabel className="text-xs">Confirm Threshold</FormLabel>
<FormControl>
<Input {...field} type="number" className="bg-background/50 h-9" onChange={e => field.onChange(Number(e.target.value))} />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="moderation.prune.batchSize"
render={({ field }) => (
<FormItem>
<FormLabel className="text-xs">Batch Size</FormLabel>
<FormControl>
<Input {...field} type="number" className="bg-background/50 h-9" onChange={e => field.onChange(Number(e.target.value))} />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="moderation.prune.batchDelayMs"
render={({ field }) => (
<FormItem>
<FormLabel className="text-xs">Batch Delay (ms)</FormLabel>
<FormControl>
<Input {...field} type="number" className="bg-background/50 h-9" onChange={e => field.onChange(Number(e.target.value))} />
</FormControl>
</FormItem>
)}
/>
</div>
</div>
</AccordionContent>
</AccordionItem>
</Accordion>
</div>
);
}