Many esthetic changes

This commit is contained in:
2024-05-22 17:18:02 -04:00
parent cd692a6f3b
commit 55bc1acbb3
5 changed files with 182 additions and 180 deletions

View File

@@ -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

View File

@@ -1,4 +0,0 @@
{
"singleQuote": true,
"semi": true
}

View File

@@ -48,7 +48,7 @@ module.exports = configure(function (/* ctx */) {
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#build // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#build
build: { build: {
env: require('dotenv').config({ path: '.env.local' }).parsed, env: require('dotenv').config().parsed,
target: { target: {
browser: ['es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1'], browser: ['es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1'],
node: 'node16', node: 'node16',

View File

@@ -1,64 +1,78 @@
<template> <template>
<div> <div>
<CalendarHeaderComponent v-model="selectedDate" /> <q-card>
<div class="boat-schedule-table-component"> <q-toolbar>
<QCalendarDay <q-toolbar-title>Select a Boat and Time</q-toolbar-title>
ref="calendar" <q-btn icon="close" flat round dense v-close-popup />
class="q-pa-xs" </q-toolbar>
flat <q-separator />
animated <CalendarHeaderComponent v-model="selectedDate" />
dense <div class="boat-schedule-table-component">
:disabled-before="disabledBefore" <QCalendarDay
interval-height="24" ref="calendar"
interval-count="18" class="q-pa-xs"
interval-start="06:00" flat
:short-interval-label="true" animated
v-model="selectedDate" dense
:column-count="boats.length" :disabled-before="disabledBefore"
v-touch-swipe.left.right="handleSwipe" interval-height="24"
> interval-count="18"
<template #head-day="{ scope }"> interval-start="06:00"
<div style="text-align: center; font-weight: 800"> :short-interval-label="true"
{{ getBoatDisplayName(scope) }} v-model="selectedDate"
</div> :column-count="boats.length"
</template> 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 }"> <template #day-body="{ scope }">
<div v-for="block in getBoatBlocks(scope)" :key="block.$id"> <div v-for="block in getBoatBlocks(scope)" :key="block.$id">
<div <div
class="timeblock" class="timeblock"
:class="selectedBlock?.$id === block.$id ? 'selected' : ''" :class="selectedBlock?.$id === block.$id ? 'selected' : ''"
:style=" :style="
blockStyles(block, scope.timeStartPos, scope.timeDurationHeight) blockStyles(
" block,
:id="block.id" scope.timeStartPos,
@click="selectBlock($event, scope, block)" scope.timeDurationHeight
> )
{{ boats[scope.columnIndex].name }}<br /> "
{{ selectedBlock?.$id === block.$id ? 'Selected' : 'Available' }} :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>
<div
v-for="reservation in getBoatReservations(scope)"
:key="reservation.$id"
>
<div <div
class="reservation" v-for="reservation in getBoatReservations(scope)"
:style=" :key="reservation.$id"
reservationStyles(
reservation,
scope.timeStartPos,
scope.timeDurationHeight
)
"
> >
{{ getUserName(reservation.user) || 'loading...' }}<br /> <div
{{ reservation.reason }} 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>
</div> </template>
</template> </QCalendarDay>
</QCalendarDay> </div></q-card
</div> >
</div> </div>
</template> </template>

View File

@@ -1,92 +1,119 @@
<template> <template>
<q-page> <div class="q-pa-md row q-gutter-sm">
<q-list> <q-card
<q-form @reset="onReset" class="q-gutter-sm"> 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>
<q-item-section :avatar="true"> <q-item-section avatar>
<q-icon name="person" <q-icon
/></q-item-section> color="primary"
name="category" />
</q-item-section>
<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-section>
</q-item> </q-item>
<q-expansion-item </q-list>
expand-separator <q-card-actions align="right">
v-model="resourceView" <q-btn
icon="calendar_month" label="Reset"
label="Boat and Time" @click="onReset"
default-opened color="secondary"
class="q-mt-none" size="md" />
:caption="bookingSummary" <q-btn
> label="Submit"
<q-separator /> @click="onSubmit"
<q-banner :class="$q.dark.isActive ? 'bg-grey-9' : 'bg-grey-3'"> color="primary" />
Use the calendar to pick a date. Select an available boat and </q-card-actions>
timeslot below. </q-card>
</q-banner> <q-dialog
<BoatScheduleTableComponent v-model="interval" /> v-model="boatSelect"
full-width>
<q-banner <BoatScheduleTableComponent v-model="interval" />
rounded </q-dialog>
class="bg-warning text-grey-10" </div>
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>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue'; import { ref, watch } from 'vue';
import { useAuthStore } from 'src/stores/auth'; import { useAuthStore } from 'src/stores/auth';
import { Boat, useBoatStore } from 'src/stores/boat'; import { Boat, useBoatStore } from 'src/stores/boat';
import { date, useQuasar } from 'quasar'; import { date, useQuasar } from 'quasar';
@@ -110,9 +137,8 @@ interface BookingForm {
const reason_options = ['Open Sail', 'Private Sail', 'Racing', 'Other']; const reason_options = ['Open Sail', 'Private Sail', 'Racing', 'Other'];
const auth = useAuthStore(); const auth = useAuthStore();
const resourceView = ref(true);
const interval = ref<Interval>(); const interval = ref<Interval>();
const bookingForm = ref<BookingForm>({ const newForm = {
bookingId: getNewId(), bookingId: getNewId(),
name: auth.currentUser?.name, name: auth.currentUser?.name,
boat: <Boat | undefined>undefined, boat: <Boat | undefined>undefined,
@@ -121,10 +147,12 @@ const bookingForm = ref<BookingForm>({
reason: 'Open Sail', reason: 'Open Sail',
members: [], members: [],
guests: [], guests: [],
}); };
const bookingForm = ref<BookingForm>({ ...newForm });
const router = useRouter(); const router = useRouter();
const reservationStore = useReservationStore(); const reservationStore = useReservationStore();
const $q = useQuasar(); const $q = useQuasar();
const boatSelect = ref(false);
watch(interval, (new_interval) => { watch(interval, (new_interval) => {
bookingForm.value.boat = useBoatStore().boats.find( bookingForm.value.boat = useBoatStore().boats.find(
@@ -135,9 +163,8 @@ watch(interval, (new_interval) => {
}); });
const onReset = () => { const onReset = () => {
// TODO bookingForm.value = { ...newForm };
}; };
const onSubmit = () => { const onSubmit = () => {
console.log('SUBMIT!'); console.log('SUBMIT!');
const booking = bookingForm.value; const booking = bookingForm.value;
@@ -166,30 +193,4 @@ const onSubmit = () => {
}); });
router.go(-1); 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> </script>