users-multi-delete-dialog.tsx 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. 'use client'
  2. import { useState } from 'react'
  3. import { type Table } from '@tanstack/react-table'
  4. import { AlertTriangle } from 'lucide-react'
  5. import { toast } from 'sonner'
  6. import { sleep } from '@/lib/utils'
  7. import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
  8. import { Input } from '@/components/ui/input'
  9. import { Label } from '@/components/ui/label'
  10. import { ConfirmDialog } from '@/components/confirm-dialog'
  11. type UserMultiDeleteDialogProps<TData> = {
  12. open: boolean
  13. onOpenChange: (open: boolean) => void
  14. table: Table<TData>
  15. }
  16. const CONFIRM_WORD = 'DELETE'
  17. export function UsersMultiDeleteDialog<TData>({
  18. open,
  19. onOpenChange,
  20. table,
  21. }: UserMultiDeleteDialogProps<TData>) {
  22. const [value, setValue] = useState('')
  23. const selectedRows = table.getFilteredSelectedRowModel().rows
  24. const handleDelete = () => {
  25. if (value.trim() !== CONFIRM_WORD) {
  26. toast.error(`Please type "${CONFIRM_WORD}" to confirm.`)
  27. return
  28. }
  29. onOpenChange(false)
  30. toast.promise(sleep(2000), {
  31. loading: 'Deleting users...',
  32. success: () => {
  33. setValue('')
  34. table.resetRowSelection()
  35. return `Deleted ${selectedRows.length} ${
  36. selectedRows.length > 1 ? 'users' : 'user'
  37. }`
  38. },
  39. error: 'Error',
  40. })
  41. }
  42. return (
  43. <ConfirmDialog
  44. open={open}
  45. onOpenChange={onOpenChange}
  46. handleConfirm={handleDelete}
  47. disabled={value.trim() !== CONFIRM_WORD}
  48. title={
  49. <span className='text-destructive'>
  50. <AlertTriangle
  51. className='me-1 inline-block stroke-destructive'
  52. size={18}
  53. />{' '}
  54. Delete {selectedRows.length}{' '}
  55. {selectedRows.length > 1 ? 'users' : 'user'}
  56. </span>
  57. }
  58. desc={
  59. <div className='space-y-4'>
  60. <p className='mb-2'>
  61. Are you sure you want to delete the selected users? <br />
  62. This action cannot be undone.
  63. </p>
  64. <Label className='my-4 flex flex-col items-start gap-1.5'>
  65. <span className=''>Confirm by typing "{CONFIRM_WORD}":</span>
  66. <Input
  67. value={value}
  68. onChange={(e) => setValue(e.target.value)}
  69. placeholder={`Type "${CONFIRM_WORD}" to confirm.`}
  70. />
  71. </Label>
  72. <Alert variant='destructive'>
  73. <AlertTitle>Warning!</AlertTitle>
  74. <AlertDescription>
  75. Please be careful, this operation can not be rolled back.
  76. </AlertDescription>
  77. </Alert>
  78. </div>
  79. }
  80. confirmText='Delete'
  81. destructive
  82. />
  83. )
  84. }