Files
bab-app/src/stores/interval.ts
2024-06-03 12:01:38 -04:00

145 lines
4.5 KiB
TypeScript

import { defineStore } from 'pinia';
import { computed, ref } from 'vue';
import { Boat } from './boat';
import { Timestamp, today } from '@quasar/quasar-ui-qcalendar';
import { Interval, IntervalRecord } from './schedule.types';
import { AppwriteIds, databases } from 'src/boot/appwrite';
import { ID, Query } from 'appwrite';
import { useReservationStore } from './reservation';
export const useIntervalStore = defineStore('interval', () => {
// TODO: Implement functions to dynamically pull this data.
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;
const dayStart = new Date(searchDate + 'T00:00');
const dayEnd = new Date(searchDate + 'T23:59');
if (!intervalDates.value[searchDate]) {
intervalDates.value[searchDate] = 'pending';
fetchIntervals(searchDate);
}
return computed(() => {
return Array.from(intervals.value.values()).filter((interval) => {
const intervalStart = new Date(interval.start);
const intervalEnd = new Date(interval.end);
const isWithinDay = intervalStart < dayEnd && intervalEnd > dayStart;
const matchesBoat = boat ? boat.$id === interval.resource : true;
return isWithinDay && matchesBoat;
});
}).value;
};
const getAvailableIntervals = (
date: Timestamp | string,
boat?: Boat
): Interval[] => {
return computed(() => {
return getIntervals(date, boat).filter((interval) => {
return !reservationStore.isResourceTimeOverlapped(
interval.resource,
new Date(interval.start),
new Date(interval.end)
);
});
}).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(
AppwriteIds.databaseId,
AppwriteIds.collection.interval,
[
Query.greaterThanEqual(
'end',
new Date(dateString + 'T00:00').toISOString()
),
Query.lessThanEqual(
'start',
new Date(dateString + 'T23:59').toISOString()
),
Query.limit(50), // We are asuming that we won't have more than 50 intervals per day.
]
);
response.documents.forEach((d) =>
intervals.value.set(d.$id, d as Interval)
);
intervalDates.value[dateString] = 'loaded';
console.info(`Loaded ${response.documents.length} intervals from server`);
} catch (error) {
console.error('Failed to fetch intervals', error);
intervalDates.value[dateString] = 'error';
}
}
const createInterval = async (interval: Interval) => {
try {
const response = await databases.createDocument(
AppwriteIds.databaseId,
AppwriteIds.collection.interval,
ID.unique(),
interval
);
intervals.value.set(response.$id, response as Interval);
} catch (e) {
console.error('Error creating Interval: ' + e);
}
};
const updateInterval = async (interval: Interval) => {
try {
if (interval.$id) {
const response = await databases.updateDocument(
AppwriteIds.databaseId,
AppwriteIds.collection.interval,
interval.$id,
{ ...interval, $id: undefined }
);
intervals.value.set(response.$id, response as Interval);
console.info(`Saved Interval: ${interval.$id}`);
} else {
console.error('Update interval called without an ID');
}
} catch (e) {
console.error('Error updating Interval: ' + e);
}
};
const deleteInterval = async (id: string) => {
try {
await databases.deleteDocument(
AppwriteIds.databaseId,
AppwriteIds.collection.interval,
id
);
intervals.value.delete(id);
console.info(`Deleted interval: ${id}`);
} catch (e) {
console.error('Error deleting Interval: ' + e);
}
};
return {
getIntervals,
getAvailableIntervals,
fetchIntervals,
fetchInterval,
createInterval,
updateInterval,
deleteInterval,
selectedDate,
};
});