forked from syntaxbullet/aurorabot
142 lines
8.3 KiB
TypeScript
142 lines
8.3 KiB
TypeScript
import React from "react";
|
|
import { useSettingsForm } from "./SettingsLayout";
|
|
import { FormField, FormItem, FormLabel, FormControl, FormDescription } from "@/components/ui/form";
|
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
|
import { Switch } from "@/components/ui/switch";
|
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
|
import { Badge } from "@/components/ui/badge";
|
|
import { Palette, Users } from "lucide-react";
|
|
import { fromSelectValue, toSelectValue } from "@/hooks/use-settings";
|
|
|
|
export function RolesSettings() {
|
|
const { form, meta } = useSettingsForm();
|
|
|
|
return (
|
|
<div className="space-y-8 animate-in fade-in slide-up duration-500">
|
|
<div className="space-y-4">
|
|
<div className="flex items-center gap-2 mb-4">
|
|
<Badge variant="outline" className="bg-primary/5 text-primary border-primary/20">
|
|
<Users className="w-3 h-3 mr-1" /> System Roles
|
|
</Badge>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<FormField
|
|
control={form.control}
|
|
name="studentRole"
|
|
render={({ field }) => (
|
|
<FormItem className="glass-card p-5 rounded-xl border border-border/50">
|
|
<FormLabel className="font-bold">Student Role</FormLabel>
|
|
<Select onValueChange={v => field.onChange(fromSelectValue(v))} value={toSelectValue(field.value || null)}>
|
|
<FormControl>
|
|
<SelectTrigger className="bg-background/50">
|
|
<SelectValue placeholder="Select role" />
|
|
</SelectTrigger>
|
|
</FormControl>
|
|
<SelectContent>
|
|
{meta?.roles.map(r => (
|
|
<SelectItem key={r.id} value={r.id}>
|
|
<span className="flex items-center gap-2">
|
|
<span className="w-3 h-3 rounded-full" style={{ background: r.color }} />
|
|
{r.name}
|
|
</span>
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
<FormDescription className="text-xs">Default role for new members/students.</FormDescription>
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
<FormField
|
|
control={form.control}
|
|
name="visitorRole"
|
|
render={({ field }) => (
|
|
<FormItem className="glass-card p-5 rounded-xl border border-border/50">
|
|
<FormLabel className="font-bold">Visitor Role</FormLabel>
|
|
<Select onValueChange={v => field.onChange(fromSelectValue(v))} value={toSelectValue(field.value || null)}>
|
|
<FormControl>
|
|
<SelectTrigger className="bg-background/50">
|
|
<SelectValue placeholder="Select role" />
|
|
</SelectTrigger>
|
|
</FormControl>
|
|
<SelectContent>
|
|
{meta?.roles.map(r => (
|
|
<SelectItem key={r.id} value={r.id}>
|
|
<span className="flex items-center gap-2">
|
|
<span className="w-3 h-3 rounded-full" style={{ background: r.color }} />
|
|
{r.name}
|
|
</span>
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
<FormDescription className="text-xs">Role for visitors/guests.</FormDescription>
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="space-y-4">
|
|
<div className="flex items-center gap-2 mb-4">
|
|
<Badge variant="outline" className="bg-primary/5 text-primary border-primary/20">
|
|
<Palette className="w-3 h-3 mr-1" /> Color Roles
|
|
</Badge>
|
|
</div>
|
|
|
|
<div className="glass-card p-6 rounded-xl border border-border/50 bg-card/30">
|
|
<div className="mb-4">
|
|
<FormDescription className="text-sm">
|
|
Select roles that users can choose from to set their name color in the bot.
|
|
</FormDescription>
|
|
</div>
|
|
<ScrollArea className="h-[400px] pr-4">
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
|
|
{meta?.roles.map((role) => (
|
|
<FormField
|
|
key={role.id}
|
|
control={form.control}
|
|
name="colorRoles"
|
|
render={({ field }) => {
|
|
const isSelected = field.value?.includes(role.id);
|
|
return (
|
|
<FormItem
|
|
key={role.id}
|
|
className={`flex flex-row items-center space-x-3 space-y-0 p-3 rounded-lg border transition-all cursor-pointer ${
|
|
isSelected
|
|
? 'bg-primary/10 border-primary/30 ring-1 ring-primary/20'
|
|
: 'hover:bg-muted/50 border-transparent'
|
|
}`}
|
|
>
|
|
<FormControl>
|
|
<Switch
|
|
checked={isSelected}
|
|
onCheckedChange={(checked) => {
|
|
return checked
|
|
? field.onChange([...(field.value || []), role.id])
|
|
: field.onChange(
|
|
field.value?.filter(
|
|
(value: string) => value !== role.id
|
|
)
|
|
)
|
|
}}
|
|
/>
|
|
</FormControl>
|
|
<FormLabel className="font-medium flex items-center gap-2 cursor-pointer w-full text-foreground text-sm">
|
|
<span className="w-3 h-3 rounded-full shadow-sm" style={{ background: role.color }} />
|
|
{role.name}
|
|
</FormLabel>
|
|
</FormItem>
|
|
)
|
|
}}
|
|
/>
|
|
))}
|
|
</div>
|
|
</ScrollArea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|