Started work on Schedule Management

This commit is contained in:
2024-05-06 17:22:11 -04:00
parent 8e73650462
commit 2872fb867e
5 changed files with 81 additions and 33 deletions

View File

@@ -2,17 +2,21 @@
<router-view /> <router-view />
</template> </template>
<script lang="ts"> <script setup lang="ts">
import { defineComponent, onMounted } from 'vue'; import { defineComponent, onMounted } from 'vue';
import { useBoatStore } from './stores/boat'; import { useBoatStore } from './stores/boat';
import { useScheduleStore } from './stores/schedule'; import { useScheduleStore } from './stores/schedule';
import { useAuthStore } from './stores/auth';
export default defineComponent({ defineComponent({
name: 'OYS Borrow-a-Boat', name: 'OYS Borrow-a-Boat',
}); });
onMounted(async () => { onMounted(async () => {
await useBoatStore().fetchBoats(); if (useAuthStore().currentUser) {
await useScheduleStore().fetchTimeBlocks(); await useBoatStore().fetchBoats();
await useScheduleStore().fetchTimeBlocks();
await useScheduleStore().fetchTimeBlockTemplates();
}
}); });
</script> </script>

View File

@@ -1,38 +1,52 @@
<template> <template>
<div class="fit row wrap justify-start items-start content-start"> <div class="fit row wrap justify-start items-start content-start">
<div class="col-9"> <div class="col-9 q-pa-md">
<div class="scheduler"> <div class="scheduler">
<q-calendar-scheduler <q-calendar-scheduler
ref="calendar" ref="calendar"
v-model="selectedDate" v-model="selectedDate"
v-model:model-resources="resources" v-model:model-resources="resources"
view="week" view="week"
:drag-enter-func="onDragEnter" :weekdays="[1, 2, 3, 4, 5, 6, 0]"
:drag-over-func="onDragOver"
:drag-leave-func="onDragLeave"
:drop-func="onDrop"
:weekday-class="onWeekdayClass"
:day-class="onDayClass"
:weekdays="[1, 2, 3, 4, 5]"
hoverable hoverable
animated animated
bordered bordered
:day-min-height="50" :day-min-height="50"
:day-height="0" :day-height="0"
style="max-width: 800px; width: 100%"
@change="onChange"
@moved="onMoved"
@click-date="onClickDate"
@click-day-resource="onClickDayResource"
@click-resource="onClickResource"
@click-head-resources="onClickHeadResources"
@click-head-day="onClickHeadDay"
></q-calendar-scheduler> ></q-calendar-scheduler>
</div> </div>
</div> </div>
HI! <div class="col-3 q-pa-md">
<div class="col-3"> <q-list padding bordered class="rounded-borders">
<!----> <q-item>
<q-item-section>
<q-item-label overline>Availability Templates</q-item-label>
<q-item-label caption
>Drag and drop a template to a boat / date to create booking
availability</q-item-label
>
</q-item-section>
</q-item>
<q-separator spaced />
<q-expansion-item
v-for="template in timeblockTemplates"
:key="template.$id"
dense
dense-toggle
expand-separator
:label="template.name"
style="font-size: 0.8em"
draggable="true"
>
<q-card>
<q-card-section>
<q-badge v-for="item in template.timeTuple" :key="item.$id">
{{ item[0] }} - {{ item[1] }}
</q-badge>
</q-card-section>
</q-card>
</q-expansion-item></q-list
>
</div> </div>
</div> </div>
</template> </template>
@@ -40,8 +54,11 @@
<script setup type="ts"> <script setup type="ts">
import {QCalendarScheduler, today} from '@quasar/quasar-ui-qcalendar' import {QCalendarScheduler, today} from '@quasar/quasar-ui-qcalendar'
import { useBoatStore } from 'src/stores/boat'; import { useBoatStore } from 'src/stores/boat';
import { useScheduleStore } from 'src/stores/schedule';
import { ref } from 'vue'; import { ref } from 'vue';
const selectedDate = ref(today()) const selectedDate = ref(today())
const resources = ref(useBoatStore().boats) const scheduleStore = useScheduleStore()
const resources = useBoatStore().boats
const timeblockTemplates = scheduleStore.timeblockTemplates
</script> </script>

View File

@@ -12,12 +12,13 @@ import type {
Reservation, Reservation,
TimeBlockTemplate, TimeBlockTemplate,
Timeblock, Timeblock,
TimeTuple,
} from '../schedule.types'; } from '../schedule.types';
export const templateA: TimeBlockTemplate = { export const templateA: TimeBlockTemplate = {
id: '1', id: '1',
name: 'WeekdayBlocks', name: 'WeekdayBlocks',
blocks: [ timeTuple: [
['08:00', '12:00'], ['08:00', '12:00'],
['12:00', '16:00'], ['12:00', '16:00'],
['17:00', '21:00'], ['17:00', '21:00'],
@@ -27,7 +28,7 @@ export const templateA: TimeBlockTemplate = {
export const templateB: TimeBlockTemplate = { export const templateB: TimeBlockTemplate = {
id: '2', id: '2',
name: 'WeekendBlocks', name: 'WeekendBlocks',
blocks: [ timeTuple: [
['07:00', '10:00'], ['07:00', '10:00'],
['10:00', '13:00'], ['10:00', '13:00'],
['13:00', '16:00'], ['13:00', '16:00'],
@@ -46,7 +47,7 @@ export function getSampleTimeBlocks(): Timeblock[] {
result.push( result.push(
...boats.value ...boats.value
.map((b): Timeblock[] => { .map((b): Timeblock[] => {
return template.blocks.map((t): Timeblock => { return template.blocks.map((t: TimeTuple): Timeblock => {
return { return {
$id: 'id' + Math.random().toString(32).slice(2), $id: 'id' + Math.random().toString(32).slice(2),
boatId: b.$id, boatId: b.$id,

View File

@@ -8,13 +8,19 @@ import {
compareDate, compareDate,
} from '@quasar/quasar-ui-qcalendar'; } from '@quasar/quasar-ui-qcalendar';
import { Reservation, Timeblock } from './schedule.types'; import {
Reservation,
TimeBlockTemplate,
TimeTuple,
Timeblock,
} from './schedule.types';
import { AppwriteIds, databases } from 'src/boot/appwrite'; import { AppwriteIds, databases } from 'src/boot/appwrite';
export const useScheduleStore = defineStore('schedule', () => { export const useScheduleStore = defineStore('schedule', () => {
// TODO: Implement functions to dynamically pull this data. // TODO: Implement functions to dynamically pull this data.
const reservations = ref<Reservation[]>([]); const reservations = ref<Reservation[]>([]);
const timeblocks = ref<Timeblock[]>([]); const timeblocks = ref<Timeblock[]>([]);
const timeblockTemplates = ref<TimeBlockTemplate[]>([]);
const getTimeblocksForDate = (date: string): Timeblock[] => { const getTimeblocksForDate = (date: string): Timeblock[] => {
// TODO: This needs to actually make sure we have the dates we need, stay in sync, etc. // TODO: This needs to actually make sure we have the dates we need, stay in sync, etc.
@@ -55,6 +61,25 @@ export const useScheduleStore = defineStore('schedule', () => {
console.error('Failed to fetch timeblocks', error); console.error('Failed to fetch timeblocks', error);
} }
} }
async function fetchTimeBlockTemplates() {
try {
const response = await databases.listDocuments(
AppwriteIds.databaseId,
AppwriteIds.collection.timeBlockTemplate
);
const res = response.documents.map((d) => {
const timeTuples: TimeTuple[] = [];
for (let i = 0; i < d.timeTuple.length; i += 2) {
timeTuples.push([d.timeTuple[i], d.timeTuple[i + 1]]);
}
return { ...d, timeTuple: timeTuples };
}) as TimeBlockTemplate[];
timeblockTemplates.value = res;
} catch (error) {
console.error('Failed to fetch timeblock templates', error);
}
}
// const getConflicts = (timeblock: Timeblock, boat: Boat) => { // const getConflicts = (timeblock: Timeblock, boat: Boat) => {
// const start = date.buildDate({ // const start = date.buildDate({
// hour: timeblock.start.hour, // hour: timeblock.start.hour,
@@ -117,10 +142,12 @@ export const useScheduleStore = defineStore('schedule', () => {
return { return {
reservations, reservations,
timeblocks, timeblocks,
timeblockTemplates,
getBoatReservations, getBoatReservations,
getConflictingReservations, getConflictingReservations,
getTimeblocksForDate, getTimeblocksForDate,
fetchTimeBlocks, fetchTimeBlocks,
fetchTimeBlockTemplates,
getNewId, getNewId,
addOrCreateReservation, addOrCreateReservation,
isReservationOverlapped, isReservationOverlapped,

View File

@@ -17,7 +17,7 @@ export interface Reservation {
e.g.: Should there be any qcalendar stuff in this store? Or should we have just JS Date e.g.: Should there be any qcalendar stuff in this store? Or should we have just JS Date
objects in here? */ objects in here? */
export type timeTuple = [start: string, end: string]; export type TimeTuple = [start: string, end: string];
export type Timeblock = Partial<Models.Document> & { export type Timeblock = Partial<Models.Document> & {
boatId: string; boatId: string;
start: string; start: string;
@@ -25,8 +25,7 @@ export type Timeblock = Partial<Models.Document> & {
selected?: false; selected?: false;
}; };
export interface TimeBlockTemplate { export type TimeBlockTemplate = Partial<Models.Document> & {
id: string;
name: string; name: string;
blocks: timeTuple[]; timeTuple: TimeTuple[];
} };