Add List View

This commit is contained in:
2024-05-24 20:45:04 -04:00
parent 2fb236cf97
commit 9f398e5509
6 changed files with 152 additions and 13 deletions

View File

@@ -44,12 +44,7 @@
label="Start" />
</q-item-section>
<q-item-section class="text-body2">
{{
date.formatDate(
new Date(bookingForm.startDate as string),
'ddd MMM Do hh:mm A'
)
}}
{{ formatDate(bookingForm.startDate) }}
</q-item-section>
</q-item>
<q-item class="q-ma-none">
@@ -59,12 +54,7 @@
label="End" />
</q-item-section>
<q-item-section class="text-body2">
{{
date.formatDate(
new Date(bookingForm.endDate as string),
'ddd MMM Do hh:mm A'
)
}}
{{ formatDate(bookingForm.endDate) }}
</q-item-section>
</q-item>
</q-list>
@@ -131,10 +121,11 @@
import { computed, ref, watch } from 'vue';
import { useAuthStore } from 'src/stores/auth';
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 BoatScheduleTableComponent from 'src/components/scheduling/boat/BoatScheduleTableComponent.vue';
import { getNewId } from 'src/utils/misc';
import { formatDate } from 'src/utils/schedule';
import { useRouter } from 'vue-router';
import { useReservationStore } from 'src/stores/reservation';

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

View File

@@ -29,6 +29,13 @@ export const links = [
front_links: true,
enabled: true,
sublinks: [
{
name: 'List',
to: '/schedule/list',
icon: 'list',
front_links: false,
enabled: true,
},
{
name: 'Book',
to: '/schedule/book',

View File

@@ -40,6 +40,11 @@ const routes: RouteRecordRaw[] = [
component: () => import('src/pages/schedule/BoatScheduleView.vue'),
name: 'boat-schedule',
},
{
path: 'list',
component: () => import('src/pages/schedule/ListBookingsPage.vue'),
name: 'list-bookings',
},
{
path: 'manage',
component: () => import('src/pages/schedule/ManageCalendar.vue'),

View File

@@ -6,10 +6,13 @@ import { ID, Query } from 'appwrite';
import { date } from 'quasar';
import { Timestamp, parseDate, today } from '@quasar/quasar-ui-qcalendar';
import { LoadingTypes } from 'src/utils/misc';
import { useAuthStore } from './auth';
export const useReservationStore = defineStore('reservation', () => {
const reservations = ref<Map<string, Reservation>>(new Map());
const datesLoaded = ref<Record<string, LoadingTypes>>({});
const userReservations = ref<Reservation[]>();
const authStore = useAuthStore();
// Fetch reservations for a specific date range
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 {
getReservationsByDate,
createReservation,
@@ -143,5 +164,7 @@ export const useReservationStore = defineStore('reservation', () => {
isReservationOverlapped,
isResourceTimeOverlapped,
getConflictingReservations,
fetchUserReservations,
getUserReservations,
};
});

View File

@@ -1,3 +1,4 @@
import { date } from 'quasar';
import { Boat } from 'src/stores/boat';
import {
Interval,
@@ -69,3 +70,8 @@ export function buildInterval(
};
return result;
}
export function formatDate(inputDate: string | undefined): string {
if (!inputDate) return '';
return date.formatDate(new Date(inputDate), 'ddd MMM Do hh:mm A');
}