feat: api client, auth store, login, authed shell, data-table + CRUD kit
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
import { useState } from 'react'
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
AlertDialogTrigger,
|
||||
} from '@/components/ui/alert-dialog'
|
||||
|
||||
interface ConfirmDialogProps {
|
||||
trigger: React.ReactNode
|
||||
title: string
|
||||
description?: string
|
||||
confirmLabel?: string
|
||||
destructive?: boolean
|
||||
onConfirm: () => Promise<void> | void
|
||||
}
|
||||
|
||||
export function ConfirmDialog({
|
||||
trigger,
|
||||
title,
|
||||
description,
|
||||
confirmLabel = '确认',
|
||||
destructive = false,
|
||||
onConfirm,
|
||||
}: ConfirmDialogProps) {
|
||||
const [busy, setBusy] = useState(false)
|
||||
|
||||
return (
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger asChild>{trigger}</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>{title}</AlertDialogTitle>
|
||||
{description && <AlertDialogDescription>{description}</AlertDialogDescription>}
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>取消</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
disabled={busy}
|
||||
className={destructive ? 'bg-destructive text-white hover:bg-destructive/90' : undefined}
|
||||
onClick={async (event) => {
|
||||
event.preventDefault()
|
||||
setBusy(true)
|
||||
try {
|
||||
await onConfirm()
|
||||
// close via Escape-equivalent: AlertDialogAction default closes,
|
||||
// but we prevented it — dispatch close by clicking cancel sibling.
|
||||
;(event.target as HTMLElement)
|
||||
.closest('[role="alertdialog"]')
|
||||
?.querySelector<HTMLButtonElement>('[data-slot="alert-dialog-cancel"]')
|
||||
?.click()
|
||||
} finally {
|
||||
setBusy(false)
|
||||
}
|
||||
}}
|
||||
>
|
||||
{busy ? '处理中…' : confirmLabel}
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user