Refinements to date handling in booking form

This commit is contained in:
2023-11-28 21:03:39 -05:00
parent a3cdbbfbbd
commit aed0462e05
9 changed files with 274 additions and 165 deletions

View File

@@ -24,80 +24,115 @@
/>
</q-btn-group>
</div>
<div class="row justify-center">
<div style="display: flex; max-width: 1024px; width: 100%">
<q-calendar-resource
ref="calendar"
v-model="selectedDate"
:model-resources="boatStore.boats"
resource-key="id"
resource-label="name"
:interval-start="6"
:interval-count="12"
animated
bordered
@change="onChange"
@moved="onMoved"
@resource-expanded="onResourceExpanded"
@click-date="onClickDate"
@click-time="onClickTime"
@click-resource="onClickResource"
@click-head-resources="onClickHeadResources"
@click-interval="onClickInterval"
>
<template #resource-intervals="{ scope }">
<template v-for="(event, index) in getEvents(scope)" :key="index">
<q-badge
outline
color="primary"
:label="event.title"
:style="getStyle(event)"
/>
</template>
<q-calendar-month
ref="calendar"
v-model="selectedDate"
animated
bordered
mini-mode
date-type="rounded"
@change="onChange"
@moved="onMoved"
@click-date="onClickDate"
/>
<div style="float: right; display: flex; max-width: 1024px; width: 100%">
<q-calendar-resource
ref="calendar"
v-model="selectedDate"
:model-resources="boatStore.boats"
resource-key="id"
resource-label="name"
:interval-start="6"
:interval-count="18"
cell-width="64"
resource-min-height="40"
animated
bordered
@change="onChange"
@moved="onMoved"
@resource-expanded="onResourceExpanded"
@click-date="onClickDate"
@click-time="onClickTime"
@click-resource="onClickResource"
@click-head-resources="onClickHeadResources"
@click-interval="onClickInterval"
>
<template #resource-intervals="{ scope }">
<template v-for="(event, index) in getEvents(scope)" :key="index">
<q-badge outline :label="event.title" :style="getStyle(event)" />
</template>
</q-calendar-resource>
</div>
</template>
</q-calendar-resource>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { QCalendarResource, today } from '@quasar/quasar-ui-qcalendar';
import {
QCalendarResource,
TimestampOrNull,
today,
parseDate,
} from '@quasar/quasar-ui-qcalendar';
import { Boat, useBoatStore } from 'src/stores/boat';
import { useBookingStore } from 'src/stores/booking';
const calendar = ref();
const boatStore = useBoatStore();
const bookingStore = useBookingStore();
import { useScheduleStore } from 'src/stores/schedule';
import { date } from 'quasar';
type ResourceIntervalScope = {
resource: Boat;
intervals: [];
timeStartPosX(start: string): number;
timeStartPosX(start: TimestampOrNull): number;
timeDurationWidth(duration: number): number;
};
const statusLookup = {
tentative: ['#f2c037', 'white'],
confirmed: ['#14539a', 'white'],
pending: ['white', 'grey'],
};
const calendar = ref();
const boatStore = useBoatStore();
const scheduleStore = useScheduleStore();
const selectedDate = ref(today());
function getEvents(scope: ResourceIntervalScope) {
const resourceEvents = bookingStore.bookings[scope.resource.id];
return resourceEvents.map((event) => ({
left: scope.timeStartPosX(event.start),
width: scope.timeDurationWidth(event.duration),
title: event.title,
}));
const resourceEvents = scheduleStore.getBoatReservations(
scope.resource.id,
date.extractDate(selectedDate.value, 'YYYY-MM-DD')
);
return resourceEvents.map((event) => {
return {
left: scope.timeStartPosX(parseDate(event.start)),
width: scope.timeDurationWidth(
date.getDateDiff(event.end, event.start, 'minutes')
),
title: event.user,
status: event.status,
};
});
}
function getStyle(event: { left: number; width: number; title: string }) {
function getStyle(event: {
left: number;
width: number;
title: string;
status: 'tentative' | 'confirmed' | 'pending';
}) {
return {
position: 'absolute',
background: 'white',
background: event.status ? statusLookup[event.status][0] : 'white',
color: event.status ? statusLookup[event.status][1] : '#14539a',
left: `${event.left}px`,
width: `${event.width}px`,
height: '40px',
height: '32px',
overflow: 'hidden',
};
}
const emit = defineEmits(['onClickDate', 'onClickTime']);
function onToday() {
calendar.value.moveToToday();
}
@@ -107,28 +142,17 @@ function onPrev() {
function onNext() {
calendar.value.next();
}
function onMoved(data) {
console.log('onMoved', data);
}
function onChange(data) {
console.log('onChange', data);
}
function onResourceExpanded(data) {
console.log('onResourceExpanded', data);
}
function onClickDate(data) {
console.log('onClickDate', data);
emit('onClickDate', data);
}
function onClickTime(data) {
console.log('onClickTime', data);
}
function onClickResource(data) {
console.log('onClickResource', data);
}
function onClickHeadResources(data) {
console.log('onClickHeadResources', data);
}
function onClickInterval(data) {
console.log('onClickInterval', data);
emit('onClickTime', data);
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
const onClickInterval = () => {};
const onClickHeadResources = onClickInterval;
const onClickResource = onClickInterval;
const onResourceExpanded = onClickInterval;
const onMoved = onClickInterval;
const onChange = onClickInterval;
</script>