Many tweaks to booking form.
This commit is contained in:
@@ -1,47 +1,36 @@
|
||||
<template>
|
||||
<q-page padding>
|
||||
<q-card>
|
||||
<q-list>
|
||||
<q-form @submit="onSubmit" @reset="onReset" class="q-gutter-md">
|
||||
<q-input bottom-slots v-model="bookingForm.name" label="Name" readonly>
|
||||
<q-input
|
||||
bottom-slots
|
||||
v-model="bookingForm.name"
|
||||
label="Creating reservation for"
|
||||
readonly
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="person" />
|
||||
</template>
|
||||
</q-input>
|
||||
<q-select
|
||||
v-model="bookingForm.boat"
|
||||
:options="boats"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
label="Boat"
|
||||
<q-expansion-item
|
||||
expand-separator
|
||||
v-model="resourceView"
|
||||
icon="calendar_month"
|
||||
label="Boat and Time"
|
||||
default-opened
|
||||
:caption="bookingSummary"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-item-section avatar>
|
||||
<q-img
|
||||
v-if="bookingForm.boat?.iconsrc"
|
||||
:src="bookingForm.boat?.iconsrc"
|
||||
/>
|
||||
<q-icon v-else name="sailing" />
|
||||
</q-item-section>
|
||||
</template>
|
||||
<q-separator />
|
||||
<resource-schedule-viewer-component
|
||||
@on-click-time="onClickTime"
|
||||
@on-close-section="() => (resourceView = !resourceView)"
|
||||
@on-update-duration="
|
||||
(value) => {
|
||||
bookingForm.duration = value;
|
||||
}
|
||||
"
|
||||
/></q-expansion-item>
|
||||
|
||||
<template v-slot:option="scope">
|
||||
<q-item v-bind="scope.itemProps">
|
||||
<q-item-section avatar>
|
||||
<q-img :src="scope.opt.iconsrc" />
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label>{{ scope.opt.name }}</q-item-label>
|
||||
<q-item-label caption>{{ scope.opt.class }}</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section avatar v-if="scope.opt.defects">
|
||||
<q-icon name="warning" color="warning" />
|
||||
<q-tooltip class="bg-amber text-black shadow-7"
|
||||
>This boat has defects. Select it to see details.
|
||||
</q-tooltip>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
</q-select>
|
||||
<q-banner
|
||||
rounded
|
||||
class="bg-warning text-grey-10"
|
||||
@@ -50,7 +39,7 @@
|
||||
<template v-slot:avatar>
|
||||
<q-icon name="warning" color="grey-10" />
|
||||
</template>
|
||||
This boat currently has the following defects:
|
||||
This boat currently has the following notices:
|
||||
<ol>
|
||||
<li
|
||||
v-for="defect in bookingForm.boat.defects"
|
||||
@@ -60,145 +49,65 @@
|
||||
</li>
|
||||
</ol>
|
||||
</q-banner>
|
||||
<q-btn
|
||||
label="View Schedule"
|
||||
color="primary"
|
||||
flat
|
||||
@click="showSchedule = true"
|
||||
>
|
||||
<q-dialog
|
||||
v-model="showSchedule"
|
||||
full-width
|
||||
cover
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
>
|
||||
<q-card>
|
||||
<resource-schedule-viewer-component
|
||||
@on-click-date="onClickDate"
|
||||
@on-click-time="onClickTime"
|
||||
/>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</q-btn>
|
||||
<q-input
|
||||
v-model="bookingForm.startDate"
|
||||
label="Check-Out"
|
||||
label-color="accent"
|
||||
readonly
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="event" class="cursor-pointer"> </q-icon>
|
||||
</template>
|
||||
<q-popup-proxy
|
||||
cover
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
@before-show="startDateOrTime = true"
|
||||
>
|
||||
<q-date
|
||||
v-model="bookingForm.startDate"
|
||||
mask="ddd MMM D, YYYY h:mm A"
|
||||
:options="limitDate"
|
||||
v-if="startDateOrTime"
|
||||
>
|
||||
<div class="row items-center justify-end">
|
||||
<q-btn
|
||||
label="Next"
|
||||
color="primary"
|
||||
flat
|
||||
@click="startDateOrTime = false"
|
||||
/>
|
||||
</div>
|
||||
</q-date>
|
||||
<q-time
|
||||
v-model="bookingForm.startDate"
|
||||
mask="ddd MMM D, YYYY h:mm A"
|
||||
:minute-options="minOpts"
|
||||
v-else
|
||||
>
|
||||
<div class="row items-center justify-end">
|
||||
<q-btn v-close-popup label="Close" color="primary" flat />
|
||||
</div>
|
||||
</q-time>
|
||||
</q-popup-proxy>
|
||||
</q-input>
|
||||
<q-input
|
||||
v-model="bookingForm.endDate"
|
||||
label="Check-In"
|
||||
label-color="accent"
|
||||
readonly
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="event" class="cursor-pointer"> </q-icon>
|
||||
</template>
|
||||
<q-popup-proxy
|
||||
cover
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
@before-show="endDateOrTime = true"
|
||||
>
|
||||
<q-date
|
||||
v-model="bookingForm.startDate"
|
||||
mask="ddd MMM D, YYYY h:mm A"
|
||||
:options="limitDate"
|
||||
v-if="endDateOrTime"
|
||||
>
|
||||
<div class="row items-center justify-end">
|
||||
<q-btn v-close-popup label="Cancel" color="accent" flat />
|
||||
<q-btn
|
||||
label="Next"
|
||||
color="primary"
|
||||
flat
|
||||
@click="endDateOrTime = !endDateOrTime"
|
||||
/>
|
||||
</div>
|
||||
</q-date>
|
||||
<q-time
|
||||
v-model="bookingForm.endDate"
|
||||
mask="ddd MMM D, YYYY h:mm A"
|
||||
:minute-options="minOpts"
|
||||
v-else
|
||||
>
|
||||
<div class="row items-center justify-end">
|
||||
<q-btn v-close-popup label="Close" color="primary" flat />
|
||||
</div>
|
||||
</q-time>
|
||||
</q-popup-proxy>
|
||||
</q-input>
|
||||
<q-chip icon="timelapse"
|
||||
>Booking Duration: {{ bookingDuration }}</q-chip
|
||||
<q-expansion-item
|
||||
expand-separator
|
||||
icon="people"
|
||||
label="Crew and Passengers"
|
||||
default-opened
|
||||
>
|
||||
<q-separator />
|
||||
</q-expansion-item>
|
||||
|
||||
<q-item-section>
|
||||
<q-btn label="Submit" type="submit" color="primary" />
|
||||
</q-item-section>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-item-section> </q-form
|
||||
></q-list>
|
||||
</q-page>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue';
|
||||
import { reactive, ref, computed, watch } from 'vue';
|
||||
import { useAuthStore } from 'src/stores/auth';
|
||||
import { Boat, useBoatStore } from 'src/stores/boat';
|
||||
import { date } from 'quasar';
|
||||
import { Dialog, date } from 'quasar';
|
||||
import ResourceScheduleViewerComponent from 'src/components/ResourceScheduleViewerComponent.vue';
|
||||
import { makeDateTime } from '@quasar/quasar-ui-qcalendar';
|
||||
import { useScheduleStore, Reservation } from 'src/stores/schedule';
|
||||
|
||||
const auth = useAuthStore();
|
||||
const boats = useBoatStore().boats;
|
||||
const dateFormat = 'ddd MMM D, YYYY h:mm A';
|
||||
const startDateOrTime = ref(true);
|
||||
const endDateOrTime = ref(true);
|
||||
const showSchedule = ref(false);
|
||||
const bookingForm = ref({
|
||||
const resourceView = ref(true);
|
||||
const scheduleStore = useScheduleStore();
|
||||
const bookingForm = reactive({
|
||||
bookingId: scheduleStore.getNewId(),
|
||||
name: auth.currentUser?.name,
|
||||
boat: <Boat | undefined>undefined,
|
||||
startDate: date.formatDate(new Date(), dateFormat),
|
||||
endDate: date.formatDate(
|
||||
date.addToDate(new Date(), { hours: 2 }),
|
||||
dateFormat
|
||||
endDate: computed(() =>
|
||||
date.formatDate(
|
||||
date.addToDate(bookingForm.startDate, {
|
||||
hours: bookingForm.duration,
|
||||
}),
|
||||
dateFormat
|
||||
)
|
||||
),
|
||||
duration: 1,
|
||||
});
|
||||
|
||||
watch(bookingForm, (b, a) => {
|
||||
const newRes = <Reservation>{
|
||||
id: b.bookingId,
|
||||
user: b.name,
|
||||
resource: b.boat,
|
||||
start: date.extractDate(b.startDate, dateFormat),
|
||||
end: date.extractDate(b.endDate, dateFormat),
|
||||
reservationDate: new Date(),
|
||||
status: 'tentative',
|
||||
};
|
||||
//TODO: Turn this into a validator.
|
||||
scheduleStore.isOverlapped(newRes)
|
||||
? Dialog.create({ message: 'This booking overlaps another!' })
|
||||
: scheduleStore.addOrCreateReservation(newRes);
|
||||
});
|
||||
|
||||
const onReset = () => {
|
||||
@@ -209,22 +118,18 @@ const onSubmit = () => {
|
||||
// TODO
|
||||
};
|
||||
|
||||
const onClickDate = (data) => {
|
||||
console.log(data);
|
||||
};
|
||||
const onClickTime = (data) => {
|
||||
bookingForm.value.boat = data.scope.resource;
|
||||
bookingForm.value.startDate = date.formatDate(
|
||||
bookingForm.boat = data.scope.resource;
|
||||
bookingForm.startDate = date.formatDate(
|
||||
date.addToDate(makeDateTime(data.scope.timestamp), { hours: 5 }), // A terrible hack to convert back to EST. TODO: FIX!!!!
|
||||
dateFormat
|
||||
);
|
||||
showSchedule.value = false;
|
||||
console.log(bookingForm.value.startDate);
|
||||
console.log(bookingForm.startDate);
|
||||
};
|
||||
const bookingDuration = computed(() => {
|
||||
const diff = date.getDateDiff(
|
||||
bookingForm.value.endDate,
|
||||
bookingForm.value.startDate,
|
||||
bookingForm.endDate,
|
||||
bookingForm.startDate,
|
||||
'minutes'
|
||||
);
|
||||
return diff <= 0
|
||||
@@ -233,6 +138,12 @@ const bookingDuration = computed(() => {
|
||||
(diff % 60 > 0 ? ' ' + (diff % 60) + ' minutes' : '');
|
||||
});
|
||||
|
||||
const bookingSummary = computed(() => {
|
||||
return bookingForm.boat && bookingForm.startDate && bookingForm.endDate
|
||||
? `${bookingForm.boat.name} @ ${bookingForm.startDate} for ${bookingDuration.value}`
|
||||
: '';
|
||||
});
|
||||
|
||||
const limitDate = (startDate: string) => {
|
||||
return date.isBetweenDates(
|
||||
startDate,
|
||||
@@ -241,6 +152,4 @@ const limitDate = (startDate: string) => {
|
||||
{ inclusiveFrom: true, inclusiveTo: true, onlyDate: true }
|
||||
);
|
||||
};
|
||||
|
||||
const minOpts = [0, 15, 30, 45, 60];
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user