tasks-multi-delete-dialog.tsx 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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 '@/utils/sleep'
  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. interface Props<TData> {
  12. open: boolean
  13. onOpenChange: (open: boolean) => void
  14. table: Table<TData>
  15. }
  16. const CONFIRM_WORD = 'DELETE'
  17. export function TasksMultiDeleteDialog<TData>({
  18. open,
  19. onOpenChange,
  20. table,
  21. }: Props<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 tasks...',
  32. success: () => {
  33. table.resetRowSelection()
  34. return `Deleted ${selectedRows.length} ${
  35. selectedRows.length > 1 ? 'tasks' : 'task'
  36. }`
  37. },
  38. error: 'Error',
  39. })
  40. }
  41. return (
  42. <ConfirmDialog
  43. open={open}
  44. onOpenChange={onOpenChange}
  45. handleConfirm={handleDelete}
  46. disabled={value.trim() !== CONFIRM_WORD}
  47. title={
  48. <span className='text-destructive'>
  49. <AlertTriangle
  50. className='stroke-destructive me-1 inline-block'
  51. size={18}
  52. />{' '}
  53. Delete {selectedRows.length}{' '}
  54. {selectedRows.length > 1 ? 'tasks' : 'task'}
  55. </span>
  56. }
  57. desc={
  58. <div className='space-y-4'>
  59. <p className='mb-2'>
  60. Are you sure you want to delete the selected tasks? <br />
  61. This action cannot be undone.
  62. </p>
  63. <Label className='my-4 flex flex-col items-start gap-1.5'>
  64. <span className=''>Confirm by typing "{CONFIRM_WORD}":</span>
  65. <Input
  66. value={value}
  67. onChange={(e) => setValue(e.target.value)}
  68. placeholder={`Type "${CONFIRM_WORD}" to confirm.`}
  69. />
  70. </Label>
  71. <Alert variant='destructive'>
  72. <AlertTitle>Warning!</AlertTitle>
  73. <AlertDescription>
  74. Please be careful, this operation can not be rolled back.
  75. </AlertDescription>
  76. </Alert>
  77. </div>
  78. }
  79. confirmText='Delete'
  80. destructive
  81. />
  82. )
  83. }