All checks were successful
Build BAB Application Deployment Artifact / build (push) Successful in 1m57s
202 lines
6.1 KiB
Vue
202 lines
6.1 KiB
Vue
<template>
|
|
<q-page>
|
|
<q-list>
|
|
<q-form @submit="onSubmit" @reset="onReset" class="q-gutter-sm">
|
|
<q-item>
|
|
<q-item-section :avatar="true">
|
|
<q-icon name="person"
|
|
/></q-item-section>
|
|
<q-item-section>
|
|
<q-item-label> Name: {{ bookingForm.name }} </q-item-label>
|
|
</q-item-section>
|
|
</q-item>
|
|
<q-expansion-item
|
|
expand-separator
|
|
v-model="resourceView"
|
|
icon="calendar_month"
|
|
label="Boat and Time"
|
|
default-opened
|
|
class="q-mt-none"
|
|
:caption="bookingSummary"
|
|
>
|
|
<q-separator />
|
|
<q-banner :class="$q.dark.isActive ? 'bg-grey-9' : 'bg-grey-3'">
|
|
Use the calendar to pick a date. Select an available boat and
|
|
timeslot below.
|
|
</q-banner>
|
|
<BoatScheduleTableComponent v-model="interval" />
|
|
|
|
<q-banner
|
|
rounded
|
|
class="bg-warning text-grey-10"
|
|
style="max-width: 95vw; margin: auto"
|
|
v-if="bookingForm.boat && bookingForm.boat.defects.length > 0"
|
|
>
|
|
<template v-slot:avatar>
|
|
<q-icon name="warning" color="grey-10" />
|
|
</template>
|
|
{{ bookingForm.boat.name }} currently has the following notices:
|
|
<ol>
|
|
<li
|
|
v-for="defect in bookingForm.boat.defects"
|
|
:key="defect.description"
|
|
>
|
|
{{ defect.description }}
|
|
</li>
|
|
</ol>
|
|
</q-banner>
|
|
<!-- <q-card-section>
|
|
<q-btn
|
|
color="primary"
|
|
class="full-width"
|
|
icon="keyboard_arrow_down"
|
|
icon-right="keyboard_arrow_down"
|
|
label="Next: Crew & Passengers"
|
|
@click="resourceView = false"
|
|
/></q-card-section> -->
|
|
</q-expansion-item>
|
|
<!-- <q-expansion-item
|
|
expand-separator
|
|
icon="people"
|
|
label="Crew and Passengers"
|
|
default-opened
|
|
><q-banner v-if="bookingForm.boat"
|
|
>Passengers:
|
|
{{ bookingForm.members.length + bookingForm.guests.length }} /
|
|
{{ bookingForm.boat.maxPassengers }}</q-banner
|
|
>
|
|
<q-item
|
|
class="q-my-sm"
|
|
v-for="passenger in [...bookingForm.members, ...bookingForm.guests]"
|
|
:key="passenger.name"
|
|
>
|
|
<q-item-section avatar>
|
|
<q-avatar color="primary" text-color="white" size="sm">
|
|
{{
|
|
passenger.name
|
|
.split(' ')
|
|
.map((i) => i.charAt(0))
|
|
.join('')
|
|
.toUpperCase()
|
|
}}
|
|
</q-avatar>
|
|
</q-item-section>
|
|
<q-item-section>{{ passenger.name }}</q-item-section>
|
|
<q-item-section side>
|
|
<q-btn color="negative" flat dense round icon="cancel" />
|
|
</q-item-section>
|
|
</q-item>
|
|
<q-separator />
|
|
</q-expansion-item> -->
|
|
|
|
<q-item-section>
|
|
<q-btn label="Submit" type="submit" color="primary" />
|
|
</q-item-section> </q-form
|
|
></q-list>
|
|
</q-page>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, computed, watch } from 'vue';
|
|
import { useAuthStore } from 'src/stores/auth';
|
|
import { Boat, useBoatStore } from 'src/stores/boat';
|
|
import { date, useQuasar } from 'quasar';
|
|
import { Interval, Reservation } from 'src/stores/schedule.types';
|
|
import BoatScheduleTableComponent from 'src/components/scheduling/boat/BoatScheduleTableComponent.vue';
|
|
import { getNewId } from 'src/utils/misc';
|
|
import { useRouter } from 'vue-router';
|
|
import { useReservationStore } from 'src/stores/reservation';
|
|
|
|
interface BookingForm {
|
|
bookingId: string;
|
|
name?: string;
|
|
boat?: Boat;
|
|
startDate?: string;
|
|
endDate?: string;
|
|
members: { name: string }[];
|
|
guests: { name: string }[];
|
|
}
|
|
|
|
const auth = useAuthStore();
|
|
const dateFormat = 'MMM D, YYYY h:mm A';
|
|
const resourceView = ref(true);
|
|
const interval = ref<Interval>();
|
|
const bookingForm = ref<BookingForm>({
|
|
bookingId: getNewId(),
|
|
name: auth.currentUser?.name,
|
|
boat: <Boat | undefined>undefined,
|
|
startDate: date.formatDate(new Date(), dateFormat),
|
|
endDate: date.formatDate(new Date(), dateFormat),
|
|
members: [{ name: 'Karen Henrikso' }, { name: "Rich O'hare" }],
|
|
guests: [{ name: 'Bob Barker' }, { name: 'Taylor Swift' }],
|
|
});
|
|
const router = useRouter();
|
|
const reservationStore = useReservationStore();
|
|
const $q = useQuasar();
|
|
|
|
watch(interval, (new_interval) => {
|
|
bookingForm.value.boat = useBoatStore().boats.find(
|
|
(b) => b.$id === new_interval?.boatId
|
|
);
|
|
bookingForm.value.startDate = date.formatDate(
|
|
new_interval?.start,
|
|
dateFormat
|
|
);
|
|
bookingForm.value.endDate = date.formatDate(new_interval?.end, dateFormat);
|
|
});
|
|
|
|
const onReset = () => {
|
|
// TODO
|
|
};
|
|
|
|
const onSubmit = () => {
|
|
const booking = bookingForm.value;
|
|
if (
|
|
!(booking.boat && booking.startDate && booking.endDate && auth.currentUser)
|
|
) {
|
|
// TODO: Make a proper validator
|
|
return;
|
|
}
|
|
const reservation = <Reservation>{
|
|
resource: booking.boat.$id,
|
|
start: booking.startDate,
|
|
end: booking.endDate,
|
|
user: auth.currentUser.$id,
|
|
status: 'confirmed',
|
|
};
|
|
// TODO: Fix this. It will always look successful
|
|
reservationStore.createReservation(reservation);
|
|
$q.notify({
|
|
color: 'green-4',
|
|
textColor: 'white',
|
|
icon: 'cloud_done',
|
|
message: 'Submitted',
|
|
});
|
|
router.go(-1);
|
|
};
|
|
|
|
const bookingDuration = computed(() => {
|
|
if (bookingForm.value.endDate && bookingForm.value.startDate) {
|
|
const diff = date.getDateDiff(
|
|
bookingForm.value.endDate,
|
|
bookingForm.value.startDate,
|
|
'minutes'
|
|
);
|
|
return diff <= 0
|
|
? 'Invalid'
|
|
: (diff > 60 ? Math.trunc(diff / 60) + ' hours' : '') +
|
|
(diff % 60 > 0 ? ' ' + (diff % 60) + ' minutes' : '');
|
|
} else {
|
|
return 0;
|
|
}
|
|
});
|
|
|
|
const bookingSummary = computed(() => {
|
|
return bookingForm.value.boat &&
|
|
bookingForm.value.startDate &&
|
|
bookingForm.value.endDate
|
|
? `${bookingForm.value.boat.name} @ ${bookingForm.value.startDate} for ${bookingDuration.value}`
|
|
: '';
|
|
});
|
|
</script>
|