Scrum4Me/components/shared/use-dirty-close-guard.tsx
Madhura68 b05c4d241b feat(dialogs): gedeelde primitives — useDirtyCloseGuard, useDialogSubmitShortcut, layout-classes
Story 1 van PBI "Alle dialogen conform docs/patterns/dialog.md".

- components/shared/use-dirty-close-guard.tsx — hook + paired AlertDialog
- components/shared/use-dialog-submit-shortcut.ts — Cmd/Ctrl+Enter handler
- components/shared/entity-dialog-layout.ts — MD3-conforme classes voor §4
- TaskDialog refactored om beide hooks + classes te gebruiken (geen
  gedragsverandering)
- 8 nieuwe unit-tests

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 07:14:07 +02:00

66 lines
1.6 KiB
TypeScript

'use client'
import { useState } from 'react'
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from '@/components/ui/alert-dialog'
export interface DirtyCloseGuard {
confirmOpen: boolean
setConfirmOpen: (v: boolean) => void
attemptClose: () => void
confirmDiscard: () => void
}
export function useDirtyCloseGuard(
isDirty: boolean,
onClose: () => void,
): DirtyCloseGuard {
const [confirmOpen, setConfirmOpen] = useState(false)
function attemptClose() {
if (isDirty) setConfirmOpen(true)
else onClose()
}
function confirmDiscard() {
setConfirmOpen(false)
onClose()
}
return { confirmOpen, setConfirmOpen, attemptClose, confirmDiscard }
}
export function DirtyCloseGuardDialog({
guard,
}: {
guard: DirtyCloseGuard
}) {
return (
<AlertDialog open={guard.confirmOpen} onOpenChange={guard.setConfirmOpen}>
<AlertDialogContent size="sm">
<AlertDialogHeader>
<AlertDialogTitle>Wijzigingen niet opgeslagen</AlertDialogTitle>
<AlertDialogDescription>
Wil je de wijzigingen weggooien?
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel onClick={() => guard.setConfirmOpen(false)}>
Terug
</AlertDialogCancel>
<AlertDialogAction variant="destructive" onClick={guard.confirmDiscard}>
Weggooien
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
)
}