Started work on Schedule Management
This commit is contained in:
12
src/App.vue
12
src/App.vue
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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[];
|
||||||
}
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user