Files
chrono/src/components/editors/EventEditorDateTimeField.vue
T
Sebastian e5ec5bb6a0 feat(editor): improve desing
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
2026-08-06 21:45:03 -04:00

97 lines
2.9 KiB
Vue

<script setup lang="ts">
import { ref, watch } from 'vue'
import { formatDisplayDate, formatDisplayTime, formatLocalIsoDate, formatLocalIsoTime } from '@/utils/format'
interface Props {
modelValue?: string | null
}
const props = defineProps<Props>()
const emit = defineEmits<{
'update:modelValue': [value: string | null]
}>()
const dateValue = ref('')
const timeValue = ref('')
const dateMenu = ref(false)
const timeMenu = ref(false)
watch(() => props.modelValue, (value) => {
const date = value ? new Date(value) : new Date()
dateValue.value = formatLocalIsoDate(date)
timeValue.value = formatLocalIsoTime(date)
}, { immediate: true })
const emitValue = () => {
if (!dateValue.value || !timeValue.value) return
emit('update:modelValue', new Date(`${dateValue.value}T${timeValue.value}`).toISOString())
}
const pickerDate = (value: string): Date | null => value ? new Date(`${value}T00:00:00`) : null
const normalizePickerDate = (value: unknown): string => {
const selected = Array.isArray(value) ? value[0] : value
const date = selected instanceof Date ? selected : new Date(String(selected))
return Number.isNaN(date.getTime()) ? '' : formatLocalIsoDate(date)
}
const selectDate = (value: unknown) => {
const date = normalizePickerDate(value)
if (date) dateValue.value = date
dateMenu.value = false
emitValue()
}
watch(timeValue, () => emitValue())
</script>
<template>
<v-row dense>
<v-col cols="6">
<v-menu v-model="dateMenu" :close-on-content-click="false" location="bottom start">
<template #activator="{ props: activatorProps }">
<v-text-field
v-bind="activatorProps"
:model-value="formatDisplayDate(dateValue)"
label="Date"
prepend-inner-icon="mdi-calendar"
variant="outlined"
density="compact"
hide-details
readonly
/>
</template>
<v-date-picker
:model-value="pickerDate(dateValue)"
color="primary"
show-adjacent-months
@update:model-value="selectDate"
/>
</v-menu>
</v-col>
<v-col cols="6">
<v-menu v-model="timeMenu" :close-on-content-click="false" location="bottom start">
<template #activator="{ props: activatorProps }">
<v-text-field
v-bind="activatorProps"
:model-value="formatDisplayTime(timeValue)"
label="Time"
prepend-inner-icon="mdi-clock-outline"
variant="outlined"
density="compact"
hide-details
readonly
/>
</template>
<v-card>
<v-time-picker v-model="timeValue" color="primary" format="ampm" />
<v-card-actions class="justify-end">
<v-btn variant="text" @click="timeMenu = false">Done</v-btn>
</v-card-actions>
</v-card>
</v-menu>
</v-col>
</v-row>
</template>