Many esthetic changes
This commit is contained in:
@@ -1,9 +0,0 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"semi": true
|
||||
}
|
||||
@@ -48,7 +48,7 @@ module.exports = configure(function (/* ctx */) {
|
||||
|
||||
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#build
|
||||
build: {
|
||||
env: require('dotenv').config({ path: '.env.local' }).parsed,
|
||||
env: require('dotenv').config().parsed,
|
||||
target: {
|
||||
browser: ['es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1'],
|
||||
node: 'node16',
|
||||
|
||||
@@ -1,64 +1,78 @@
|
||||
<template>
|
||||
<div>
|
||||
<CalendarHeaderComponent v-model="selectedDate" />
|
||||
<div class="boat-schedule-table-component">
|
||||
<QCalendarDay
|
||||
ref="calendar"
|
||||
class="q-pa-xs"
|
||||
flat
|
||||
animated
|
||||
dense
|
||||
:disabled-before="disabledBefore"
|
||||
interval-height="24"
|
||||
interval-count="18"
|
||||
interval-start="06:00"
|
||||
:short-interval-label="true"
|
||||
v-model="selectedDate"
|
||||
:column-count="boats.length"
|
||||
v-touch-swipe.left.right="handleSwipe"
|
||||
>
|
||||
<template #head-day="{ scope }">
|
||||
<div style="text-align: center; font-weight: 800">
|
||||
{{ getBoatDisplayName(scope) }}
|
||||
</div>
|
||||
</template>
|
||||
<q-card>
|
||||
<q-toolbar>
|
||||
<q-toolbar-title>Select a Boat and Time</q-toolbar-title>
|
||||
<q-btn icon="close" flat round dense v-close-popup />
|
||||
</q-toolbar>
|
||||
<q-separator />
|
||||
<CalendarHeaderComponent v-model="selectedDate" />
|
||||
<div class="boat-schedule-table-component">
|
||||
<QCalendarDay
|
||||
ref="calendar"
|
||||
class="q-pa-xs"
|
||||
flat
|
||||
animated
|
||||
dense
|
||||
:disabled-before="disabledBefore"
|
||||
interval-height="24"
|
||||
interval-count="18"
|
||||
interval-start="06:00"
|
||||
:short-interval-label="true"
|
||||
v-model="selectedDate"
|
||||
:column-count="boats.length"
|
||||
v-touch-swipe.left.right="handleSwipe"
|
||||
>
|
||||
<template #head-day="{ scope }">
|
||||
<div style="text-align: center; font-weight: 800">
|
||||
{{ getBoatDisplayName(scope) }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #day-body="{ scope }">
|
||||
<div v-for="block in getBoatBlocks(scope)" :key="block.$id">
|
||||
<div
|
||||
class="timeblock"
|
||||
:class="selectedBlock?.$id === block.$id ? 'selected' : ''"
|
||||
:style="
|
||||
blockStyles(block, scope.timeStartPos, scope.timeDurationHeight)
|
||||
"
|
||||
:id="block.id"
|
||||
@click="selectBlock($event, scope, block)"
|
||||
>
|
||||
{{ boats[scope.columnIndex].name }}<br />
|
||||
{{ selectedBlock?.$id === block.$id ? 'Selected' : 'Available' }}
|
||||
<template #day-body="{ scope }">
|
||||
<div v-for="block in getBoatBlocks(scope)" :key="block.$id">
|
||||
<div
|
||||
class="timeblock"
|
||||
:class="selectedBlock?.$id === block.$id ? 'selected' : ''"
|
||||
:style="
|
||||
blockStyles(
|
||||
block,
|
||||
scope.timeStartPos,
|
||||
scope.timeDurationHeight
|
||||
)
|
||||
"
|
||||
:id="block.id"
|
||||
@click="selectBlock($event, scope, block)"
|
||||
v-close-popup
|
||||
>
|
||||
{{ boats[scope.columnIndex].name }}<br />
|
||||
{{
|
||||
selectedBlock?.$id === block.$id ? 'Selected' : 'Available'
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-for="reservation in getBoatReservations(scope)"
|
||||
:key="reservation.$id"
|
||||
>
|
||||
<div
|
||||
class="reservation"
|
||||
:style="
|
||||
reservationStyles(
|
||||
reservation,
|
||||
scope.timeStartPos,
|
||||
scope.timeDurationHeight
|
||||
)
|
||||
"
|
||||
v-for="reservation in getBoatReservations(scope)"
|
||||
:key="reservation.$id"
|
||||
>
|
||||
{{ getUserName(reservation.user) || 'loading...' }}<br />
|
||||
{{ reservation.reason }}
|
||||
<div
|
||||
class="reservation"
|
||||
:style="
|
||||
reservationStyles(
|
||||
reservation,
|
||||
scope.timeStartPos,
|
||||
scope.timeDurationHeight
|
||||
)
|
||||
"
|
||||
>
|
||||
{{ getUserName(reservation.user) || 'loading...' }}<br />
|
||||
<q-chip icon="key">{{ reservation.reason }}</q-chip>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</QCalendarDay>
|
||||
</div>
|
||||
</template>
|
||||
</QCalendarDay>
|
||||
</div></q-card
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,92 +1,119 @@
|
||||
<template>
|
||||
<q-page>
|
||||
<q-list>
|
||||
<q-form @reset="onReset" class="q-gutter-sm">
|
||||
<div class="q-pa-md row q-gutter-sm">
|
||||
<q-card
|
||||
flat
|
||||
bordered
|
||||
class="col-md-4 col-sm-8 col-xs-12">
|
||||
<q-card-section>
|
||||
<div class="text-h5 q-mt-none q-mb-xs">New Booking</div>
|
||||
<div class="text-caption text-grey-8">for: {{ bookingForm.name }}</div>
|
||||
</q-card-section>
|
||||
<q-separator />
|
||||
<q-item
|
||||
clickable
|
||||
@click="boatSelect = true">
|
||||
<q-item-section avatar>
|
||||
<q-icon
|
||||
color="primary"
|
||||
name="event" />
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-card v-if="bookingForm.boat">
|
||||
<q-card-section>
|
||||
<q-img
|
||||
:src="bookingForm.boat?.imgSrc"
|
||||
:fit="'scale-down'">
|
||||
<div class="row absolute-top">
|
||||
<div class="col text-h6 text-left">
|
||||
{{ bookingForm.boat?.name }}
|
||||
</div>
|
||||
<div class="col text-right">
|
||||
{{ bookingForm.boat?.class }}
|
||||
</div>
|
||||
</div>
|
||||
</q-img>
|
||||
</q-card-section>
|
||||
<q-separator />
|
||||
<q-card-section class="q-py-none">
|
||||
<q-list
|
||||
dense
|
||||
class="row">
|
||||
<q-item>
|
||||
<q-item-section avatar>
|
||||
<q-badge
|
||||
outline
|
||||
color="primary"
|
||||
label="Start" />
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
{{
|
||||
date.formatDate(
|
||||
new Date(bookingForm.startDate as string),
|
||||
'ddd MMM Do @ hh:mm A'
|
||||
)
|
||||
}}
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item class="q-ma-none">
|
||||
<q-item-section avatar>
|
||||
<q-badge
|
||||
outline
|
||||
color="primary"
|
||||
label="End" />
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
{{
|
||||
date.formatDate(
|
||||
new Date(bookingForm.endDate as string),
|
||||
'ddd MMM Do @ hh:mm A'
|
||||
)
|
||||
}}
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
<div v-else>Tap to Select a Boat / Time</div>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-list dense>
|
||||
<q-item>
|
||||
<q-item-section :avatar="true">
|
||||
<q-icon name="person"
|
||||
/></q-item-section>
|
||||
<q-item-section avatar>
|
||||
<q-icon
|
||||
color="primary"
|
||||
name="category" />
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label> Name: {{ bookingForm.name }} </q-item-label>
|
||||
<q-select
|
||||
filled
|
||||
v-model="bookingForm.reason"
|
||||
:options="reason_options"
|
||||
label="Reason for sail" />
|
||||
</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: Booking Details"
|
||||
@click="resourceView = false"
|
||||
/></q-card-section>
|
||||
</q-expansion-item>
|
||||
<q-expansion-item
|
||||
expand-separator
|
||||
icon="people"
|
||||
label="Booking Details"
|
||||
default-opened
|
||||
>
|
||||
<div class="row">
|
||||
<div class="col-auto">
|
||||
<q-select
|
||||
filled
|
||||
v-model="bookingForm.reason"
|
||||
:options="reason_options"
|
||||
label="Reason for sail"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-expansion-item>
|
||||
|
||||
<q-item-section>
|
||||
<q-btn
|
||||
label="Submit"
|
||||
type="submit"
|
||||
@click="onSubmit"
|
||||
color="primary"
|
||||
/>
|
||||
</q-item-section> </q-form
|
||||
></q-list>
|
||||
</q-page>
|
||||
</q-list>
|
||||
<q-card-actions align="right">
|
||||
<q-btn
|
||||
label="Reset"
|
||||
@click="onReset"
|
||||
color="secondary"
|
||||
size="md" />
|
||||
<q-btn
|
||||
label="Submit"
|
||||
@click="onSubmit"
|
||||
color="primary" />
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
<q-dialog
|
||||
v-model="boatSelect"
|
||||
full-width>
|
||||
<BoatScheduleTableComponent v-model="interval" />
|
||||
</q-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import { ref, watch } from 'vue';
|
||||
import { useAuthStore } from 'src/stores/auth';
|
||||
import { Boat, useBoatStore } from 'src/stores/boat';
|
||||
import { date, useQuasar } from 'quasar';
|
||||
@@ -110,9 +137,8 @@ interface BookingForm {
|
||||
const reason_options = ['Open Sail', 'Private Sail', 'Racing', 'Other'];
|
||||
|
||||
const auth = useAuthStore();
|
||||
const resourceView = ref(true);
|
||||
const interval = ref<Interval>();
|
||||
const bookingForm = ref<BookingForm>({
|
||||
const newForm = {
|
||||
bookingId: getNewId(),
|
||||
name: auth.currentUser?.name,
|
||||
boat: <Boat | undefined>undefined,
|
||||
@@ -121,10 +147,12 @@ const bookingForm = ref<BookingForm>({
|
||||
reason: 'Open Sail',
|
||||
members: [],
|
||||
guests: [],
|
||||
});
|
||||
};
|
||||
const bookingForm = ref<BookingForm>({ ...newForm });
|
||||
const router = useRouter();
|
||||
const reservationStore = useReservationStore();
|
||||
const $q = useQuasar();
|
||||
const boatSelect = ref(false);
|
||||
|
||||
watch(interval, (new_interval) => {
|
||||
bookingForm.value.boat = useBoatStore().boats.find(
|
||||
@@ -135,9 +163,8 @@ watch(interval, (new_interval) => {
|
||||
});
|
||||
|
||||
const onReset = () => {
|
||||
// TODO
|
||||
bookingForm.value = { ...newForm };
|
||||
};
|
||||
|
||||
const onSubmit = () => {
|
||||
console.log('SUBMIT!');
|
||||
const booking = bookingForm.value;
|
||||
@@ -166,30 +193,4 @@ const onSubmit = () => {
|
||||
});
|
||||
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} @ ${new Date(
|
||||
bookingForm.value.startDate
|
||||
).toLocaleString()} for ${bookingDuration.value}`
|
||||
: '';
|
||||
});
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user