add static site generation including robots.txt and sitemap.xml

This commit is contained in:
survellow
2024-07-03 17:33:12 +02:00
parent a003ba736c
commit cf638cf93c
31 changed files with 846 additions and 923 deletions

1
frontend/.gitignore vendored
View File

@ -10,6 +10,7 @@ lerna-debug.log*
node_modules node_modules
dist dist
dist-ssr dist-ssr
.vite-ssg-temp
*.local *.local
# Editor directories and files # Editor directories and files

View File

@ -1,5 +1,5 @@
<!doctype html> <!doctype html>
<html<!--app-html-attrs--> lang="en"> <html lang="de">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" sizes="32x32" /> <link rel="icon" href="/favicon.ico" sizes="32x32" />
@ -12,13 +12,9 @@
href="/themes/lara-light-blue/theme.css" href="/themes/lara-light-blue/theme.css"
/> />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>HTWKalender</title>
<!--app-head-tags-->
</head> </head>
<body<!--app-body-attrs-->> <body>
<!--app-body-tags-open-->
<div id="app"><!--app-html--></div> <div id="app"><!--app-html--></div>
<script type="module" src="/src/entry-client.ts"></script> <script type="module" src="/src/main.ts"></script>
<!--app-body-tags-->
</body> </body>
</html> </html>

File diff suppressed because it is too large Load Diff

View File

@ -4,10 +4,8 @@
"version": "0.0.0", "version": "0.0.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "node src/server", "dev": "vite",
"build": "vue-tsc && npm run build:client && npm run build:server", "build": "vue-tsc && vite-ssg build",
"build:client": "vite build --outDir dist/client",
"build:server": "vite build --outDir dist/server --ssr src/entry-server.ts",
"preview": "vite preview", "preview": "vite preview",
"lint": "eslint --ext .js,.vue --ignore-path .gitignore --fix src", "lint": "eslint --ext .js,.vue --ignore-path .gitignore --fix src",
"lint-no-fix": "eslint --ext .js,.vue --ignore-path .gitignore src", "lint-no-fix": "eslint --ext .js,.vue --ignore-path .gitignore src",
@ -25,14 +23,12 @@
"@unhead/ssr": "^1.9.14", "@unhead/ssr": "^1.9.14",
"@unhead/vue": "^1.9.10", "@unhead/vue": "^1.9.10",
"@vueuse/core": "^10.9.0", "@vueuse/core": "^10.9.0",
"compression": "^1.7.4",
"express": "^4.19.2",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"primeflex": "^3.3.1", "primeflex": "^3.3.1",
"primeicons": "^6.0.1", "primeicons": "^6.0.1",
"primevue": "^3.50.0", "primevue": "^3.50.0",
"sirv": "^2.0.4",
"source-sans": "^3.46.0", "source-sans": "^3.46.0",
"vite-ssg": "^0.23.7",
"vue": "^3.4.11", "vue": "^3.4.11",
"vue-i18n": "^9.10.2", "vue-i18n": "^9.10.2",
"vue-router": "^4.3.0" "vue-router": "^4.3.0"
@ -52,6 +48,7 @@
"terser": "^5.31.0", "terser": "^5.31.0",
"typescript": "^5.4.3", "typescript": "^5.4.3",
"vite": "^5.2.7", "vite": "^5.2.7",
"vite-ssg-sitemap": "^0.7.1",
"vitest": "^1.4.0", "vitest": "^1.4.0",
"vue-tsc": "^1.8.27" "vue-tsc": "^1.8.27"
} }

View File

@ -1,2 +0,0 @@
User-agent: *
Allow: /

View File

@ -19,7 +19,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
<script lang="ts" setup> <script lang="ts" setup>
import MenuBar from "./components/MenuBar.vue"; import MenuBar from "./components/MenuBar.vue";
import { RouteRecordName, RouterView, useRoute, useRouter } from "vue-router"; import { RouteRecordName, RouterView, useRoute, useRouter } from "vue-router";
import { useHead, useServerSeoMeta } from "@unhead/vue"; import { useHead, useServerHead, useServerSeoMeta } from "@unhead/vue";
import CalendarPreview from "./components/CalendarPreview.vue"; import CalendarPreview from "./components/CalendarPreview.vue";
import moduleStore from "./store/moduleStore.ts"; import moduleStore from "./store/moduleStore.ts";
import { computed, provide, ref } from "vue"; import { computed, provide, ref } from "vue";
@ -42,7 +42,10 @@ const disabledPages = [
// Provide canonical link for SEO // Provide canonical link for SEO
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const baseUri = "https://cal.htwk-leipzig.de"; // could be stored in .env
const domain = "cal.htwk-leipzig.de"
provide('domain', domain);
const baseUri = "https://" + domain;
const canonical = computed(() => `${baseUri}${router.resolve(route.name ? { name: route.name } : route).path}`); const canonical = computed(() => `${baseUri}${router.resolve(route.name ? { name: route.name } : route).path}`);
const title = computed(() => route.meta.label? const title = computed(() => route.meta.label?
`HTWKalender - ${t(String(route.meta.label))}`: `HTWKalender - ${t(String(route.meta.label))}`:
@ -64,6 +67,10 @@ useHead({
] ]
}); });
// SEO optimization
useServerHead({
title: title
});
useServerSeoMeta( useServerSeoMeta(
{ {
title: title, title: title,

View File

@ -17,6 +17,9 @@
import { Module } from "../model/module.ts"; import { Module } from "../model/module.ts";
export async function createIndividualFeed(modules: Module[]): Promise<string> { export async function createIndividualFeed(modules: Module[]): Promise<string> {
if (import.meta.env.SSR) {
return "";
}
try { try {
const response = await fetch("/api/feed", { const response = await fetch("/api/feed", {
method: "POST", method: "POST",
@ -62,6 +65,9 @@ export async function saveIndividualFeed(
token: string, token: string,
modules: Module[], modules: Module[],
): Promise<string> { ): Promise<string> {
if (import.meta.env.SSR) {
return "";
}
await fetch("/api/collections/feeds/records/" + token, { await fetch("/api/collections/feeds/records/" + token, {
method: "PATCH", method: "PATCH",
headers: { headers: {
@ -81,6 +87,9 @@ export async function saveIndividualFeed(
} }
export async function deleteIndividualFeed(token: string): Promise<void> { export async function deleteIndividualFeed(token: string): Promise<void> {
if (import.meta.env.SSR) {
return;
}
await fetch("/api/feed?token=" + token, { await fetch("/api/feed?token=" + token, {
method: "DELETE", method: "DELETE",
}) })

View File

@ -19,6 +19,9 @@
import { Module } from "../model/module.ts"; import { Module } from "../model/module.ts";
export async function fetchCourse(): Promise<string[]> { export async function fetchCourse(): Promise<string[]> {
if (import.meta.env.SSR) {
return [];
}
const courses: string[] = []; const courses: string[] = [];
await fetch("/api/courses") await fetch("/api/courses")
.then((response) => { .then((response) => {
@ -39,6 +42,9 @@ export async function fetchCourse(): Promise<string[]> {
export async function fetchCourseBySemester( export async function fetchCourseBySemester(
semester: string, semester: string,
): Promise<string[]> { ): Promise<string[]> {
if (import.meta.env.SSR) {
return [];
}
const courses: string[] = []; const courses: string[] = [];
await fetch("/api/courses/events?semester=" + semester) await fetch("/api/courses/events?semester=" + semester)
.then((response) => { .then((response) => {
@ -60,6 +66,9 @@ export async function fetchModulesByCourseAndSemester(
course: string, course: string,
semester: string, semester: string,
): Promise<Module[]> { ): Promise<Module[]> {
if (import.meta.env.SSR) {
return [];
}
const modules: Module[] = []; const modules: Module[] = [];
await fetch("/api/course/modules?course=" + course + "&semester=" + semester) await fetch("/api/course/modules?course=" + course + "&semester=" + semester)
.then((response) => { .then((response) => {
@ -86,6 +95,9 @@ export async function fetchModulesByCourseAndSemester(
} }
export async function fetchAllModules(): Promise<Module[]> { export async function fetchAllModules(): Promise<Module[]> {
if (import.meta.env.SSR) {
return [];
}
const modules: Module[] = []; const modules: Module[] = [];
await fetch("/api/modules") await fetch("/api/modules")
.then((response) => { .then((response) => {

View File

@ -17,6 +17,9 @@
// function to fetch course data from the API // function to fetch course data from the API
export async function fetchEventTypes(): Promise<string[]> { export async function fetchEventTypes(): Promise<string[]> {
if (import.meta.env.SSR) {
return [];
}
const eventTypes: string[] = []; const eventTypes: string[] = [];
await fetch("/api/events/types") await fetch("/api/events/types")
.then((response) => { .then((response) => {

View File

@ -17,6 +17,9 @@
import { Module } from "../model/module"; import { Module } from "../model/module";
export async function fetchModule(module: Module): Promise<Module> { export async function fetchModule(module: Module): Promise<Module> {
if (import.meta.env.SSR) {
return new Module("", "", "", "", "", "", "", false, []);
}
// request to the data-manager on /api/module with query parameters name as the module name // request to the data-manager on /api/module with query parameters name as the module name
const request = new Request("/api/module?uuid=" + module.uuid); const request = new Request("/api/module?uuid=" + module.uuid);

View File

@ -17,6 +17,9 @@
import { AnonymizedEventDTO } from "../model/event.ts"; import { AnonymizedEventDTO } from "../model/event.ts";
export async function fetchRoom(): Promise<string[]> { export async function fetchRoom(): Promise<string[]> {
if (import.meta.env.SSR) {
return [];
}
const rooms: string[] = []; const rooms: string[] = [];
await fetch("/api/rooms") await fetch("/api/rooms")
.then((response) => { .then((response) => {
@ -33,6 +36,9 @@ export async function fetchEventsByRoomAndDuration(
from_date: string, from_date: string,
to_date: string, to_date: string,
): Promise<AnonymizedEventDTO[]> { ): Promise<AnonymizedEventDTO[]> {
if (import.meta.env.SSR) {
return [];
}
const events: AnonymizedEventDTO[] = []; const events: AnonymizedEventDTO[] = [];
await fetch( await fetch(
"/api/schedule?room=" + room + "&from=" + from_date + "&to=" + to_date, "/api/schedule?room=" + room + "&from=" + from_date + "&to=" + to_date,

View File

@ -18,6 +18,9 @@ import { Module } from "../model/module";
import { Calendar } from "../model/calendar"; import { Calendar } from "../model/calendar";
export async function getCalender(token: string): Promise<Module[]> { export async function getCalender(token: string): Promise<Module[]> {
if (import.meta.env.SSR) {
return [];
}
const request = new Request("/api/collections/feeds/records/" + token, { const request = new Request("/api/collections/feeds/records/" + token, {
method: "GET", method: "GET",
}); });

View File

@ -19,6 +19,9 @@ export async function requestFreeRooms(
from: string, from: string,
to: string, to: string,
): Promise<string[]> { ): Promise<string[]> {
if (import.meta.env.SSR) {
return [];
}
const rooms: string[] = []; const rooms: string[] = [];
await fetch("/api/rooms/free?from=" + from + "&to=" + to) await fetch("/api/rooms/free?from=" + from + "&to=" + to)
.then((response) => { .then((response) => {

View File

@ -27,7 +27,7 @@ import {
DataTableRowUnselectEvent, DataTableRowUnselectEvent,
} from "primevue/datatable"; } from "primevue/datatable";
import { useDialog } from "primevue/usedialog"; import { useDialog } from "primevue/usedialog";
import router from "../router"; import { router } from "@/main";
import { fetchModule } from "../api/fetchModule.ts"; import { fetchModule } from "../api/fetchModule.ts";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { fetchEventTypes } from "../api/fetchEvents.ts"; import { fetchEventTypes } from "../api/fetchEvents.ts";

View File

@ -26,7 +26,7 @@ import { CalendarOptions, DatesSetArg, EventInput } from "@fullcalendar/core";
import { fetchEventsByRoomAndDuration } from "../api/fetchRoom.ts"; import { fetchEventsByRoomAndDuration } from "../api/fetchRoom.ts";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import allLocales from "@fullcalendar/core/locales-all"; import allLocales from "@fullcalendar/core/locales-all";
import router from "@/router"; import { router } from "@/main";
import { formatYearMonthDay } from "@/helpers/dates"; import { formatYearMonthDay } from "@/helpers/dates";
import { useQuery } from "@tanstack/vue-query"; import { useQuery } from "@tanstack/vue-query";
import { watch } from "vue"; import { watch } from "vue";

View File

@ -27,7 +27,7 @@ function setup() {
_i18n = createI18n({ _i18n = createI18n({
legacy: false, legacy: false,
locale: localeStore().locale, locale: localeStore().locale,
fallbackLocale: "en", fallbackLocale: "de",
messages: { messages: {
en, en,
de, de,

View File

@ -16,8 +16,7 @@
import "source-sans/source-sans-3.css"; import "source-sans/source-sans-3.css";
import { createApp } from "vue"; import { ViteSSG } from "vite-ssg";
import { createHead } from "@unhead/vue";
import "./style.css"; import "./style.css";
import App from "./App.vue"; import App from "./App.vue";
import PrimeVue from "primevue/config"; import PrimeVue from "primevue/config";
@ -36,7 +35,7 @@ import Slider from "primevue/slider";
import ToggleButton from "primevue/togglebutton"; import ToggleButton from "primevue/togglebutton";
import "primeicons/primeicons.css"; import "primeicons/primeicons.css";
import "primeflex/primeflex.css"; import "primeflex/primeflex.css";
import router from "./router"; import routes from "./router";
import SpeedDial from "primevue/speeddial"; import SpeedDial from "primevue/speeddial";
import TabView from "primevue/tabview"; import TabView from "primevue/tabview";
import TabPanel from "primevue/tabpanel"; import TabPanel from "primevue/tabpanel";
@ -57,57 +56,81 @@ import Skeleton from "primevue/skeleton";
import Calendar from "primevue/calendar"; import Calendar from "primevue/calendar";
import i18n from "./i18n"; import i18n from "./i18n";
import { VueQueryPlugin } from "@tanstack/vue-query"; import { VueQueryPlugin } from "@tanstack/vue-query";
import { Router } from "vue-router";
const app = createApp(App); var router : Router;
const pinia = createPinia();
app.use(VueQueryPlugin, { export const createApp = ViteSSG(
queryClientConfig: { App,
defaultOptions: { {
queries: { base: import.meta.env.BASE_URL,
refetchOnWindowFocus: false, routes: routes.routes,
},
},
}, },
}); (ctx) => {
const { app } = ctx;
const pinia = createPinia();
app.use(pinia);
const head = createHead(); router = ctx.router;
app.use(head);
app.use(PrimeVue); router.beforeEach(async (to, from) => {
app.use(router); const newLocale = to.params.locale;
app.use(ToastService); const prevLocale = from.params.locale;
app.use(pinia); // If the locale hasn't changed, do nothing
app.use(DialogService); if (newLocale === prevLocale) {
i18n.setup(); return;
app.use(i18n.vueI18n); }
app.component("Avatar", Avatar); i18n.setLocale(newLocale);
app.component("Badge", Badge); });
app.component("Button", Button);
app.component("Menu", Menu);
app.component("Menubar", Menubar);
app.component("Dialog", Dialog);
app.component("Dropdown", Dropdown);
app.component("InputText", InputText);
app.component("InputSwitch", InputSwitch);
app.component("Card", Card);
app.component("DataView", DataView);
app.component("Slider", Slider);
app.component("ToggleButton", ToggleButton);
app.component("SpeedDial", SpeedDial);
app.component("TabView", TabView);
app.component("TabPanel", TabPanel);
app.component("MultiSelect", MultiSelect);
app.component("Tag", Tag);
app.component("Toast", Toast);
app.component("Accordion", Accordion);
app.component("AccordionTab", AccordionTab);
app.component("DataTable", DataTable);
app.component("Column", Column);
app.component("DynamicDialog", DynamicDialog);
app.component("ProgressSpinner", ProgressSpinner);
app.component("Checkbox", Checkbox);
app.component("Skeleton", Skeleton);
app.component("Calendar", Calendar);
app.mount("#app"); app.use(VueQueryPlugin, {
queryClientConfig: {
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
},
},
},
});
//app.config.globalProperties.$hostname = "https://cal.htwk-leipzig.de"
app.use(router);
app.use(ToastService);
app.use(DialogService);
i18n.setup();
app.use(i18n.vueI18n);
app.use(PrimeVue);
app.component("Avatar", Avatar);
app.component("Badge", Badge);
app.component("Button", Button);
app.component("Menu", Menu);
app.component("Menubar", Menubar);
app.component("Dialog", Dialog);
app.component("Dropdown", Dropdown);
app.component("InputText", InputText);
app.component("InputSwitch", InputSwitch);
app.component("Card", Card);
app.component("DataView", DataView);
app.component("Slider", Slider);
app.component("ToggleButton", ToggleButton);
app.component("SpeedDial", SpeedDial);
app.component("TabView", TabView);
app.component("TabPanel", TabPanel);
app.component("MultiSelect", MultiSelect);
app.component("Tag", Tag);
app.component("Toast", Toast);
app.component("Accordion", Accordion);
app.component("AccordionTab", AccordionTab);
app.component("DataTable", DataTable);
app.component("Column", Column);
app.component("DynamicDialog", DynamicDialog);
app.component("ProgressSpinner", ProgressSpinner);
app.component("Checkbox", Checkbox);
app.component("Skeleton", Skeleton);
app.component("Calendar", Calendar);
},
)
export {router}

View File

@ -14,7 +14,7 @@
//You should have received a copy of the GNU Affero General Public License //You should have received a copy of the GNU Affero General Public License
//along with this program. If not, see <https://www.gnu.org/licenses/>. //along with this program. If not, see <https://www.gnu.org/licenses/>.
import { createMemoryHistory, createRouter, createWebHistory } from "vue-router"; import { createMemoryHistory, RouterOptions, createWebHistory } from "vue-router";
const CourseSelection = () => import("../view/CourseSelection.vue"); const CourseSelection = () => import("../view/CourseSelection.vue");
const AdditionalModules = () => import("../view/create/AdditionalModules.vue"); const AdditionalModules = () => import("../view/create/AdditionalModules.vue");
@ -28,9 +28,7 @@ const EditAdditionalModules = () =>
const EditModules = () => import("../view/edit/EditModules.vue"); const EditModules = () => import("../view/edit/EditModules.vue");
const Faq = () => import("../view/Faq.vue"); const Faq = () => import("../view/Faq.vue");
import i18n from "../i18n"; const routes : RouterOptions = {
const router = createRouter({
history: import.meta.env.SSR ? createMemoryHistory(import.meta.env.BASE_URL) : createWebHistory(import.meta.env.BASE_URL), history: import.meta.env.SSR ? createMemoryHistory(import.meta.env.BASE_URL) : createWebHistory(import.meta.env.BASE_URL),
routes: [ routes: [
{ {
@ -136,16 +134,6 @@ const router = createRouter({
} }
}, },
], ],
}); };
router.beforeEach(async (to, from) => { export default routes;
const newLocale = to.params.locale;
const prevLocale = from.params.locale;
// If the locale hasn't changed, do nothing
if (newLocale === prevLocale) {
return;
}
i18n.setLocale(newLocale);
});
export default router;

View File

@ -20,7 +20,7 @@ import { useLocalStorage } from "@vueuse/core";
const localeStore = defineStore("localeStore", { const localeStore = defineStore("localeStore", {
state: () => { state: () => {
return { return {
locale: useLocalStorage("locale", "en"), //useLocalStorage takes in a key of 'count' and default value of 0 locale: useLocalStorage("locale", "de"), //useLocalStorage takes in a key of 'count' and default value of 0
}; };
}, },
actions: { actions: {

View File

@ -19,14 +19,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
<script lang="ts" setup> <script lang="ts" setup>
import tokenStore from "@/store/tokenStore.ts"; import tokenStore from "@/store/tokenStore.ts";
import { useToast } from "primevue/usetoast"; import { useToast } from "primevue/usetoast";
import { computed, onMounted } from "vue"; import { computed, inject, onMounted } from "vue";
import router from "@/router"; import { router } from "@/main";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
const { t } = useI18n({ useScope: "global" }); const { t } = useI18n({ useScope: "global" });
const toast = useToast(); const toast = useToast();
const domain = window.location.hostname; const domain = inject<string>("domain")!;
const getLink = () => const getLink = () =>
"https://" + domain + "/api/feed?token=" + tokenStore().token; "https://" + domain + "/api/feed?token=" + tokenStore().token;

View File

@ -27,7 +27,7 @@ import ModuleSelection from "@/components/ModuleSelection.vue";
import { Module } from "@/model/module.ts"; import { Module } from "@/model/module.ts";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import moduleStore from "@/store/moduleStore"; import moduleStore from "@/store/moduleStore";
import router from "@/router"; import { router } from "@/main";
async function getModules() { async function getModules() {
modules.value = await fetchModulesByCourseAndSemester( modules.value = await fetchModulesByCourseAndSemester(

View File

@ -42,7 +42,7 @@ const hasContent = computed(() => {
</script> </script>
<template> <template>
<heading class="flex flex-column align-items-center mt-0"> <div class="flex flex-column align-items-center mt-0">
<div <div
class="flex align-items-center justify-content-center gap-3 mx-2 mb-4 transition-rolldown" class="flex align-items-center justify-content-center gap-3 mx-2 mb-4 transition-rolldown"
:class="{ 'md:mt-8': hideContent }" :class="{ 'md:mt-8': hideContent }"
@ -87,7 +87,7 @@ const hasContent = computed(() => {
> >
<slot name="content"></slot> <slot name="content"></slot>
</div> </div>
</heading> </div>
</template> </template>
<style scoped> <style scoped>

View File

@ -18,7 +18,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
<script lang="ts" setup> <script lang="ts" setup>
import moduleStore from "@/store/moduleStore"; import moduleStore from "@/store/moduleStore";
import router from "@/router"; import {router} from "@/main";
import AdditionalModuleTable from "@/components/AdditionalModuleTable.vue"; import AdditionalModuleTable from "@/components/AdditionalModuleTable.vue";
const store = moduleStore(); const store = moduleStore();

View File

@ -19,7 +19,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
<script setup lang="ts"> <script setup lang="ts">
import moduleStore from "@/store/moduleStore.ts"; import moduleStore from "@/store/moduleStore.ts";
import { createIndividualFeed } from "@/api/createFeed.ts"; import { createIndividualFeed } from "@/api/createFeed.ts";
import router from "@/router"; import { router } from "@/main";
import tokenStore from "@/store/tokenStore.ts"; import tokenStore from "@/store/tokenStore.ts";
import { Ref, computed, inject, ref, onMounted } from "vue"; import { Ref, computed, inject, ref, onMounted } from "vue";
import ModuleTemplateDialog from "@/components/ModuleTemplateDialog.vue"; import ModuleTemplateDialog from "@/components/ModuleTemplateDialog.vue";

View File

@ -19,7 +19,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
<script lang="ts" setup> <script lang="ts" setup>
import { defineAsyncComponent } from "vue"; import { defineAsyncComponent } from "vue";
import moduleStore from "@/store/moduleStore"; import moduleStore from "@/store/moduleStore";
import router from "@/router"; import { router } from "@/main";
const store = moduleStore(); const store = moduleStore();
const AdditionalModuleTable = defineAsyncComponent( const AdditionalModuleTable = defineAsyncComponent(

View File

@ -21,7 +21,7 @@ import { Ref, ref } from "vue";
import { Module } from "@/model/module"; import { Module } from "@/model/module";
import moduleStore from "@/store/moduleStore"; import moduleStore from "@/store/moduleStore";
import { getCalender } from "@/api/loadCalendar"; import { getCalender } from "@/api/loadCalendar";
import router from "@/router"; import { router } from "@/main";
import tokenStore from "@/store/tokenStore"; import tokenStore from "@/store/tokenStore";
import { useToast } from "primevue/usetoast"; import { useToast } from "primevue/usetoast";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";

View File

@ -23,7 +23,7 @@ import moduleStore from "@/store/moduleStore";
import { fetchAllModules } from "@/api/fetchCourse.ts"; import { fetchAllModules } from "@/api/fetchCourse.ts";
import { deleteIndividualFeed, saveIndividualFeed } from "@/api/createFeed.ts"; import { deleteIndividualFeed, saveIndividualFeed } from "@/api/createFeed.ts";
import tokenStore from "@/store/tokenStore"; import tokenStore from "@/store/tokenStore";
import router from "@/router"; import { router } from "@/main";
import ModuleTemplateDialog from "@/components/ModuleTemplateDialog.vue"; import ModuleTemplateDialog from "@/components/ModuleTemplateDialog.vue";
import { onlyWhitespace } from "@/helpers/strings.ts"; import { onlyWhitespace } from "@/helpers/strings.ts";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";

View File

@ -151,7 +151,7 @@ import DynamicPage from "@/view/DynamicPage.vue";
import { requestFreeRooms } from "@/api/requestFreeRooms.ts"; import { requestFreeRooms } from "@/api/requestFreeRooms.ts";
import { FilterMatchMode } from "primevue/api"; import { FilterMatchMode } from "primevue/api";
import { padStart } from "@fullcalendar/core/internal"; import { padStart } from "@fullcalendar/core/internal";
import router from "@/router"; import { router } from "@/main";
import { formatYearMonthDay } from "@/helpers/dates"; import { formatYearMonthDay } from "@/helpers/dates";
const mobilePage = inject("mobilePage") as Ref<boolean>; const mobilePage = inject("mobilePage") as Ref<boolean>;

View File

@ -22,7 +22,7 @@ import { fetchRoom } from "@/api/fetchRoom.ts";
import DynamicPage from "@/view/DynamicPage.vue"; import DynamicPage from "@/view/DynamicPage.vue";
import RoomOccupation from "@/components/RoomOccupation.vue"; import RoomOccupation from "@/components/RoomOccupation.vue";
import { computedAsync } from "@vueuse/core"; import { computedAsync } from "@vueuse/core";
import router from "@/router"; import { router } from "@/main";
type Room = { type Room = {
name: string; name: string;

View File

@ -20,7 +20,8 @@
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
"paths": { "paths": {
"@/*": ["./src/*"] "@/*": ["./src/*"],
"primevue/*": ["./node_modules/primevue/*"]
} }
}, },
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],

View File

@ -18,7 +18,12 @@ import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue"; import vue from "@vitejs/plugin-vue";
import { fileURLToPath } from "node:url"; import { fileURLToPath } from "node:url";
import resolve from "@rollup/plugin-node-resolve"; import resolve from "@rollup/plugin-node-resolve";
import {resolve as pathResolver} from "path";
import terser from "@rollup/plugin-terser"; import terser from "@rollup/plugin-terser";
import ViteSSGOptions from "vite-ssg";
import generateSitemap from 'vite-ssg-sitemap'
const hostname = "https://cal.htwk-leipzig.de";
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
@ -28,8 +33,27 @@ export default defineConfig({
terser(), terser(),
], ],
resolve: { resolve: {
alias: { alias:
"@": fileURLToPath(new URL("./src", import.meta.url)), {
"@": fileURLToPath(new URL("./src", import.meta.url)),
'primevue' : pathResolver(__dirname, 'node_modules/primevue'),
},
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.css', '.scss'],
},
ssgOptions: {
script: "async",
formatting: "minify",
format: "esm",
onFinished: () => {
generateSitemap({
hostname: hostname,
exclude: [
'/additional-modules',
'/edit-additional-modules',
'/edit-calendar',
'/rename-modules',
]
})
}, },
}, },
server: { server: {