96 lines
2.6 KiB
TypeScript
96 lines
2.6 KiB
TypeScript
'use client'
|
|
|
|
import { useState } from 'react'
|
|
import { type Table } from '@tanstack/react-table'
|
|
import { AlertTriangle } from 'lucide-react'
|
|
import { toast } from 'sonner'
|
|
import { sleep } from '@/lib/utils'
|
|
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
|
|
import { Input } from '@/components/ui/input'
|
|
import { Label } from '@/components/ui/label'
|
|
import { ConfirmDialog } from '@/components/confirm-dialog'
|
|
|
|
type TaskMultiDeleteDialogProps<TData> = {
|
|
open: boolean
|
|
onOpenChange: (open: boolean) => void
|
|
table: Table<TData>
|
|
}
|
|
|
|
const CONFIRM_WORD = 'DELETE'
|
|
|
|
export function TasksMultiDeleteDialog<TData>({
|
|
open,
|
|
onOpenChange,
|
|
table,
|
|
}: TaskMultiDeleteDialogProps<TData>) {
|
|
const [value, setValue] = useState('')
|
|
|
|
const selectedRows = table.getFilteredSelectedRowModel().rows
|
|
|
|
const handleDelete = () => {
|
|
if (value.trim() !== CONFIRM_WORD) {
|
|
toast.error(`Please type "${CONFIRM_WORD}" to confirm.`)
|
|
return
|
|
}
|
|
|
|
onOpenChange(false)
|
|
|
|
toast.promise(sleep(2000), {
|
|
loading: 'Deleting tasks...',
|
|
success: () => {
|
|
setValue('')
|
|
table.resetRowSelection()
|
|
return `Deleted ${selectedRows.length} ${
|
|
selectedRows.length > 1 ? 'tasks' : 'task'
|
|
}`
|
|
},
|
|
error: 'Error',
|
|
})
|
|
}
|
|
|
|
return (
|
|
<ConfirmDialog
|
|
open={open}
|
|
onOpenChange={onOpenChange}
|
|
handleConfirm={handleDelete}
|
|
disabled={value.trim() !== CONFIRM_WORD}
|
|
title={
|
|
<span className='text-destructive'>
|
|
<AlertTriangle
|
|
className='me-1 inline-block stroke-destructive'
|
|
size={18}
|
|
/>{' '}
|
|
Delete {selectedRows.length}{' '}
|
|
{selectedRows.length > 1 ? 'tasks' : 'task'}
|
|
</span>
|
|
}
|
|
desc={
|
|
<div className='space-y-4'>
|
|
<p className='mb-2'>
|
|
Are you sure you want to delete the selected tasks? <br />
|
|
This action cannot be undone.
|
|
</p>
|
|
|
|
<Label className='my-4 flex flex-col items-start gap-1.5'>
|
|
<span className=''>Confirm by typing "{CONFIRM_WORD}":</span>
|
|
<Input
|
|
value={value}
|
|
onChange={(e) => setValue(e.target.value)}
|
|
placeholder={`Type "${CONFIRM_WORD}" to confirm.`}
|
|
/>
|
|
</Label>
|
|
|
|
<Alert variant='destructive'>
|
|
<AlertTitle>Warning!</AlertTitle>
|
|
<AlertDescription>
|
|
Please be careful, this operation can not be rolled back.
|
|
</AlertDescription>
|
|
</Alert>
|
|
</div>
|
|
}
|
|
confirmText='Delete'
|
|
destructive
|
|
/>
|
|
)
|
|
}
|