UI Enhancements
This commit is contained in:
@@ -118,7 +118,6 @@ async function login(email: string, password: string) {
|
||||
spinner: false,
|
||||
icon: 'check_circle',
|
||||
});
|
||||
console.log('Redirecting to index page');
|
||||
appRouter.replace({ name: 'index' });
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof AppwriteException) {
|
||||
|
||||
@@ -163,6 +163,7 @@ watch(reservation, (newReservation) => {
|
||||
} else {
|
||||
const updatedReservation = {
|
||||
...newReservation,
|
||||
user: auth.currentUser?.$id,
|
||||
interval: {
|
||||
start: newReservation.start,
|
||||
end: newReservation.end,
|
||||
@@ -191,7 +192,6 @@ const bookingName = computed(() =>
|
||||
|
||||
const boat = computed((): Boat | null => {
|
||||
const boatId = bookingForm.value.interval?.resource;
|
||||
console.log('Boat Lookup:', boatId);
|
||||
return boatStore.getBoatById(boatId);
|
||||
});
|
||||
|
||||
|
||||
@@ -12,21 +12,20 @@
|
||||
max-width: 350px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
"
|
||||
>
|
||||
">
|
||||
<span
|
||||
class="q-button"
|
||||
style="cursor: pointer; user-select: none"
|
||||
@click="onPrev"
|
||||
><</span
|
||||
>
|
||||
@click="onPrev">
|
||||
<
|
||||
</span>
|
||||
{{ formattedMonth }}
|
||||
<span
|
||||
class="q-button"
|
||||
style="cursor: pointer; user-select: none"
|
||||
@click="onNext"
|
||||
>></span
|
||||
>
|
||||
@click="onNext">
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -35,8 +34,7 @@
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
"
|
||||
>
|
||||
">
|
||||
<div style="display: flex; width: 100%">
|
||||
<q-calendar-month
|
||||
ref="calendar"
|
||||
@@ -48,10 +46,10 @@
|
||||
date-type="rounded"
|
||||
@change="onChange"
|
||||
@moved="onMoved"
|
||||
@click-date="onClickDate"
|
||||
/>
|
||||
</div></div
|
||||
></q-card-section>
|
||||
@click-date="onClickDate" />
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-calendar-resource
|
||||
v-model="selectedDate"
|
||||
:model-resources="boatStore.boats"
|
||||
@@ -73,18 +71,25 @@
|
||||
@click-time="onClickTime"
|
||||
@click-resource="onClickResource"
|
||||
@click-head-resources="onClickHeadResources"
|
||||
@click-interval="onClickInterval"
|
||||
>
|
||||
@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
|
||||
v-for="(event, index) in getEvents(scope)"
|
||||
:key="index">
|
||||
<q-badge
|
||||
outline
|
||||
:label="event.title"
|
||||
:style="getStyle(event)" />
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template #resource-label="{ scope: { resource } }">
|
||||
<div class="col-12 .col-md-auto">
|
||||
{{ resource.displayName }}
|
||||
<q-icon v-if="resource.defects" name="warning" color="warning" />
|
||||
<q-icon
|
||||
v-if="resource.defects"
|
||||
name="warning"
|
||||
color="warning" />
|
||||
</div>
|
||||
</template>
|
||||
</q-calendar-resource>
|
||||
@@ -97,9 +102,10 @@
|
||||
dense
|
||||
@update:model-value="onUpdateDuration"
|
||||
label="Duration (hours)"
|
||||
stack-label
|
||||
><template v-slot:append><q-icon name="timelapse" /></template></q-select
|
||||
></q-card-section>
|
||||
stack-label>
|
||||
<template v-slot:append><q-icon name="timelapse" /></template>
|
||||
</q-select>
|
||||
</q-card-section>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
@@ -117,6 +123,8 @@ import { useReservationStore } from 'src/stores/reservation';
|
||||
import { date } from 'quasar';
|
||||
import { computed } from 'vue';
|
||||
import type { StatusTypes } from 'src/stores/schedule.types';
|
||||
import { useIntervalStore } from 'src/stores/interval';
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
interface EventData {
|
||||
event: object;
|
||||
@@ -146,7 +154,7 @@ const statusLookup = {
|
||||
const calendar = ref();
|
||||
const boatStore = useBoatStore();
|
||||
const reservationStore = useReservationStore();
|
||||
const selectedDate = ref(today());
|
||||
const { selectedDate } = storeToRefs(useIntervalStore());
|
||||
const duration = ref(1);
|
||||
|
||||
const formattedMonth = computed(() => {
|
||||
|
||||
@@ -4,8 +4,24 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import BoatReservationComponent from 'src/components/BoatReservationComponent.vue';
|
||||
import { Reservation } from 'src/stores/schedule.types';
|
||||
import { useIntervalStore } from 'src/stores/interval';
|
||||
import { Interval, Reservation } from 'src/stores/schedule.types';
|
||||
import { ref } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
const $route = useRoute();
|
||||
const newReservation = ref<Reservation>();
|
||||
|
||||
if (typeof $route.query.interval === 'string') {
|
||||
useIntervalStore()
|
||||
.fetchInterval($route.query.interval)
|
||||
.then(
|
||||
(interval: Interval) =>
|
||||
(newReservation.value = <Reservation>{
|
||||
resource: interval.resource,
|
||||
start: interval.start,
|
||||
end: interval.end,
|
||||
})
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
<template>
|
||||
<q-page>
|
||||
<q-card class="row">
|
||||
<div class="col">
|
||||
<navigation-bar
|
||||
@today="onToday"
|
||||
@prev="onPrev"
|
||||
@next="onNext" />
|
||||
</div>
|
||||
<div class="col q-ma-sm">
|
||||
<q-calendar-scheduler
|
||||
ref="calendar"
|
||||
v-model="selectedDate"
|
||||
@@ -16,14 +18,8 @@
|
||||
v-touch-swipe.mouse.left.right="handleSwipe"
|
||||
:max-days="$q.screen.lt.sm ? 3 : 7"
|
||||
animated
|
||||
style="--calendar-resources-width: 2em"
|
||||
day-min-height="50px"
|
||||
@change="onChange"
|
||||
@moved="onMoved"
|
||||
@click-date="onClickDate"
|
||||
@click-time="onClickTime"
|
||||
@click-interval="onClickInterval"
|
||||
@click-head-day="onClickHeadDay">
|
||||
bordered
|
||||
style="--calendar-resources-width: 40px">
|
||||
<template #day="{ scope }">
|
||||
<div
|
||||
v-for="interval in getSortedIntervals(
|
||||
@@ -31,12 +27,15 @@
|
||||
scope.resource
|
||||
)"
|
||||
:key="interval.$id"
|
||||
class="row q-pb-xs">
|
||||
class="q-pb-xs row"
|
||||
@click="createReservationFromInterval(interval)">
|
||||
<q-badge
|
||||
multi-line
|
||||
class="col-12"
|
||||
:class="!interval.user ? 'cursor-pointer' : null"
|
||||
class="col-12 q-pa-sm"
|
||||
:transparent="interval.user != undefined"
|
||||
:color="interval.user ? 'secondary' : 'primary'"
|
||||
:outline="!interval.user"
|
||||
:id="interval.id">
|
||||
{{
|
||||
interval.user
|
||||
@@ -44,12 +43,14 @@
|
||||
: 'Available'
|
||||
}}
|
||||
<br />
|
||||
{{ formatTime(interval.start) }} - {{ formatTime(interval.end) }}
|
||||
{{ formatTime(interval.start) }} to
|
||||
<br />
|
||||
{{ formatTime(interval.end) }}
|
||||
</q-badge>
|
||||
</div>
|
||||
</template>
|
||||
</q-calendar-scheduler>
|
||||
</q-card>
|
||||
</div>
|
||||
</q-page>
|
||||
</template>
|
||||
|
||||
@@ -59,7 +60,7 @@ import { ref } from 'vue';
|
||||
import { useAuthStore } from 'src/stores/auth';
|
||||
|
||||
const reservationStore = useReservationStore();
|
||||
import { getDate, today } from '@quasar/quasar-ui-qcalendar';
|
||||
import { getDate } from '@quasar/quasar-ui-qcalendar';
|
||||
import { QCalendarScheduler } from '@quasar/quasar-ui-qcalendar';
|
||||
import { Timestamp } from '@quasar/quasar-ui-qcalendar';
|
||||
import { Boat, useBoatStore } from 'src/stores/boat';
|
||||
@@ -68,12 +69,15 @@ import { useQuasar } from 'quasar';
|
||||
import { formatTime } from 'src/utils/schedule';
|
||||
import { useIntervalStore } from 'src/stores/interval';
|
||||
import { Interval } from 'src/stores/schedule.types';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
const selectedDate = ref(today());
|
||||
const boatStore = useBoatStore();
|
||||
const calendar = ref();
|
||||
const $q = useQuasar();
|
||||
const $router = useRouter();
|
||||
const { getAvailableIntervals } = useIntervalStore();
|
||||
const { selectedDate } = storeToRefs(useIntervalStore());
|
||||
|
||||
// interface DayScope {
|
||||
// timestamp: Timestamp;
|
||||
@@ -111,6 +115,13 @@ const getSortedIntervals = (timestamp: Timestamp, boat?: Boat): Interval[] => {
|
||||
// return s;
|
||||
// }
|
||||
|
||||
const createReservationFromInterval = (interval: Interval) => {
|
||||
$router.push({
|
||||
name: 'reserve-boat',
|
||||
query: { interval: interval.$id },
|
||||
});
|
||||
};
|
||||
|
||||
function handleSwipe({ ...event }) {
|
||||
event.direction === 'right' ? calendar.value?.prev() : calendar.value?.next();
|
||||
}
|
||||
@@ -124,24 +135,6 @@ function boatReservationEvents(
|
||||
(resource as Boat).$id
|
||||
);
|
||||
}
|
||||
function onMoved(data: Event) {
|
||||
console.log('onMoved', data);
|
||||
}
|
||||
function onChange(data: Event) {
|
||||
console.log('onChange', data);
|
||||
}
|
||||
function onClickDate(data: Event) {
|
||||
console.log('onClickDate', data);
|
||||
}
|
||||
function onClickTime(data: Event) {
|
||||
console.log('onClickTime', data);
|
||||
}
|
||||
function onClickInterval(data: Event) {
|
||||
console.log('onClickInterval', data);
|
||||
}
|
||||
function onClickHeadDay(data: Event) {
|
||||
console.log('onClickHeadDay', data);
|
||||
}
|
||||
function onToday() {
|
||||
calendar.value.moveToToday();
|
||||
}
|
||||
@@ -152,3 +145,10 @@ function onNext() {
|
||||
calendar.value.next();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="sass">
|
||||
.q-calendar-scheduler__resource
|
||||
background-color: $primary
|
||||
color: white
|
||||
font-weight: bold
|
||||
</style>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<template>
|
||||
<ToolbarComponent pageTitle="Tasks" />
|
||||
<q-page padding>
|
||||
<div class="q-pa-md" style="max-width: 400px">
|
||||
<div
|
||||
class="q-pa-md"
|
||||
style="max-width: 400px">
|
||||
<TaskEditComponent :taskId="taskId" />
|
||||
</div>
|
||||
</q-page>
|
||||
@@ -9,7 +11,6 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
const taskId = useRoute().params.id as string;
|
||||
console.log(taskId);
|
||||
import ToolbarComponent from 'src/components/ToolbarComponent.vue';
|
||||
import TaskEditComponent from 'src/components/task/TaskEditComponent.vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
@@ -54,7 +54,7 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
if (!id) return 'No User';
|
||||
try {
|
||||
if (!userNames.value[id]) {
|
||||
userNames.value[id] = '';
|
||||
userNames.value[id] = 'Loading...';
|
||||
functions
|
||||
.createExecution(
|
||||
'userinfo',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { computed, ref } from 'vue';
|
||||
import { Boat } from './boat';
|
||||
import { Timestamp } from '@quasar/quasar-ui-qcalendar';
|
||||
import { Timestamp, today } from '@quasar/quasar-ui-qcalendar';
|
||||
|
||||
import { Interval, IntervalRecord } from './schedule.types';
|
||||
import { AppwriteIds, databases } from 'src/boot/appwrite';
|
||||
@@ -13,6 +13,7 @@ export const useIntervalStore = defineStore('interval', () => {
|
||||
const intervals = ref<Map<string, Interval>>(new Map());
|
||||
const intervalDates = ref<IntervalRecord>({});
|
||||
const reservationStore = useReservationStore();
|
||||
const selectedDate = ref<string>(today());
|
||||
|
||||
const getIntervals = (date: Timestamp | string, boat?: Boat): Interval[] => {
|
||||
const searchDate = typeof date === 'string' ? date : date.date;
|
||||
@@ -39,8 +40,6 @@ export const useIntervalStore = defineStore('interval', () => {
|
||||
boat?: Boat
|
||||
): Interval[] => {
|
||||
return computed(() => {
|
||||
console.log(boat);
|
||||
console.log(getIntervals(date, boat));
|
||||
return getIntervals(date, boat).filter((interval) => {
|
||||
return !reservationStore.isResourceTimeOverlapped(
|
||||
interval.resource,
|
||||
@@ -51,6 +50,14 @@ export const useIntervalStore = defineStore('interval', () => {
|
||||
}).value;
|
||||
};
|
||||
|
||||
async function fetchInterval(id: string): Promise<Interval> {
|
||||
return (await databases.getDocument(
|
||||
AppwriteIds.databaseId,
|
||||
AppwriteIds.collection.interval,
|
||||
id
|
||||
)) as Interval;
|
||||
}
|
||||
|
||||
async function fetchIntervals(dateString: string) {
|
||||
try {
|
||||
const response = await databases.listDocuments(
|
||||
@@ -128,8 +135,10 @@ export const useIntervalStore = defineStore('interval', () => {
|
||||
getIntervals,
|
||||
getAvailableIntervals,
|
||||
fetchIntervals,
|
||||
fetchInterval,
|
||||
createInterval,
|
||||
updateInterval,
|
||||
deleteInterval,
|
||||
selectedDate,
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user