import { useState } from 'react' import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' import { storageFolderPermissionsOptions, storageFolderMutations, storageFolderKeys, } from '@/api/storage' import { roleListOptions } from '@/api/rbac' import { userListOptions } from '@/api/users' import type { UserRecord } from '@/api/users' import type { Role } from '@/types/rbac' import type { StorageFolderPermission } from '@/types/storage' import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog' import { Button } from '@/components/ui/button' import { Badge } from '@/components/ui/badge' import { Label } from '@/components/ui/label' import { Switch } from '@/components/ui/switch' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select' import { Trash2, Shield, Users, User } from 'lucide-react' import { toast } from 'sonner' interface FolderPermissionsDialogProps { folderId: string folderName: string isPublic: boolean open: boolean onOpenChange: (open: boolean) => void } const ACCESS_LEVELS = [ { value: 'traverse', label: 'Traverse', variant: 'outline' as const }, { value: 'view', label: 'View', variant: 'secondary' as const }, { value: 'edit', label: 'Edit', variant: 'default' as const }, { value: 'admin', label: 'Admin', variant: 'destructive' as const }, ] export function FolderPermissionsDialog({ folderId, folderName, isPublic, open, onOpenChange }: FolderPermissionsDialogProps) { const queryClient = useQueryClient() const [assigneeType, setAssigneeType] = useState<'role' | 'user'>('role') const [assigneeId, setAssigneeId] = useState('') const [accessLevel, setAccessLevel] = useState('view') const { data: permissionsData, isLoading: permsLoading } = useQuery({ ...storageFolderPermissionsOptions(folderId), enabled: open && !!folderId, }) const { data: rolesData } = useQuery({ ...roleListOptions(), enabled: open }) const { data: usersData } = useQuery({ ...userListOptions({ page: 1, limit: 100, order: 'asc' }), enabled: open && assigneeType === 'user', }) const permissions = permissionsData?.data ?? [] const roles = rolesData?.data ?? [] const users = usersData?.data ?? [] const togglePublicMutation = useMutation({ mutationFn: (newIsPublic: boolean) => storageFolderMutations.update(folderId, { isPublic: newIsPublic }), onSuccess: () => { queryClient.invalidateQueries({ queryKey: storageFolderKeys.all }) queryClient.invalidateQueries({ queryKey: storageFolderKeys.detail(folderId) }) toast.success(isPublic ? 'Folder set to private' : 'Folder set to public') }, onError: (err) => toast.error(err.message), }) const addPermissionMutation = useMutation({ mutationFn: () => storageFolderMutations.addPermission(folderId, { ...(assigneeType === 'role' ? { roleId: assigneeId } : { userId: assigneeId }), accessLevel, }), onSuccess: () => { queryClient.invalidateQueries({ queryKey: storageFolderKeys.permissions(folderId) }) setAssigneeId('') setAccessLevel('view') toast.success('Permission added') }, onError: (err) => toast.error(err.message), }) const removePermissionMutation = useMutation({ mutationFn: (permId: string) => storageFolderMutations.removePermission(permId), onSuccess: () => { queryClient.invalidateQueries({ queryKey: storageFolderKeys.permissions(folderId) }) toast.success('Permission removed') }, onError: (err) => toast.error(err.message), }) function getPermissionLabel(perm: StorageFolderPermission): { icon: typeof Shield; name: string } { if (perm.roleId) { const role = roles.find((r: Role) => r.id === perm.roleId) return { icon: Users, name: role?.name ?? 'Unknown role' } } const user = users.find((u: UserRecord) => u.id === perm.userId) return { icon: User, name: user ? `${user.firstName} ${user.lastName}` : 'Unknown user' } } function handleAdd(e: React.FormEvent) { e.preventDefault() if (!assigneeId) return addPermissionMutation.mutate() } return ( Permissions — {folderName}
{/* Public toggle */}

Public folders are viewable by all users with file access

togglePublicMutation.mutate(checked)} disabled={togglePublicMutation.isPending} />
{/* Current permissions */}
{permsLoading ? (

Loading...

) : permissions.length === 0 ? (

No specific permissions assigned

) : ( permissions.map((perm) => { const { icon: Icon, name } = getPermissionLabel(perm) const level = ACCESS_LEVELS.find((l) => l.value === perm.accessLevel) return (
{name}
{level?.label ?? perm.accessLevel}
) }) )}
{/* Add permission form */}
{/* Role / User toggle */}
{/* Assignee select */} {/* Access level select */}
) }