Files
onboard/resources/js/Components/DatePickerQuery.vue

137 lines
4.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup>
import {NDatePicker, NIcon, } from 'naive-ui'
import {computed, onMounted, ref, watch} from "vue";
import {router} from "@inertiajs/vue3";
import {TbCalendar} from 'vue-icons-plus/tb'
import {formatRussianDate, formatRussianDateRange} from "../Utils/dateFormatter.js";
import {useReportStore} from "../Stores/report.js";
const props = defineProps({
// Пользователь с ролью админ или зав
isHeadOrAdmin: {
type: Boolean,
default: false
},
date: {
type: [Number, Array]
},
isOneDay: {
type: Boolean
}
})
const reportStore = useReportStore()
const isUseDateRange = computed(() => props.isHeadOrAdmin)
const datePicker = ref()
const showCalendar = ref(false)
const dateType = computed(() => {
if (isUseDateRange.value) return 'daterange'
return 'date'
})
const queryDate = ref([null, null])
const modelValue = defineModel('date')
const setQueryDate = () => {
reportStore.openedCollapsible = []
router.reload({
data: {
startAt: queryDate.value[0],
endAt: queryDate.value[1]
},
})
}
// Форматированное значение для отображения
const formattedValue = computed(() => {
const value = modelValue.value
if (props.isHeadOrAdmin) {
if (props.isOneDay) {
const dateToFormat = Array.isArray(value) ? value[1] : value
return formatRussianDate(dateToFormat)
} else if (Array.isArray(value) && value.length >= 2 && value[0] && value[1]) { // Для админа - диапазон дат
return formatRussianDateRange(value)
}
// Если что-то пошло не так, форматируем как одиночную дату
if (value) {
const dateToFormat = Array.isArray(value) ? value[0] : value
return formatRussianDate(dateToFormat)
}
return ''
} else {
// Для врача - одиночная дата
let dateToFormat
if (Array.isArray(value)) {
dateToFormat = value[1] || value[0]
} else {
dateToFormat = value
}
// Если выбрана сегодняшняя дата - показываем текущее время
if (dateToFormat) {
return formatRussianDate(dateToFormat)
}
return ''
}
})
const handleDateUpdate = (value) => {
// Устанавливаем новое значение
modelValue.value = value
// Для диапазона: отправляем только если обе даты заполнены
if (isUseDateRange.value) {
if (Array.isArray(value) && value[0] && value[1]) {
// Дебаунс для предотвращения двойной отправки
setTimeout(() => {
// Проверяем что значение не изменилось за время таймаута
if (JSON.stringify(modelValue.value) === JSON.stringify(value)) {
queryDate.value = value
setQueryDate()
}
}, 100)
}
} else {
// Для одиночной даты отправляем сразу
if (value) {
queryDate.value = [value, value]
setQueryDate()
}
}
}
</script>
<template>
<div class="relative inline-flex items-center">
<div v-if="formattedValue" class="font-medium leading-3 cursor-pointer" @click="showCalendar = true">
{{ formattedValue }}
</div>
<NDatePicker v-model:value="modelValue"
v-model:show="showCalendar"
ref="datePicker"
class="opacity-0 absolute! inset-x-0 bottom-full -translate-y-1/2"
placement="top-start"
input-readonly
bind-calendar-months
@update:value="value => handleDateUpdate(value)"
:type="dateType" />
<div class="cursor-pointer p-2 flex items-center justify-center" @click="showCalendar = true">
<NIcon size="20">
<TbCalendar />
</NIcon>
</div>
</div>
</template>
<style scoped>
:deep(.n-input) {
position: absolute;
pointer-events: none;
}
</style>