feat: Add configuration management for default user roles and permissions

This commit is contained in:
beilunyang
2024-12-28 00:54:29 +08:00
parent 798def1d89
commit 6420cd7570
10 changed files with 145 additions and 20 deletions
+88
View File
@@ -0,0 +1,88 @@
"use client"
import { Button } from "@/components/ui/button"
import { Settings } from "lucide-react"
import { useToast } from "@/components/ui/use-toast"
import { useState, useEffect } from "react"
import { Role, ROLES } from "@/lib/permissions"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
export function ConfigPanel() {
const [defaultRole, setDefaultRole] = useState<string>("")
const [loading, setLoading] = useState(false)
const { toast } = useToast()
useEffect(() => {
fetchConfig()
}, [])
const fetchConfig = async () => {
const res = await fetch("/api/config")
if (res.ok) {
const data = await res.json() as { defaultRole: Exclude<Role, typeof ROLES.EMPEROR> }
setDefaultRole(data.defaultRole)
}
}
const handleSave = async () => {
setLoading(true)
try {
const res = await fetch("/api/config", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ defaultRole }),
})
if (!res.ok) throw new Error("保存失败")
toast({
title: "保存成功",
description: "默认角色设置已更新",
})
} catch (error) {
toast({
title: "保存失败",
description: error instanceof Error ? error.message : "请稍后重试",
variant: "destructive",
})
} finally {
setLoading(false)
}
}
return (
<div className="bg-background rounded-lg border-2 border-primary/20 p-6">
<div className="flex items-center gap-2 mb-6">
<Settings className="w-5 h-5 text-primary" />
<h2 className="text-lg font-semibold"></h2>
</div>
<div className="space-y-4">
<div className="flex items-center gap-4">
<span className="text-sm">:</span>
<Select value={defaultRole} onValueChange={setDefaultRole}>
<SelectTrigger className="w-32">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value={ROLES.KNIGHT}></SelectItem>
<SelectItem value={ROLES.CIVILIAN}></SelectItem>
</SelectContent>
</Select>
<Button
onClick={handleSave}
disabled={loading}
>
</Button>
</div>
</div>
</div>
)
}
+3
View File
@@ -10,6 +10,7 @@ import { WebhookConfig } from "./webhook-config"
import { PromotePanel } from "./promote-panel"
import { useRolePermission } from "@/hooks/use-role-permission"
import { PERMISSIONS } from "@/lib/permissions"
import { ConfigPanel } from "./config-panel"
interface ProfileCardProps {
user: User
@@ -26,6 +27,7 @@ export function ProfileCard({ user }: ProfileCardProps) {
const { checkPermission } = useRolePermission()
const canManageWebhook = checkPermission(PERMISSIONS.MANAGE_WEBHOOK)
const canPromote = checkPermission(PERMISSIONS.PROMOTE_USER)
const canManageConfig = checkPermission(PERMISSIONS.MANAGE_CONFIG)
return (
<div className="max-w-2xl mx-auto space-y-6">
@@ -85,6 +87,7 @@ export function ProfileCard({ user }: ProfileCardProps) {
</div>
)}
{canManageConfig && <ConfigPanel />}
{canPromote && <PromotePanel />}
<div className="flex flex-col sm:flex-row gap-4 px-1">