Update channel dashboard page
This commit is contained in:
@@ -16,8 +16,6 @@ import {
|
||||
Settings,
|
||||
Plus,
|
||||
Eye,
|
||||
Edit,
|
||||
UserPlus,
|
||||
Check,
|
||||
Search,
|
||||
MoreVertical,
|
||||
@@ -30,6 +28,7 @@ import {
|
||||
CreditCard,
|
||||
Cpu,
|
||||
Server,
|
||||
Trash2,
|
||||
} from "lucide-react"
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
|
||||
import { useLanguage } from "@/contexts/language-context"
|
||||
@@ -129,10 +128,8 @@ export default function ChannelDashboard() {
|
||||
|
||||
// Tenant detail/edit/manage users dialogs
|
||||
const [showTenantDetailsDialog, setShowTenantDetailsDialog] = useState(false)
|
||||
const [showManageUsersDialog, setShowManageUsersDialog] = useState(false)
|
||||
const [selectedTenantForDetails, setSelectedTenantForDetails] = useState<any>(null)
|
||||
const [tenantRole, setTenantRole] = useState<"tenant" | "billing-admin" | "operations-admin">("tenant")
|
||||
const [isUpdatingRole, setIsUpdatingRole] = useState(false)
|
||||
const [isDeletingTenant, setIsDeletingTenant] = useState(false)
|
||||
|
||||
// API Data states
|
||||
const [tenantsData, setTenantsData] = useState<any[]>([])
|
||||
@@ -919,22 +916,6 @@ export default function ChannelDashboard() {
|
||||
<Eye className="h-4 w-4 mr-2" />
|
||||
{text.viewDetails}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
setSelectedTenantForDetails(tenant)
|
||||
// 根据租户的 plan 或 role 设置初始角色
|
||||
// 默认从 subscriptionTier 推断:free->tenant, pro->billing-admin, enterprise->operations-admin
|
||||
const currentRole = tenant.plan === "free" ? "tenant"
|
||||
: tenant.plan === "pro" ? "billing-admin"
|
||||
: tenant.plan === "enterprise" ? "operations-admin"
|
||||
: "tenant"
|
||||
setTenantRole(currentRole as "tenant" | "billing-admin" | "operations-admin")
|
||||
setShowManageUsersDialog(true)
|
||||
}}
|
||||
>
|
||||
<UserPlus className="h-4 w-4 mr-2" />
|
||||
{language === "zh" ? "管理用户" : "Manage Users"}
|
||||
</DropdownMenuItem>
|
||||
{/* <DropdownMenuItem>
|
||||
<Cpu className="h-4 w-4 mr-2" />
|
||||
{text.allocateAgents}
|
||||
@@ -2647,125 +2628,6 @@ export default function ChannelDashboard() {
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{/* Manage Users Dialog */}
|
||||
<Dialog open={showManageUsersDialog} onOpenChange={setShowManageUsersDialog}>
|
||||
<DialogContent className="max-w-3xl">
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
{language === "zh" ? "管理用户" : "Manage Users"} - {selectedTenantForDetails?.name}
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4 py-4">
|
||||
<div>
|
||||
<p className="text-sm font-medium mb-2">
|
||||
{language === "zh" ? "租户登录信息" : "Tenant Login Info"}
|
||||
</p>
|
||||
<div className="rounded-lg border p-3 space-y-2">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-sm text-muted-foreground">{language === "zh" ? "邮箱" : "Email"}:</span>
|
||||
<span className="text-sm font-medium">{selectedTenantForDetails?.email || "N/A"}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-sm text-muted-foreground">{language === "zh" ? "租户ID" : "Tenant ID"}:</span>
|
||||
<span className="text-sm font-medium text-muted-foreground font-mono text-xs">{selectedTenantForDetails?.id || "N/A"}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="tenant-role" className="text-sm font-medium mb-2 block">
|
||||
{language === "zh" ? "租户角色" : "Tenant Role"}
|
||||
</Label>
|
||||
<Select
|
||||
value={tenantRole}
|
||||
onValueChange={(value: "tenant" | "billing-admin" | "operations-admin") => setTenantRole(value)}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="tenant">
|
||||
{language === "zh" ? "租户" : "Tenant"}
|
||||
</SelectItem>
|
||||
<SelectItem value="billing-admin">
|
||||
{language === "zh" ? "计费管理员" : "Billing Admin"}
|
||||
</SelectItem>
|
||||
<SelectItem value="operations-admin">
|
||||
{language === "zh" ? "运营管理员" : "Operations Admin"}
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<p className="text-xs text-muted-foreground mt-2">
|
||||
{language === "zh"
|
||||
? "修改角色后,租户将获得相应的权限。角色变更将影响租户的订阅等级。"
|
||||
: "Changing the role will grant the tenant corresponding permissions. Role changes will affect the tenant's subscription tier."}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => setShowManageUsersDialog(false)}
|
||||
>
|
||||
{language === "zh" ? "取消" : "Cancel"}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={async () => {
|
||||
if (!selectedTenantForDetails) return
|
||||
|
||||
setIsUpdatingRole(true)
|
||||
try {
|
||||
// 角色到订阅等级的映射
|
||||
const roleToTierMap: Record<string, string> = {
|
||||
"tenant": "free",
|
||||
"billing-admin": "pro",
|
||||
"operations-admin": "enterprise"
|
||||
}
|
||||
|
||||
// 更新租户的订阅等级(对应角色)
|
||||
const result = await TaijiAPIClient.updateTenantBilling(
|
||||
selectedTenantForDetails.id,
|
||||
{ subscriptionTier: roleToTierMap[tenantRole] }
|
||||
)
|
||||
|
||||
if (result.success) {
|
||||
toast({
|
||||
title: language === "zh" ? "更新成功" : "Success",
|
||||
description: language === "zh"
|
||||
? `租户角色已更新为 ${tenantRole === "tenant" ? "租户" : tenantRole === "billing-admin" ? "计费管理员" : "运营管理员"}`
|
||||
: `Tenant role updated to ${tenantRole}`,
|
||||
})
|
||||
|
||||
// 刷新租户列表
|
||||
await loadChannelData()
|
||||
setShowManageUsersDialog(false)
|
||||
} else {
|
||||
toast({
|
||||
title: language === "zh" ? "更新失败" : "Update Failed",
|
||||
description: (result as any)?.message || (language === "zh" ? "无法更新租户角色" : "Failed to update tenant role"),
|
||||
variant: "destructive",
|
||||
})
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error("Failed to update tenant role:", error)
|
||||
toast({
|
||||
title: language === "zh" ? "更新失败" : "Update Failed",
|
||||
description: error.message || (language === "zh" ? "网络错误,请稍后重试" : "Network error, please try again"),
|
||||
variant: "destructive",
|
||||
})
|
||||
} finally {
|
||||
setIsUpdatingRole(false)
|
||||
}
|
||||
}}
|
||||
disabled={isUpdatingRole}
|
||||
>
|
||||
{isUpdatingRole
|
||||
? (language === "zh" ? "保存中..." : "Saving...")
|
||||
: (language === "zh" ? "保存" : "Save")}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</main>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user