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:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user