61 lines
1.6 KiB
Vue
61 lines
1.6 KiB
Vue
<script setup>
|
|
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
|
|
import CalendarView from './components/CalendarView.vue'
|
|
import { useCalendarStore } from './stores/CalendarStore'
|
|
import { lang } from './utils/locale'
|
|
import { formatTodayString } from './utils/date'
|
|
|
|
const calendarStore = useCalendarStore()
|
|
|
|
// Initialize holidays when app starts
|
|
function isEditableElement(el) {
|
|
if (!el) return false
|
|
const tag = el.tagName
|
|
if (tag === 'INPUT' || tag === 'TEXTAREA') return true
|
|
if (el.isContentEditable) return true
|
|
return false
|
|
}
|
|
|
|
function handleGlobalKey(e) {
|
|
// Only consider Ctrl/Meta+Z combos
|
|
if (!(e.ctrlKey || e.metaKey)) return
|
|
if (e.key !== 'z' && e.key !== 'Z') return
|
|
// Don't interfere with native undo/redo inside editable fields
|
|
const target = e.target
|
|
if (isEditableElement(target)) return
|
|
// Decide undo vs redo (Shift = redo)
|
|
if (e.shiftKey) {
|
|
calendarStore.$history?.redo()
|
|
} else {
|
|
calendarStore.$history?.undo()
|
|
}
|
|
e.preventDefault()
|
|
}
|
|
|
|
onMounted(() => {
|
|
calendarStore.initializeHolidaysFromConfig()
|
|
document.addEventListener('keydown', handleGlobalKey, { passive: false })
|
|
// Set document language via shared util
|
|
if (lang) document.documentElement.setAttribute('lang', lang)
|
|
})
|
|
|
|
onBeforeUnmount(() => {
|
|
document.removeEventListener('keydown', handleGlobalKey)
|
|
})
|
|
|
|
// Watch today's date to update document title
|
|
watch(
|
|
() => calendarStore.now,
|
|
(val) => {
|
|
document.title = formatTodayString(new Date(val), "short", "short")
|
|
},
|
|
{ immediate: false },
|
|
)
|
|
</script>
|
|
|
|
<template>
|
|
<CalendarView />
|
|
</template>
|
|
|
|
<style scoped></style>
|