Skip to content

Commit

Permalink
basic impementation of a calendar
Browse files Browse the repository at this point in the history
  • Loading branch information
CommanderStorm committed Apr 21, 2023
1 parent fb9ebb8 commit 2ad0d7a
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 2 deletions.
3 changes: 2 additions & 1 deletion webclient/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"swagger-ui-dist": "^5.0.0-alpha.0",
"swaggerdark": "github:octycs/SwaggerDark#f02d394c8ff698cdd93e09c2188b058d2d686ca3",
"vue": "^3.2.45",
"vue-router": "^4.1.6"
"vue-router": "^4.1.6",
"vue-simple-calendar": "^6.3.1"
},
"devDependencies": {
"@intlify/unplugin-vue-i18n": "^0.8.1",
Expand Down
2 changes: 2 additions & 0 deletions webclient/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script setup lang="ts">
import AppSearchBar from "@/components/AppSearchBar.vue";
import CalendarModal from "@/components/CalendarModal.vue";
import AppLanguageToggler from "@/components/AppLanguageToggler.vue";
import AppThemeToggler from "@/components/AppThemeToggler.vue";
import { useGlobalStore } from "@/stores/global";
Expand Down Expand Up @@ -129,6 +130,7 @@ const global = useGlobalStore();
</div>
</footer>
<FeedbackModal v-if="global.feedback.open" />
<CalendarModal v-if="global.calendar.open" />
<!-- General message modal -->
<div class="modal active" v-if="global.information_modal?.body">
<div class="modal-overlay" @click="global.information_modal.body = null"></div>
Expand Down
105 changes: 105 additions & 0 deletions webclient/src/components/CalendarModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<script setup lang="ts">
import { CalendarView, CalendarViewHeader } from "vue-simple-calendar";
import { ref, watch } from "vue";
import type { ICalendarItem } from "vue-simple-calendar/dist/src/ICalendarItem";
import { useGlobalStore } from "@/stores/global";
import { useRoute } from "vue-router";
import type { components } from "@/api_types";
type CalendarResponse = components["schemas"]["CalendarResponse"];
import "/node_modules/vue-simple-calendar/dist/style.css";
import "/node_modules/vue-simple-calendar/dist/css/default.css";
import { useFetch } from "@/utils/fetch";
const global = useGlobalStore();
const showDate = ref(new Date());
const tumonlineCalendarUrl = ref("https://campus.tum.de/tumonline");
const lastmod = ref("xx.xx.xxxx xx:xx");
const events = ref<ICalendarItem[]>([]);
const route = useRoute();
// called when the view is loaded
update();
// called when the view navigates to another view, but not when its initially loaded
watch(() => showDate.value, update);
watch(() => route.params.id, update);
function update() {
// If we set the items like this, switching between months works without a problem
const start = new Date(showDate.value);
start.setDate(start.getDate() - 60);
const end = new Date(showDate.value);
end.setDate(end.getDate() + 60);
const startString = start.toISOString().replace("Z", "");
const endString = end.toISOString().replace("Z", "");
console.table({ startString, endString });
useFetch<CalendarResponse>(`/api/calendar/${route.params.id}?start=${startString}&end=${endString}`, (d) => {
console.log(d);
tumonlineCalendarUrl.value = d.calendar_url;
lastmod.value = d.lastmod;
events.value = d.events.map((e) => ({
id: e.id,
title: e.title,
startDate: new Date(e.start),
endDate: new Date(e.end),
classes: e.classes,
}));
});
}
function setShowDate(d) {
showDate.value = d;
}
</script>
<template>
<div class="modal modal-lg active" id="calendar-modal">
<a @click="global.calendar.open = false" class="modal-overlay" aria-label="Close"></a>
<div class="modal-container">
<div class="modal-header">
<a @click="global.calendar.open = false" class="btn btn-clear float-right" aria-label="Close"></a>
<div class="modal-title h5">Calendar</div>
</div>
<div class="modal-body">
<div class="modal-body">
<CalendarView
id="calendar-view"
:items="global.calendar.events"
:show-date="showDate"
:startingDayOfWeek="1"
class="theme-default"
>
<template #header="{ headerProps }">
<CalendarViewHeader :header-props="headerProps" @input="setShowDate" />
</template>
</CalendarView>
</div>
</div>
<div class="modal-footer">
Events are updated daily, if in doubt, please check the
<a v-bind:href="global.calendar.url || 'https://campus.tum.de'">official calendar on TUMonline</a>. <br />
Last update: {{ lastmod }}
</div>
</div>
</div>
</template>
<style lang="scss">
#calendar-modal {
.modal-container {
position: relative;
top: 5em;
height: auto;
max-width: 100vw !important;
max-height: 90vh !important;
.modal-body {
padding: 0;
height: 50rem;
#calendar-view {
display: flex;
flex-direction: column;
flex-grow: 1;
}
}
}
}
</style>
3 changes: 3 additions & 0 deletions webclient/src/stores/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ export const useGlobalStore = defineStore({
state: () => ({
search_focused: false,
error_message: null,
calendar: {
open: false,
},
information_modal: {
header: null as string | null,
body: null as string | null,
Expand Down
4 changes: 3 additions & 1 deletion webclient/src/views/DetailsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { useI18n } from "vue-i18n";
import { getLocalStorageWithExpiry, removeLocalStorage } from "@/utils/storage";
import { copyCurrentLink, setDescription, setTitle } from "@/utils/common";
import { selectedMap, useDetailsStore } from "@/stores/details";
import { useGlobalStore } from "@/stores/global";
import { nextTick, onMounted, ref, watch } from "vue";
import { useFetch } from "@/utils/fetch";
import { useRoute } from "vue-router";
Expand Down Expand Up @@ -62,6 +63,7 @@ function update() {
});
}
const global = useGlobalStore();
const state = useDetailsStore();
const copied = ref(false);
// Coordinate picker states
Expand Down Expand Up @@ -250,7 +252,7 @@ onMounted(() => {
<a
class="btn btn-link btn-action btn-sm"
v-if="state.data?.props?.calendar_url"
v-bind:href="state.data.props.calendar_url"
@click="global.calendar.open = true"
target="_blank"
v-bind:title="$t('view_view.header.calendar')"
>
Expand Down

0 comments on commit 2ad0d7a

Please sign in to comment.