98 lines
2.7 KiB
TypeScript
98 lines
2.7 KiB
TypeScript
import type { ApplicationFormDto } from '~~/.api-client'
|
|
import { useLogger } from '~/composables/useLogger'
|
|
|
|
interface LocalStorageBackup {
|
|
formId: string
|
|
sectionIndex: number
|
|
timestamp: number
|
|
formData: ApplicationFormDto
|
|
}
|
|
|
|
const STORAGE_KEY_PREFIX = 'lch-form-backup-'
|
|
|
|
export function useLocalStorageBackup(formId: string) {
|
|
const storageKey = `${STORAGE_KEY_PREFIX}${formId}`
|
|
const logger = useLogger().withTag('localStorageBackup')
|
|
|
|
const hasBackup = ref(false)
|
|
const backupTimestamp = ref<Date | null>(null)
|
|
const backupSectionIndex = ref<number | null>(null)
|
|
|
|
function checkForBackup(): boolean {
|
|
if (import.meta.server) return false
|
|
|
|
try {
|
|
const storedApplicationForm = localStorage.getItem(storageKey)
|
|
if (storedApplicationForm) {
|
|
const backup = JSON.parse(storedApplicationForm) as LocalStorageBackup
|
|
hasBackup.value = true
|
|
backupTimestamp.value = new Date(backup.timestamp)
|
|
backupSectionIndex.value = backup.sectionIndex
|
|
return true
|
|
}
|
|
} catch {
|
|
clearBackup()
|
|
}
|
|
return false
|
|
}
|
|
|
|
function saveBackup(formData: ApplicationFormDto, currentSectionIndex: number): void {
|
|
if (import.meta.server) return
|
|
|
|
try {
|
|
const backup: LocalStorageBackup = {
|
|
formId,
|
|
sectionIndex: currentSectionIndex,
|
|
timestamp: Date.now(),
|
|
formData
|
|
}
|
|
localStorage.setItem(storageKey, JSON.stringify(backup))
|
|
hasBackup.value = true
|
|
backupTimestamp.value = new Date(backup.timestamp)
|
|
backupSectionIndex.value = currentSectionIndex
|
|
} catch (e) {
|
|
// localStorage might be full or unavailable
|
|
logger.error('Error saving backup', e)
|
|
}
|
|
}
|
|
|
|
function loadBackup(): ApplicationFormDto | null {
|
|
if (import.meta.server) return null
|
|
|
|
try {
|
|
const stored = localStorage.getItem(storageKey)
|
|
if (stored) {
|
|
const backup = JSON.parse(stored) as LocalStorageBackup
|
|
return backup.formData
|
|
}
|
|
} catch {
|
|
clearBackup()
|
|
}
|
|
return null
|
|
}
|
|
|
|
function clearBackup(): void {
|
|
if (import.meta.server) return
|
|
|
|
localStorage.removeItem(storageKey)
|
|
hasBackup.value = false
|
|
backupTimestamp.value = null
|
|
backupSectionIndex.value = null
|
|
}
|
|
|
|
// Call synchronously - import.meta.server guard handles SSR safety.
|
|
// Do NOT use onMounted here: this composable is called after `await` in async setup(),
|
|
// which means Vue's active component instance is gone and lifecycle hooks cannot be registered.
|
|
checkForBackup()
|
|
|
|
return {
|
|
hasBackup: readonly(hasBackup),
|
|
backupTimestamp: readonly(backupTimestamp),
|
|
backupSectionIndex: readonly(backupSectionIndex),
|
|
saveBackup,
|
|
loadBackup,
|
|
clearBackup,
|
|
checkForBackup
|
|
}
|
|
}
|