import { keepPreviousData } from '@tanstack/react-query'
import { useDebounce } from '@uidotdev/usehooks'
import { Check, ChevronsUpDown } from 'lucide-react'
import { useMemo, useState } from 'react'
import { toast } from 'sonner'
import {
Button,
cn,
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
copyToClipboard,
Popover,
PopoverContent,
PopoverTrigger,
ScrollArea,
} from 'ui'
import { Admonition } from 'ui-patterns/admonition'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader'
import { User, useUsersInfiniteQuery } from '@/data/auth/users-infinite-query'
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
import { useRoleImpersonationStateSnapshot } from '@/state/role-impersonation-state'
import { ResponseError } from '@/types'
export const UserSelector = () => {
const { data: project } = useSelectedProjectQuery()
const state = useRoleImpersonationStateSnapshot()
const [open, setOpen] = useState(false)
const [searchText, setSearchText] = useState('')
const debouncedSearchText = useDebounce(searchText, 300)
const { data, error, isSuccess, isPending, isError } = useUsersInfiniteQuery(
{
projectRef: project?.ref,
connectionString: project?.connectionString,
keywords: debouncedSearchText.trim().toLocaleLowerCase(),
},
{ placeholderData: keepPreviousData }
)
const users = useMemo(() => data?.pages.flatMap((page) => page.result) ?? [], [data?.pages])
const impersonatingUser =
state.role?.type === 'postgrest' &&
state.role.role === 'authenticated' &&
state.role.userType === 'native'
? state.role.user
: undefined
const onSelectUser = async (user: User) => {
try {
await state.setRole({
type: 'postgrest',
role: 'authenticated',
userType: 'native',
user,
aal: 'aal1',
})
} catch (error) {
toast.error(`Failed to impersonate user: ${(error as ResponseError).message}`)
}
}
return (
{
copyToClipboard(impersonatingUser?.id ?? '')
toast('Copied ID to clipboard')
}}
>
{impersonatingUser.id}
{user.email}
{user.id?.slice(0, 8)}