Files
saladeaula.digital/apps/admin.saladeaula.digital/app/routes/_.$orgid.users._index/columns.tsx
2025-11-25 13:39:19 -03:00

141 lines
3.8 KiB
TypeScript

'use client'
import { type ColumnDef } from '@tanstack/react-table'
import { useToggle } from 'ahooks'
import {
EllipsisVerticalIcon,
PencilIcon,
UserRoundMinusIcon
} from 'lucide-react'
import { NavLink, useParams } from 'react-router'
import { toast } from 'sonner'
import {
useDataTable,
DataTableColumnHeaderSelect,
DataTableColumnSelect
} from '@repo/ui/components/data-table'
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger
} from '@repo/ui/components/ui/alert-dialog'
import { Button } from '@repo/ui/components/ui/button'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger
} from '@repo/ui/components/ui/dropdown-menu'
import { Spinner } from '@repo/ui/components/ui/spinner'
import { type User, columns as columns_ } from '@repo/ui/routes/users/columns'
export type { User }
export const columns: ColumnDef<User>[] = [
{
id: 'select',
header: DataTableColumnHeaderSelect,
cell: DataTableColumnSelect,
meta: { className: 'w-9' }
},
...columns_,
{
id: 'actions',
cell: ActionMenu,
meta: { className: 'w-12' }
}
]
function ActionMenu({ row }: { row: any }) {
return (
<div className="flex justify-end items-center">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
variant="ghost"
className="data-[state=open]:bg-muted text-muted-foreground cursor-pointer"
size="icon-sm"
>
<EllipsisVerticalIcon />
<span className="sr-only">Abrir menu</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-36 *:cursor-pointer">
<DropdownMenuItem asChild onSelect={(e) => e.preventDefault()}>
<NavLink to={`${row.id}`}>
{({ isPending }) => (
<>
{isPending ? <Spinner /> : <PencilIcon />}
Editar
</>
)}
</NavLink>
</DropdownMenuItem>
<UnlinkItem id={row.id} />
</DropdownMenuContent>
</DropdownMenu>
</div>
)
}
function UnlinkItem({ id }: { id: string }) {
const [loading, { set }] = useToggle(false)
const { orgid } = useParams()
const { table } = useDataTable<User>()
const unlink = async (e) => {
e.preventDefault()
set(true)
const r = await fetch(`/~/api/orgs/${orgid}/users/${id}`, {
method: 'DELETE'
})
if (r.ok) {
toast.info('O colaborador foi desvinculado')
// @ts-ignore
table.options.meta?.removeRow?.(id)
}
}
return (
<AlertDialog>
<AlertDialogTrigger asChild>
<DropdownMenuItem
variant="destructive"
onSelect={(e) => e.preventDefault()}
>
<UserRoundMinusIcon /> Desvincular
</DropdownMenuItem>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Tem certeza absoluta?</AlertDialogTitle>
<AlertDialogDescription>
Esta ação não pode ser desfeita. Isso{' '}
<span className="font-bold">
removerá permanentemente o vínculo
</span>{' '}
deste colaborador.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter className="*:cursor-pointer">
<AlertDialogCancel>Cancelar</AlertDialogCancel>
<AlertDialogAction asChild>
<Button onClick={unlink} disabled={loading} variant="destructive">
{loading ? <Spinner /> : null} Continuar
</Button>
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
)
}