Clean up all kinds of typescript issues
This commit is contained in:
@@ -3,9 +3,16 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { defineComponent, onMounted } from 'vue';
|
||||
import { useBoatStore } from './stores/boat';
|
||||
import { useScheduleStore } from './stores/schedule';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'OYS Borrow-a-Boat',
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
await useBoatStore().fetchBoats();
|
||||
await useScheduleStore().fetchTimeBlocks();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -13,9 +13,10 @@ const client = new Client();
|
||||
// const appDatabaseId = '654ac5044d1c446feb71';
|
||||
|
||||
// Private self-hosted appwrite
|
||||
client
|
||||
.setEndpoint(process.env.APPWRITE_API_ENDPOINT)
|
||||
.setProject(process.env.APPWRITE_API_PROJECT);
|
||||
if (process.env.APPWRITE_API_ENDPOINT && process.env.APPWRITE_API_PROJECT)
|
||||
client
|
||||
.setEndpoint(process.env.APPWRITE_API_ENDPOINT)
|
||||
.setProject(process.env.APPWRITE_API_PROJECT);
|
||||
|
||||
//TODO move this to config file
|
||||
const AppwriteIds = {
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<p>{{ title }}</p>
|
||||
<ul>
|
||||
<li v-for="todo in todos" :key="todo.id" @click="increment">
|
||||
{{ todo.id }} - {{ todo.content }}
|
||||
</li>
|
||||
</ul>
|
||||
<p>Count: {{ todoCount }} / {{ meta.totalCount }}</p>
|
||||
<p>Active: {{ active ? 'yes' : 'no' }}</p>
|
||||
<p>Clicks on todos: {{ clickCount }}</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {
|
||||
defineComponent,
|
||||
PropType,
|
||||
computed,
|
||||
ref,
|
||||
toRef,
|
||||
Ref,
|
||||
} from 'vue';
|
||||
import { Todo, Meta } from './models';
|
||||
|
||||
function useClickCount() {
|
||||
const clickCount = ref(0);
|
||||
function increment() {
|
||||
clickCount.value += 1
|
||||
return clickCount.value;
|
||||
}
|
||||
|
||||
return { clickCount, increment };
|
||||
}
|
||||
|
||||
function useDisplayTodo(todos: Ref<Todo[]>) {
|
||||
const todoCount = computed(() => todos.value.length);
|
||||
return { todoCount };
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ExampleComponent',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
todos: {
|
||||
type: Array as PropType<Todo[]>,
|
||||
default: () => []
|
||||
},
|
||||
meta: {
|
||||
type: Object as PropType<Meta>,
|
||||
required: true
|
||||
},
|
||||
active: {
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
setup (props) {
|
||||
return { ...useClickCount(), ...useDisplayTodo(toRef(props, 'todos')) };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@@ -116,7 +116,7 @@ import { Boat, useBoatStore } from 'src/stores/boat';
|
||||
import { useScheduleStore } from 'src/stores/schedule';
|
||||
import { date } from 'quasar';
|
||||
import { computed } from 'vue';
|
||||
import type { StatusTypes } from 'src/stores/schedule';
|
||||
import type { StatusTypes } from 'src/stores/schedule.types';
|
||||
|
||||
interface EventData {
|
||||
event: object;
|
||||
@@ -172,7 +172,7 @@ function monthFormatter() {
|
||||
|
||||
function getEvents(scope: ResourceIntervalScope) {
|
||||
const resourceEvents = scheduleStore.getBoatReservations(
|
||||
date.extractDate(selectedDate.value, 'YYYY-MM-DD'),
|
||||
parseDate(date.extractDate(selectedDate.value, 'YYYY-MM-DD')) as Timestamp,
|
||||
scope.resource.$id
|
||||
);
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
:short-interval-label="true"
|
||||
v-model="selectedDate"
|
||||
:column-count="boatData.length"
|
||||
@change="changeEvent"
|
||||
v-touch-swipe.left.right="handleSwipe"
|
||||
>
|
||||
<template #head-day="{ scope }">
|
||||
@@ -71,15 +70,13 @@ import {
|
||||
parseTimestamp,
|
||||
parseDate,
|
||||
addToDate,
|
||||
makeDateTime,
|
||||
} from '@quasar/quasar-ui-qcalendar';
|
||||
import CalendarHeaderComponent from './CalendarHeaderComponent.vue';
|
||||
|
||||
import { ref, computed, onMounted } from 'vue';
|
||||
import { Boat, useBoatStore } from 'src/stores/boat';
|
||||
import { useBoatStore } from 'src/stores/boat';
|
||||
import { useScheduleStore } from 'src/stores/schedule';
|
||||
import { Reservation, Timeblock } from 'src/stores/schedule.types';
|
||||
import { date } from 'quasar';
|
||||
import { Timeblock } from 'src/stores/schedule.types';
|
||||
|
||||
const scheduleStore = useScheduleStore();
|
||||
const boatStore = useBoatStore();
|
||||
@@ -98,18 +95,18 @@ onMounted(async () => {
|
||||
function handleSwipe({ ...event }) {
|
||||
event.direction === 'right' ? calendar.value?.prev() : calendar.value?.next();
|
||||
}
|
||||
function reservationStyles(
|
||||
reservation: Reservation,
|
||||
timeStartPos: (t: string) => string,
|
||||
timeDurationHeight: (d: number) => string
|
||||
) {
|
||||
return genericBlockStyle(
|
||||
parseDate(reservation.start) as Timestamp,
|
||||
parseDate(reservation.end) as Timestamp,
|
||||
timeStartPos,
|
||||
timeDurationHeight
|
||||
);
|
||||
}
|
||||
// function reservationStyles(
|
||||
// reservation: Reservation,
|
||||
// timeStartPos: (t: string) => string,
|
||||
// timeDurationHeight: (d: number) => string
|
||||
// ) {
|
||||
// return genericBlockStyle(
|
||||
// parseDate(reservation.start) as Timestamp,
|
||||
// parseDate(reservation.end) as Timestamp,
|
||||
// timeStartPos,
|
||||
// timeDurationHeight
|
||||
// );
|
||||
// }
|
||||
|
||||
function blockStyles(
|
||||
block: Timeblock,
|
||||
@@ -190,33 +187,33 @@ function getBoatBlocks(scope: DayBodyScope): Timeblock[] {
|
||||
: [];
|
||||
}
|
||||
|
||||
function changeEvent({ start }: { start: string }) {
|
||||
// const newBlocks = scheduleStore.getTimeblocksForDate(start);
|
||||
// const reservations = scheduleStore.getBoatReservations(
|
||||
// parsed(start) as Timestamp
|
||||
// );
|
||||
// boatData.value.map((boat) => {
|
||||
// boat.reservations = reservations.filter(
|
||||
// (reservation) => reservation.resource === boat
|
||||
// );
|
||||
// boat.blocks = newBlocks.filter(
|
||||
// (block) =>
|
||||
// block.boatId === boat.$id &&
|
||||
// boat.reservations?.filter(
|
||||
// (r: Reservation) =>
|
||||
// r.start <
|
||||
// date.addToDate(makeDateTime(parsed(block.end) as Timestamp), {
|
||||
// hours: 4,
|
||||
// }) &&
|
||||
// r.end >
|
||||
// date.addToDate(makeDateTime(parsed(block.start) as Timestamp), {
|
||||
// hours: 4,
|
||||
// })
|
||||
// ).length == 0
|
||||
// );
|
||||
// });
|
||||
// setTimeout(() => calendar.value?.scrollToTime('09:00'), 100); // Should figure out why we need this setTimeout...
|
||||
}
|
||||
// function changeEvent({ start }: { start: string }) {
|
||||
// const newBlocks = scheduleStore.getTimeblocksForDate(start);
|
||||
// const reservations = scheduleStore.getBoatReservations(
|
||||
// parsed(start) as Timestamp
|
||||
// );
|
||||
// boatData.value.map((boat) => {
|
||||
// boat.reservations = reservations.filter(
|
||||
// (reservation) => reservation.resource === boat
|
||||
// );
|
||||
// boat.blocks = newBlocks.filter(
|
||||
// (block) =>
|
||||
// block.boatId === boat.$id &&
|
||||
// boat.reservations?.filter(
|
||||
// (r: Reservation) =>
|
||||
// r.start <
|
||||
// date.addToDate(makeDateTime(parsed(block.end) as Timestamp), {
|
||||
// hours: 4,
|
||||
// }) &&
|
||||
// r.end >
|
||||
// date.addToDate(makeDateTime(parsed(block.start) as Timestamp), {
|
||||
// hours: 4,
|
||||
// })
|
||||
// ).length == 0
|
||||
// );
|
||||
// });
|
||||
// setTimeout(() => calendar.value?.scrollToTime('09:00'), 100); // Should figure out why we need this setTimeout...
|
||||
// }
|
||||
|
||||
const disabledBefore = computed(() => {
|
||||
const todayTs = parseTimestamp(today()) as Timestamp;
|
||||
|
||||
@@ -57,7 +57,7 @@ import { ref, reactive, computed } from 'vue';
|
||||
|
||||
const selectedDate = defineModel<string>();
|
||||
|
||||
const weekdays = reactive([0, 1, 2, 3, 4, 5, 6]),
|
||||
const weekdays = reactive([1, 2, 3, 4, 5, 6, 0]),
|
||||
locale = ref('en-CA'),
|
||||
monthFormatter = monthFormatterFunc(),
|
||||
dayFormatter = dayFormatterFunc(),
|
||||
@@ -124,8 +124,14 @@ function dayClass(day: Timestamp) {
|
||||
}
|
||||
|
||||
function monthFormatterFunc() {
|
||||
const longOptions = { timeZone: 'UTC', month: 'long' };
|
||||
const shortOptions = { timeZone: 'UTC', month: 'short' };
|
||||
const longOptions: Intl.DateTimeFormatOptions = {
|
||||
timeZone: 'UTC',
|
||||
month: 'long',
|
||||
};
|
||||
const shortOptions: Intl.DateTimeFormatOptions = {
|
||||
timeZone: 'UTC',
|
||||
month: 'short',
|
||||
};
|
||||
|
||||
return createNativeLocaleFormatter(locale.value, (_tms, short) =>
|
||||
short ? shortOptions : longOptions
|
||||
@@ -133,17 +139,28 @@ function monthFormatterFunc() {
|
||||
}
|
||||
|
||||
function weekdayFormatterFunc() {
|
||||
const longOptions = { timeZone: 'UTC', weekday: 'long' };
|
||||
const shortOptions = { timeZone: 'UTC', weekday: 'short' };
|
||||
|
||||
const longOptions: Intl.DateTimeFormatOptions = {
|
||||
timeZone: 'UTC',
|
||||
weekday: 'long',
|
||||
};
|
||||
const shortOptions: Intl.DateTimeFormatOptions = {
|
||||
timeZone: 'UTC',
|
||||
weekday: 'short',
|
||||
};
|
||||
return createNativeLocaleFormatter(locale.value, (_tms, short) =>
|
||||
short ? shortOptions : longOptions
|
||||
);
|
||||
}
|
||||
|
||||
function dayFormatterFunc() {
|
||||
const longOptions = { timeZone: 'UTC', day: '2-digit' };
|
||||
const shortOptions = { timeZone: 'UTC', day: 'numeric' };
|
||||
const longOptions: Intl.DateTimeFormatOptions = {
|
||||
timeZone: 'UTC',
|
||||
day: '2-digit',
|
||||
};
|
||||
const shortOptions: Intl.DateTimeFormatOptions = {
|
||||
timeZone: 'UTC',
|
||||
day: 'numeric',
|
||||
};
|
||||
|
||||
return createNativeLocaleFormatter(locale.value, (_tms, short) =>
|
||||
short ? shortOptions : longOptions
|
||||
|
||||
@@ -20,5 +20,5 @@
|
||||
import { defineProps } from 'vue';
|
||||
import type { Task } from 'src/stores/task';
|
||||
|
||||
const props = defineProps<{ task: Task }>();
|
||||
defineProps<{ task: Task }>();
|
||||
</script>
|
||||
|
||||
@@ -162,7 +162,7 @@ import { useRouter } from 'vue-router';
|
||||
import { useTaskStore, TASKSTATUS } from 'src/stores/task';
|
||||
import type { TaskTag, SkillTag, Task } from 'src/stores/task';
|
||||
import { date } from 'quasar';
|
||||
import { Boat, useBoatStore } from 'src/stores/boat';
|
||||
import { useBoatStore } from 'src/stores/boat';
|
||||
|
||||
const props = defineProps<{ taskId?: string }>();
|
||||
const taskStore = useTaskStore();
|
||||
@@ -187,7 +187,7 @@ const targetTask = taskId && taskStore.tasks.find((t) => t.$id === taskId);
|
||||
const modifiedTask = reactive(targetTask ? targetTask : defaultTask);
|
||||
|
||||
let tasks = taskStore.tasks;
|
||||
const boatList = ref<Boat[]>(useBoatStore().boats);
|
||||
const boatList = useBoatStore().boats;
|
||||
|
||||
const skillTagOptions = ref<SkillTag[]>(taskStore.skillTags);
|
||||
const taskTagOptions = ref<TaskTag[]>(taskStore.taskTags);
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
rounded
|
||||
class="bg-warning text-grey-10"
|
||||
style="max-width: 95vw; margin: auto"
|
||||
v-if="bookingForm.boat?.defects"
|
||||
v-if="bookingForm.boat && bookingForm.boat.defects.length > 0"
|
||||
>
|
||||
<template v-slot:avatar>
|
||||
<q-icon name="warning" color="grey-10" />
|
||||
@@ -63,7 +63,7 @@
|
||||
><q-banner v-if="bookingForm.boat"
|
||||
>Passengers:
|
||||
{{ bookingForm.members.length + bookingForm.guests.length }} /
|
||||
{{ bookingForm.boat.booking?.maxPassengers }}</q-banner
|
||||
{{ bookingForm.boat.maxPassengers }}</q-banner
|
||||
>
|
||||
<q-item
|
||||
class="q-my-sm"
|
||||
|
||||
@@ -85,22 +85,22 @@ function slotStyle(
|
||||
function reservationEvents(timestamp: Timestamp) {
|
||||
return scheduleStore.getBoatReservations(timestamp);
|
||||
}
|
||||
function onMoved(data) {
|
||||
function onMoved(data: Event) {
|
||||
console.log('onMoved', data);
|
||||
}
|
||||
function onChange(data) {
|
||||
function onChange(data: Event) {
|
||||
console.log('onChange', data);
|
||||
}
|
||||
function onClickDate(data) {
|
||||
function onClickDate(data: Event) {
|
||||
console.log('onClickDate', data);
|
||||
}
|
||||
function onClickTime(data) {
|
||||
function onClickTime(data: Event) {
|
||||
console.log('onClickTime', data);
|
||||
}
|
||||
function onClickInterval(data) {
|
||||
function onClickInterval(data: Event) {
|
||||
console.log('onClickInterval', data);
|
||||
}
|
||||
function onClickHeadDay(data) {
|
||||
function onClickHeadDay(data: Event) {
|
||||
console.log('onClickHeadDay', data);
|
||||
}
|
||||
</script>
|
||||
|
||||
47
src/pages/schedule/ManageCalendar.vue
Normal file
47
src/pages/schedule/ManageCalendar.vue
Normal file
@@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<div class="fit row wrap justify-start items-start content-start">
|
||||
<div class="col-9">
|
||||
<div class="scheduler">
|
||||
<q-calendar-scheduler
|
||||
ref="calendar"
|
||||
v-model="selectedDate"
|
||||
v-model:model-resources="resources"
|
||||
view="week"
|
||||
:drag-enter-func="onDragEnter"
|
||||
:drag-over-func="onDragOver"
|
||||
:drag-leave-func="onDragLeave"
|
||||
:drop-func="onDrop"
|
||||
:weekday-class="onWeekdayClass"
|
||||
:day-class="onDayClass"
|
||||
:weekdays="[1, 2, 3, 4, 5]"
|
||||
hoverable
|
||||
animated
|
||||
bordered
|
||||
:day-min-height="50"
|
||||
: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>
|
||||
</div>
|
||||
</div>
|
||||
HI!
|
||||
<div class="col-3">
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup type="ts">
|
||||
import {QCalendarScheduler, today} from '@quasar/quasar-ui-qcalendar'
|
||||
import { useBoatStore } from 'src/stores/boat';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const selectedDate = ref(today())
|
||||
const resources = ref(useBoatStore().boats)
|
||||
</script>
|
||||
@@ -23,5 +23,6 @@ const navlinks = [
|
||||
label: 'Create a Reservation',
|
||||
},
|
||||
{ icon: 'calendar_month', to: '/schedule/view', label: 'View Schedule' },
|
||||
{ icon: 'edit_calendar', to: '/schedule/manage', label: 'Manage Calendar' },
|
||||
];
|
||||
</script>
|
||||
|
||||
@@ -40,6 +40,11 @@ const routes: RouteRecordRaw[] = [
|
||||
component: () => import('src/pages/schedule/BoatScheduleView.vue'),
|
||||
name: 'boat-schedule',
|
||||
},
|
||||
{
|
||||
path: 'manage',
|
||||
component: () => import('src/pages/schedule/ManageCalendar.vue'),
|
||||
name: 'manage-schedule',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { ID, account } from 'boot/appwrite';
|
||||
import type { Models } from 'appwrite';
|
||||
import { OAuthProvider, type Models } from 'appwrite';
|
||||
import { ref } from 'vue';
|
||||
|
||||
export const useAuthStore = defineStore('auth', () => {
|
||||
@@ -21,12 +21,12 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
return await login(email, password);
|
||||
}
|
||||
async function login(email: string, password: string) {
|
||||
await account.createEmailSession(email, password);
|
||||
await account.createEmailPasswordSession(email, password);
|
||||
currentUser.value = await account.get();
|
||||
}
|
||||
async function googleLogin() {
|
||||
account.createOAuth2Session(
|
||||
'google',
|
||||
OAuthProvider.Google,
|
||||
'https://bab.toal.ca/',
|
||||
'https://bab.toal.ca/#/login'
|
||||
);
|
||||
|
||||
@@ -13,10 +13,10 @@ export interface Boat extends Models.Document {
|
||||
year?: number;
|
||||
imgSrc?: string;
|
||||
iconSrc?: string;
|
||||
bookingAvailable?: boolean;
|
||||
bookingAvailable: boolean;
|
||||
requiredCerts: string[];
|
||||
maxPassengers: number;
|
||||
defects?: {
|
||||
defects: {
|
||||
type: string;
|
||||
severity: string;
|
||||
description: string;
|
||||
|
||||
@@ -44,7 +44,7 @@ export function getSampleTimeBlocks(): Timeblock[] {
|
||||
for (let i = 0; i <= 30; i++) {
|
||||
const template = templateB;
|
||||
result.push(
|
||||
...boats
|
||||
...boats.value
|
||||
.map((b): Timeblock[] => {
|
||||
return template.blocks.map((t): Timeblock => {
|
||||
return {
|
||||
@@ -126,7 +126,7 @@ export function getSampleReservations(): Reservation[] {
|
||||
};
|
||||
|
||||
return sampleData.map((entry): Reservation => {
|
||||
const boat = <Boat>boatStore.boats.find((b) => b.$id == entry.boat);
|
||||
const boat = <Boat>boatStore.boats.value.find((b) => b.$id == entry.boat);
|
||||
return {
|
||||
id: entry.id,
|
||||
user: entry.user,
|
||||
|
||||
@@ -18,12 +18,12 @@ export interface Reservation {
|
||||
objects in here? */
|
||||
|
||||
export type timeTuple = [start: string, end: string];
|
||||
export interface Timeblock extends Models.Document {
|
||||
export type Timeblock = Partial<Models.Document> & {
|
||||
boatId: string;
|
||||
start: string;
|
||||
end: string;
|
||||
selected?: false;
|
||||
}
|
||||
};
|
||||
|
||||
export interface TimeBlockTemplate {
|
||||
id: string;
|
||||
|
||||
Reference in New Issue
Block a user