Create useConfirm composable (promise-based, singleton state) and ConfirmModal component. Replace all 10 confirm()/window.confirm() calls across 9 pages and 1 composable. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
74 lines
1.5 KiB
TypeScript
74 lines
1.5 KiB
TypeScript
/**
|
|
* Promise-based confirmation dialog composable.
|
|
*
|
|
* Usage:
|
|
* const { confirm, confirmState } = useConfirm()
|
|
* const ok = await confirm({ message: 'Supprimer ?' })
|
|
* if (ok) { ... }
|
|
*
|
|
* The ConfirmModal component reads `confirmState` to render the dialog.
|
|
*/
|
|
|
|
import { reactive } from 'vue'
|
|
|
|
export interface ConfirmOptions {
|
|
title?: string
|
|
message: string
|
|
confirmText?: string
|
|
cancelText?: string
|
|
dangerous?: boolean
|
|
}
|
|
|
|
export interface ConfirmState {
|
|
open: boolean
|
|
title: string
|
|
message: string
|
|
confirmText: string
|
|
cancelText: string
|
|
dangerous: boolean
|
|
resolve: ((value: boolean) => void) | null
|
|
}
|
|
|
|
const state = reactive<ConfirmState>({
|
|
open: false,
|
|
title: '',
|
|
message: '',
|
|
confirmText: 'Supprimer',
|
|
cancelText: 'Annuler',
|
|
dangerous: true,
|
|
resolve: null,
|
|
})
|
|
|
|
function confirm(options: ConfirmOptions): Promise<boolean> {
|
|
return new Promise((resolve) => {
|
|
state.title = options.title ?? 'Confirmation'
|
|
state.message = options.message
|
|
state.confirmText = options.confirmText ?? 'Supprimer'
|
|
state.cancelText = options.cancelText ?? 'Annuler'
|
|
state.dangerous = options.dangerous ?? true
|
|
state.resolve = resolve
|
|
state.open = true
|
|
})
|
|
}
|
|
|
|
function handleConfirm() {
|
|
state.resolve?.(true)
|
|
state.open = false
|
|
state.resolve = null
|
|
}
|
|
|
|
function handleCancel() {
|
|
state.resolve?.(false)
|
|
state.open = false
|
|
state.resolve = null
|
|
}
|
|
|
|
export function useConfirm() {
|
|
return {
|
|
confirm,
|
|
confirmState: state,
|
|
handleConfirm,
|
|
handleCancel,
|
|
}
|
|
}
|