frontend/src/components/input/datepicker.vue

187 lines
4.0 KiB
Vue

<template>
<div class="datepicker">
<a @click.stop="show = !show">
<template v-if="date === null">
{{ chooseDateLabel }}
</template>
<template v-else>
{{ formatDateShort(date) }}
</template>
</a>
<transition name="fade">
<div v-if="show" class="datepicker-popup">
<a @click.stop="() => setDate('today')">
<span class="icon">
<icon :icon="['far', 'calendar-alt']"/>
</span>
<span class="text">
<span>
Today
</span>
<span class="weekday">
{{ getWeekdayFromStringInterval('today') }}
</span>
</span>
</a>
<a @click.stop="() => setDate('tomorrow')">
<span class="icon">
<icon :icon="['far', 'sun']"/>
</span>
<span class="text">
<span>
Tomorrow
</span>
<span class="weekday">
{{ getWeekdayFromStringInterval('tomorrow') }}
</span>
</span>
</a>
<a @click.stop="() => setDate('nextMonday')">
<span class="icon">
<icon icon="coffee"/>
</span>
<span class="text">
<span>
Next Monday
</span>
<span class="weekday">
{{ getWeekdayFromStringInterval('nextMonday') }}
</span>
</span>
</a>
<a @click.stop="() => setDate('thisWeekend')">
<span class="icon">
<icon icon="cocktail"/>
</span>
<span class="text">
<span>
This Weekend
</span>
<span class="weekday">
{{ getWeekdayFromStringInterval('thisWeekend') }}
</span>
</span>
</a>
<a @click.stop="() => setDate('laterThisWeek')">
<span class="icon">
<icon icon="chess-knight"/>
</span>
<span class="text">
<span>
Later This Week
</span>
<span class="weekday">
{{ getWeekdayFromStringInterval('laterThisWeek') }}
</span>
</span>
</a>
<a @click.stop="() => setDate('nextWeek')">
<span class="icon">
<icon icon="forward"/>
</span>
<span class="text">
<span>
Next Week
</span>
<span class="weekday">
{{ getWeekdayFromStringInterval('nextWeek') }}
</span>
</span>
</a>
<flat-pickr
:config="flatPickerConfig"
class="input"
v-model="date"
/>
</div>
</transition>
</div>
</template>
<script>
import flatPickr from 'vue-flatpickr-component'
import 'flatpickr/dist/flatpickr.css'
import {calculateDayInterval} from '@/helpers/time/calculateDayInterval'
import {format} from 'date-fns'
import {calculateNearestHours} from '@/helpers/time/calculateNearestHours'
export default {
name: 'datepicker',
data() {
return {
date: null,
show: false,
flatPickerConfig: {
altFormat: 'j M Y H:i',
altInput: true,
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
inline: true,
},
}
},
components: {
flatPickr,
},
props: {
value: {
validator: prop => prop instanceof Date || prop === null
},
chooseDateLabel: {
type: String,
default: 'Choose a date'
},
},
mounted() {
this.date = this.value
document.addEventListener('click', this.hideDatePopup)
},
beforeDestroy() {
document.removeEventListener('click', this.hideDatePopup)
},
watch: {
value(newVal) {
this.date = newVal
},
},
methods: {
updateData() {
this.$emit('input', this.date)
this.$emit('change')
},
hideDatePopup() {
this.show = false
},
setDate(date) {
if (this.date === null) {
this.date = new Date()
}
const interval = calculateDayInterval(date)
const newDate = new Date()
newDate.setDate(newDate.getDate() + interval)
newDate.setHours(calculateNearestHours(newDate))
newDate.setMinutes(0)
newDate.setSeconds(0)
this.date = newDate
this.updateData()
},
getDayIntervalFromString(date) {
return calculateDayInterval(date)
},
getWeekdayFromStringInterval(date) {
const interval = calculateDayInterval(date)
const newDate = new Date()
newDate.setDate(newDate.getDate() + interval)
return format(newDate, 'E')
},
},
}
</script>