Ask before deleting without leaving the app

Deleting a period or a day went through the browser's own confirmation box.
It halts the page while it is open, which meant the delete path could not be
driven by anything automated, and it looks nothing like the rest of the app.
Both now ask inline: the first click offers the choice, and only the second
one deletes. That matters more than it did, since deleting a period now takes
its days with it.
This commit is contained in:
2026-09-18 00:49:39 +02:00
parent ac3b6a41d7
commit c5587c5b46
8 changed files with 229 additions and 117 deletions
@@ -55,6 +55,7 @@ export function PlannedDayModal({
const [isDubbeldag, setIsDubbeldag] = useState(false)
const [localError, setLocalError] = useState<string | null>(null)
const [isTogglingOverride, setIsTogglingOverride] = useState(false)
const [isConfirmingDelete, setIsConfirmingDelete] = useState(false)
useEffect(() => {
if (existingDay) {
@@ -67,6 +68,7 @@ export function PlannedDayModal({
setIsDubbeldag(false)
}
setLocalError(null)
setIsConfirmingDelete(false)
}, [isOpen, existingDay, selectedParentId, defaultDayType])
useEffect(() => {
@@ -88,15 +90,24 @@ export function PlannedDayModal({
}
}
const handleDelete = async () => {
const handleDeleteClick = () => {
if (!onDelete) return
if (confirm(t('plannedDayModal.confirmDelete'))) {
try {
setLocalError(null)
await onDelete()
} catch (err) {
setLocalError(err instanceof Error ? err.message : t('plannedDayModal.deleteError'))
}
setIsConfirmingDelete(true)
}
const handleCancelDelete = () => {
setIsConfirmingDelete(false)
}
const handleConfirmDelete = async () => {
if (!onDelete) return
try {
setLocalError(null)
await onDelete()
} catch (err) {
setLocalError(err instanceof Error ? err.message : t('plannedDayModal.deleteError'))
} finally {
setIsConfirmingDelete(false)
}
}
@@ -256,32 +267,59 @@ export function PlannedDayModal({
</div>
<div className="planned-day-modal__footer">
{!isRangeMode && existingDay && onDelete && (
<button
className="planned-day-modal__button planned-day-modal__button--danger"
onClick={handleDelete}
disabled={isSaving}
data-testid="delete-button"
>
{isSaving ? t('plannedDayModal.deletingButton') : t('plannedDayModal.deleteButton')}
</button>
{!isRangeMode && existingDay && onDelete && isConfirmingDelete && (
<div className="planned-day-modal__delete-confirm" data-testid="delete-confirm">
<span className="planned-day-modal__delete-confirm-text">
{t('plannedDayModal.confirmDelete')}
</span>
<button
className="planned-day-modal__button planned-day-modal__button--secondary"
onClick={handleCancelDelete}
disabled={isSaving}
data-testid="delete-cancel-button"
>
{t('plannedDayModal.cancelButton')}
</button>
<button
className="planned-day-modal__button planned-day-modal__button--danger"
onClick={() => void handleConfirmDelete()}
disabled={isSaving}
data-testid="delete-confirm-button"
>
{isSaving ? t('plannedDayModal.deletingButton') : t('plannedDayModal.deleteConfirmButton')}
</button>
</div>
)}
{!isConfirmingDelete && (
<>
{!isRangeMode && existingDay && onDelete && (
<button
className="planned-day-modal__button planned-day-modal__button--danger"
onClick={handleDeleteClick}
disabled={isSaving}
data-testid="delete-button"
>
{isSaving ? t('plannedDayModal.deletingButton') : t('plannedDayModal.deleteButton')}
</button>
)}
<button
className="planned-day-modal__button planned-day-modal__button--secondary"
onClick={onClose}
disabled={isSaving}
data-testid="cancel-button"
>
{t('plannedDayModal.cancelButton')}
</button>
<button
className="planned-day-modal__button planned-day-modal__button--primary"
onClick={handleSave}
disabled={isSaving}
data-testid="save-button"
>
{isSaving ? t('plannedDayModal.savingButton') : t('plannedDayModal.saveButton')}
</button>
</>
)}
<button
className="planned-day-modal__button planned-day-modal__button--secondary"
onClick={onClose}
disabled={isSaving}
data-testid="cancel-button"
>
{t('plannedDayModal.cancelButton')}
</button>
<button
className="planned-day-modal__button planned-day-modal__button--primary"
onClick={handleSave}
disabled={isSaving}
data-testid="save-button"
>
{isSaving ? t('plannedDayModal.savingButton') : t('plannedDayModal.saveButton')}
</button>
</div>
</div>
</div>