Add List View
This commit is contained in:
@@ -44,12 +44,7 @@
|
|||||||
label="Start" />
|
label="Start" />
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section class="text-body2">
|
<q-item-section class="text-body2">
|
||||||
{{
|
{{ formatDate(bookingForm.startDate) }}
|
||||||
date.formatDate(
|
|
||||||
new Date(bookingForm.startDate as string),
|
|
||||||
'ddd MMM Do hh:mm A'
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
<q-item class="q-ma-none">
|
<q-item class="q-ma-none">
|
||||||
@@ -59,12 +54,7 @@
|
|||||||
label="End" />
|
label="End" />
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section class="text-body2">
|
<q-item-section class="text-body2">
|
||||||
{{
|
{{ formatDate(bookingForm.endDate) }}
|
||||||
date.formatDate(
|
|
||||||
new Date(bookingForm.endDate as string),
|
|
||||||
'ddd MMM Do hh:mm A'
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
</q-list>
|
</q-list>
|
||||||
@@ -131,10 +121,11 @@
|
|||||||
import { computed, ref, watch } from 'vue';
|
import { computed, 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 { useQuasar } from 'quasar';
|
||||||
import { Interval, Reservation } from 'src/stores/schedule.types';
|
import { Interval, Reservation } from 'src/stores/schedule.types';
|
||||||
import BoatScheduleTableComponent from 'src/components/scheduling/boat/BoatScheduleTableComponent.vue';
|
import BoatScheduleTableComponent from 'src/components/scheduling/boat/BoatScheduleTableComponent.vue';
|
||||||
import { getNewId } from 'src/utils/misc';
|
import { getNewId } from 'src/utils/misc';
|
||||||
|
import { formatDate } from 'src/utils/schedule';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { useReservationStore } from 'src/stores/reservation';
|
import { useReservationStore } from 'src/stores/reservation';
|
||||||
|
|
||||||
|
|||||||
107
src/pages/schedule/ListBookingsPage.vue
Normal file
107
src/pages/schedule/ListBookingsPage.vue
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
<template>
|
||||||
|
<template
|
||||||
|
v-for="(booking, index) in sortedBookings"
|
||||||
|
:key="booking.$id">
|
||||||
|
<q-toolbar
|
||||||
|
class="bg-secondary glossy text-white"
|
||||||
|
v-if="showMarker(index, sortedBookings)">
|
||||||
|
Past
|
||||||
|
</q-toolbar>
|
||||||
|
<q-card
|
||||||
|
bordered
|
||||||
|
:class="isPast(booking.end) ? 'text-blue-grey-6' : ''"
|
||||||
|
class="q-ma-md">
|
||||||
|
<q-card-section>
|
||||||
|
<div class="row items-center no-wrap">
|
||||||
|
<div class="col">
|
||||||
|
<div class="text-h6">
|
||||||
|
{{ boatStore.getBoatById(booking.resource)?.name }}
|
||||||
|
</div>
|
||||||
|
<div class="text-subtitle2">
|
||||||
|
<p>Start: {{ formatDate(booking.start) }}</p>
|
||||||
|
<p>End: {{ formatDate(booking.end) }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<q-btn
|
||||||
|
color="grey-7"
|
||||||
|
round
|
||||||
|
flat
|
||||||
|
icon="more_vert">
|
||||||
|
<q-menu
|
||||||
|
cover
|
||||||
|
auto-close>
|
||||||
|
<q-list>
|
||||||
|
<q-item clickable>
|
||||||
|
<q-item-section>Remove Card</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
<q-item clickable>
|
||||||
|
<q-item-section>Send Feedback</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
<q-item clickable>
|
||||||
|
<q-item-section>Share</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</q-list>
|
||||||
|
</q-menu>
|
||||||
|
</q-btn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-card-section>Some more information here...</q-card-section>
|
||||||
|
|
||||||
|
<q-separator />
|
||||||
|
|
||||||
|
<q-card-actions>
|
||||||
|
<q-btn flat>Action 1</q-btn>
|
||||||
|
<q-btn flat>Action 2</q-btn>
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useBoatStore } from 'src/stores/boat';
|
||||||
|
import { useReservationStore } from 'src/stores/reservation';
|
||||||
|
import { Reservation } from 'src/stores/schedule.types';
|
||||||
|
import { formatDate } from 'src/utils/schedule';
|
||||||
|
import { computed, onMounted } from 'vue';
|
||||||
|
|
||||||
|
const reservationStore = useReservationStore();
|
||||||
|
const bookings = reservationStore.getUserReservations();
|
||||||
|
const boatStore = useBoatStore();
|
||||||
|
|
||||||
|
const sortedBookings = computed(() =>
|
||||||
|
bookings.value
|
||||||
|
?.slice()
|
||||||
|
.sort((a, b) => new Date(b.start).getTime() - new Date(a.start).getTime())
|
||||||
|
);
|
||||||
|
|
||||||
|
const isPast = (itemDate: Date | string): boolean => {
|
||||||
|
if (!(itemDate instanceof Date)) {
|
||||||
|
itemDate = new Date(itemDate);
|
||||||
|
}
|
||||||
|
console.log(itemDate);
|
||||||
|
const currentDate = new Date();
|
||||||
|
return itemDate < currentDate;
|
||||||
|
};
|
||||||
|
|
||||||
|
const showMarker = (
|
||||||
|
index: number,
|
||||||
|
items: Reservation[] | undefined
|
||||||
|
): boolean => {
|
||||||
|
if (!items) return false;
|
||||||
|
|
||||||
|
const currentItemDate = new Date(items[index].start);
|
||||||
|
const nextItemDate = index > 0 ? new Date(items[index - 1].start) : null;
|
||||||
|
|
||||||
|
// Show marker if current item is past and the next item is future or vice versa
|
||||||
|
return (
|
||||||
|
isPast(currentItemDate) && (nextItemDate === null || !isPast(nextItemDate))
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
boatStore.fetchBoats();
|
||||||
|
reservationStore.fetchUserReservations();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -29,6 +29,13 @@ export const links = [
|
|||||||
front_links: true,
|
front_links: true,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
sublinks: [
|
sublinks: [
|
||||||
|
{
|
||||||
|
name: 'List',
|
||||||
|
to: '/schedule/list',
|
||||||
|
icon: 'list',
|
||||||
|
front_links: false,
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'Book',
|
name: 'Book',
|
||||||
to: '/schedule/book',
|
to: '/schedule/book',
|
||||||
|
|||||||
@@ -40,6 +40,11 @@ const routes: RouteRecordRaw[] = [
|
|||||||
component: () => import('src/pages/schedule/BoatScheduleView.vue'),
|
component: () => import('src/pages/schedule/BoatScheduleView.vue'),
|
||||||
name: 'boat-schedule',
|
name: 'boat-schedule',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'list',
|
||||||
|
component: () => import('src/pages/schedule/ListBookingsPage.vue'),
|
||||||
|
name: 'list-bookings',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'manage',
|
path: 'manage',
|
||||||
component: () => import('src/pages/schedule/ManageCalendar.vue'),
|
component: () => import('src/pages/schedule/ManageCalendar.vue'),
|
||||||
|
|||||||
@@ -6,10 +6,13 @@ import { ID, Query } from 'appwrite';
|
|||||||
import { date } from 'quasar';
|
import { date } from 'quasar';
|
||||||
import { Timestamp, parseDate, today } from '@quasar/quasar-ui-qcalendar';
|
import { Timestamp, parseDate, today } from '@quasar/quasar-ui-qcalendar';
|
||||||
import { LoadingTypes } from 'src/utils/misc';
|
import { LoadingTypes } from 'src/utils/misc';
|
||||||
|
import { useAuthStore } from './auth';
|
||||||
|
|
||||||
export const useReservationStore = defineStore('reservation', () => {
|
export const useReservationStore = defineStore('reservation', () => {
|
||||||
const reservations = ref<Map<string, Reservation>>(new Map());
|
const reservations = ref<Map<string, Reservation>>(new Map());
|
||||||
const datesLoaded = ref<Record<string, LoadingTypes>>({});
|
const datesLoaded = ref<Record<string, LoadingTypes>>({});
|
||||||
|
const userReservations = ref<Reservation[]>();
|
||||||
|
const authStore = useAuthStore();
|
||||||
|
|
||||||
// Fetch reservations for a specific date range
|
// Fetch reservations for a specific date range
|
||||||
const fetchReservationsForDateRange = async (
|
const fetchReservationsForDateRange = async (
|
||||||
@@ -136,6 +139,24 @@ export const useReservationStore = defineStore('reservation', () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getUserReservations = () => {
|
||||||
|
return userReservations;
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchUserReservations = async () => {
|
||||||
|
if (!authStore.currentUser) return;
|
||||||
|
try {
|
||||||
|
const response = await databases.listDocuments(
|
||||||
|
AppwriteIds.databaseId,
|
||||||
|
AppwriteIds.collection.reservation,
|
||||||
|
[Query.equal('user', authStore.currentUser.$id)]
|
||||||
|
);
|
||||||
|
userReservations.value = response.documents as Reservation[];
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to fetch reservations for user: ', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getReservationsByDate,
|
getReservationsByDate,
|
||||||
createReservation,
|
createReservation,
|
||||||
@@ -143,5 +164,7 @@ export const useReservationStore = defineStore('reservation', () => {
|
|||||||
isReservationOverlapped,
|
isReservationOverlapped,
|
||||||
isResourceTimeOverlapped,
|
isResourceTimeOverlapped,
|
||||||
getConflictingReservations,
|
getConflictingReservations,
|
||||||
|
fetchUserReservations,
|
||||||
|
getUserReservations,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { date } from 'quasar';
|
||||||
import { Boat } from 'src/stores/boat';
|
import { Boat } from 'src/stores/boat';
|
||||||
import {
|
import {
|
||||||
Interval,
|
Interval,
|
||||||
@@ -69,3 +70,8 @@ export function buildInterval(
|
|||||||
};
|
};
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function formatDate(inputDate: string | undefined): string {
|
||||||
|
if (!inputDate) return '';
|
||||||
|
return date.formatDate(new Date(inputDate), 'ddd MMM Do hh:mm A');
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user