import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router' import { t } from '@/i18n' import { useLocalizedOverlay } from '@/i18n/presentation' import ConfirmDialog from '@/components/ConfirmDialog.vue' import { authRedirectPending } from '@/composables/useApi' interface UnsavedChangesOptions { isDirty: () => boolean title: () => string onDiscard?: () => void } export function useUnsavedChangesGuard({ isDirty, title, onDiscard }: UnsavedChangesOptions) { const overlay = useLocalizedOverlay() async function allowsLeaving() { if (authRedirectPending.value || !isDirty()) { return true } const confirmed = await overlay .create(ConfirmDialog, { props: { get title() { return t('Leave without saving?') }, get description() { return t("Your changes to \u0022{0}\u0022 haven't been saved.", [title()]) }, get confirmLabel() { return t('Keep editing') }, get cancelLabel() { return t('Discard changes') }, get pendingLabel() { return t('Keep editing') }, tone: 'neutral', action: async () => {}, dismissResolvesTo: 'confirm', }, }) .open() if (confirmed) { return false } onDiscard?.() return true } onBeforeRouteLeave(allowsLeaving) onBeforeRouteUpdate((to, from) => (to.params.id === from.params.id ? true : allowsLeaving())) }