mirror of
https://gitlab.dit.htwk-leipzig.de/htwk-software/htwkalender.git
synced 2025-07-25 05:49:13 +02:00
31 add page labels and meta information
This commit is contained in:
80
frontend/package-lock.json
generated
80
frontend/package-lock.json
generated
@@ -15,6 +15,7 @@
|
||||
"@fullcalendar/vue3": "^6.1.11",
|
||||
"@tanstack/vue-query": "^5.28.9",
|
||||
"@tanstack/vue-query-devtools": "^5.28.10",
|
||||
"@unhead/vue": "^1.9.10",
|
||||
"@vueuse/core": "^10.9.0",
|
||||
"pinia": "^2.1.7",
|
||||
"primeflex": "^3.3.1",
|
||||
@@ -1260,6 +1261,58 @@
|
||||
"integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@unhead/dom": {
|
||||
"version": "1.9.10",
|
||||
"resolved": "https://registry.npmjs.org/@unhead/dom/-/dom-1.9.10.tgz",
|
||||
"integrity": "sha512-F4sBrmd8kG8MEqcVTGL0Y6tXbJMdWK724pznUzefpZTs1GaVypFikLluaLt4EnICcVhOBSe4TkGrc8N21IJJzQ==",
|
||||
"dependencies": {
|
||||
"@unhead/schema": "1.9.10",
|
||||
"@unhead/shared": "1.9.10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/harlan-zw"
|
||||
}
|
||||
},
|
||||
"node_modules/@unhead/schema": {
|
||||
"version": "1.9.10",
|
||||
"resolved": "https://registry.npmjs.org/@unhead/schema/-/schema-1.9.10.tgz",
|
||||
"integrity": "sha512-3ROh0doKfA7cIcU0zmjYVvNOiJuxSOcjInL+7iOFIxQovEWr1PcDnrnbEWGJsXrLA8eqjrjmhuDqAr3JbMGsLg==",
|
||||
"dependencies": {
|
||||
"hookable": "^5.5.3",
|
||||
"zhead": "^2.2.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/harlan-zw"
|
||||
}
|
||||
},
|
||||
"node_modules/@unhead/shared": {
|
||||
"version": "1.9.10",
|
||||
"resolved": "https://registry.npmjs.org/@unhead/shared/-/shared-1.9.10.tgz",
|
||||
"integrity": "sha512-LBXxm/8ahY4FZ0FbWVaM1ANFO5QpPzvaYwjAQhgHANsrqFP2EqoGcOv1CfhdQbxg8vpGXkjI7m0r/8E9d3JoDA==",
|
||||
"dependencies": {
|
||||
"@unhead/schema": "1.9.10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/harlan-zw"
|
||||
}
|
||||
},
|
||||
"node_modules/@unhead/vue": {
|
||||
"version": "1.9.10",
|
||||
"resolved": "https://registry.npmjs.org/@unhead/vue/-/vue-1.9.10.tgz",
|
||||
"integrity": "sha512-Zi65eTU5IIaqqXAVOVJ4fnwJRR751FZIFlzYOjIekf1eNkISy+A4xyz3NIEQWSlXCrOiDNgDhT0YgKUcx5FfHQ==",
|
||||
"dependencies": {
|
||||
"@unhead/schema": "1.9.10",
|
||||
"@unhead/shared": "1.9.10",
|
||||
"hookable": "^5.5.3",
|
||||
"unhead": "1.9.10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/harlan-zw"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": ">=2.7 || >=3"
|
||||
}
|
||||
},
|
||||
"node_modules/@vitejs/plugin-vue": {
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz",
|
||||
@@ -2897,6 +2950,11 @@
|
||||
"he": "bin/he"
|
||||
}
|
||||
},
|
||||
"node_modules/hookable": {
|
||||
"version": "5.5.3",
|
||||
"resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
|
||||
"integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="
|
||||
},
|
||||
"node_modules/human-signals": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
|
||||
@@ -4338,6 +4396,20 @@
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/unhead": {
|
||||
"version": "1.9.10",
|
||||
"resolved": "https://registry.npmjs.org/unhead/-/unhead-1.9.10.tgz",
|
||||
"integrity": "sha512-Y3w+j1x1YFig2YuE+W2sER+SciRR7MQktYRHNqvZJ0iUNCCJTS8Z/SdSMUEeuFV28daXeASlR3fy7Ry3O2indg==",
|
||||
"dependencies": {
|
||||
"@unhead/dom": "1.9.10",
|
||||
"@unhead/schema": "1.9.10",
|
||||
"@unhead/shared": "1.9.10",
|
||||
"hookable": "^5.5.3"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/harlan-zw"
|
||||
}
|
||||
},
|
||||
"node_modules/update-browserslist-db": {
|
||||
"version": "1.0.13",
|
||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
|
||||
@@ -4789,6 +4861,14 @@
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/zhead": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/zhead/-/zhead-2.2.4.tgz",
|
||||
"integrity": "sha512-8F0OI5dpWIA5IGG5NHUg9staDwz/ZPxZtvGVf01j7vHqSyZ0raHY+78atOVxRqb73AotX22uV1pXt3gYSstGag==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/harlan-zw"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@
|
||||
"@fullcalendar/vue3": "^6.1.11",
|
||||
"@tanstack/vue-query": "^5.28.9",
|
||||
"@tanstack/vue-query-devtools": "^5.28.10",
|
||||
"@unhead/vue": "^1.9.10",
|
||||
"@vueuse/core": "^10.9.0",
|
||||
"pinia": "^2.1.7",
|
||||
"primeflex": "^3.3.1",
|
||||
|
2
frontend/public/robots.txt
Normal file
2
frontend/public/robots.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
User-agent: *
|
||||
Allow: /
|
@@ -18,11 +18,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
<script lang="ts" setup>
|
||||
import MenuBar from "./components/MenuBar.vue";
|
||||
import { RouteRecordName, RouterView } from "vue-router";
|
||||
import { RouteRecordName, RouterView, useRoute, useRouter } from "vue-router";
|
||||
import { useHead } from "@unhead/vue";
|
||||
import CalendarPreview from "./components/CalendarPreview.vue";
|
||||
import moduleStore from "./store/moduleStore.ts";
|
||||
import { provide, ref } from "vue";
|
||||
import { computed, provide, ref } from "vue";
|
||||
import { VueQueryDevtools } from "@tanstack/vue-query-devtools";
|
||||
import { useI18n } from "vue-i18n";
|
||||
const { t } = useI18n({ useScope: "global" });
|
||||
|
||||
const disabledPages = [
|
||||
"room-finder",
|
||||
@@ -36,6 +39,33 @@ const disabledPages = [
|
||||
"room-schedule",
|
||||
];
|
||||
|
||||
// Provide canonical link for SEO
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
const baseUri = "https://cal.htwk-leipzig.de"; // could be stored in .env
|
||||
const canonical = computed(() => `${baseUri}${router.resolve(route.name ? { name: route.name } : route).path}`);
|
||||
const title = computed(() => route.meta.label?
|
||||
`HTWKalender - ${t(String(route.meta.label))}`:
|
||||
"HTWKalender"
|
||||
);
|
||||
|
||||
useHead({
|
||||
title: title,
|
||||
link: [
|
||||
{ rel: "canonical", href: canonical},
|
||||
],
|
||||
meta: [
|
||||
{
|
||||
name: "description",
|
||||
content: "Dein individueller Stundenplan mit Sportevents und Prüfungen. Finde kommende Veranstaltungen oder freie Räume zum Lernen und Arbeiten.",
|
||||
},
|
||||
{
|
||||
name: "keywords",
|
||||
content: "HTWK Leipzig, Stundenplan, iCal, freie Räume, Lerngruppen, Sport, Prüfungen",
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
const store = moduleStore();
|
||||
const mobilePage = ref(true);
|
||||
provide("mobilePage", mobilePage);
|
||||
|
@@ -102,12 +102,13 @@ function handleDarkModeToggled(isDarkVar: boolean) {
|
||||
"
|
||||
v-bind="props.action"
|
||||
@click="navigate"
|
||||
:href="item.route"
|
||||
>
|
||||
<span :class="item.icon" />
|
||||
<span class="ml-2 p-menuitem-label">{{ item.label }}</span>
|
||||
</a>
|
||||
</router-link>
|
||||
<a
|
||||
<span
|
||||
v-else
|
||||
:class="
|
||||
$route.path.includes(item.info)
|
||||
@@ -115,11 +116,10 @@ function handleDarkModeToggled(isDarkVar: boolean) {
|
||||
: 'flex align-items-center'
|
||||
"
|
||||
v-bind="props.action"
|
||||
:href="item.url"
|
||||
>
|
||||
<span :class="item.icon" />
|
||||
<span class="ml-2 p-menuitem-label">{{ item.label }}</span>
|
||||
</a>
|
||||
</span>
|
||||
</template>
|
||||
<template #end>
|
||||
<div class="flex align-items-stretch justify-content-center">
|
||||
|
@@ -17,6 +17,7 @@
|
||||
import "source-sans/source-sans-3.css";
|
||||
|
||||
import { createApp } from "vue";
|
||||
import { createHead } from "@unhead/vue";
|
||||
import "./style.css";
|
||||
import App from "./App.vue";
|
||||
import PrimeVue from "primevue/config";
|
||||
@@ -69,6 +70,9 @@ app.use(VueQueryPlugin, {
|
||||
},
|
||||
});
|
||||
|
||||
const head = createHead();
|
||||
app.use(head);
|
||||
|
||||
app.use(PrimeVue);
|
||||
app.use(router);
|
||||
app.use(ToastService);
|
||||
|
@@ -37,46 +37,73 @@ const router = createRouter({
|
||||
path: "/",
|
||||
name: "course-selection",
|
||||
component: CourseSelection,
|
||||
meta: {
|
||||
label: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/rooms/occupancy",
|
||||
name: "room-schedule",
|
||||
component: RoomFinder,
|
||||
meta: {
|
||||
label: "roomFinderPage.roomSchedule",
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/rooms/free",
|
||||
name: "free-rooms",
|
||||
component: FreeRooms,
|
||||
meta: {
|
||||
label: "freeRooms.freeRooms",
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/faq",
|
||||
name: "faq",
|
||||
component: Faq,
|
||||
meta: {
|
||||
label: "faq",
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/additional-modules",
|
||||
name: "additional-modules",
|
||||
component: AdditionalModules,
|
||||
meta: {
|
||||
label: "createCalendar",
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/edit-additional-modules",
|
||||
name: "edit-additional-modules",
|
||||
component: EditAdditionalModules,
|
||||
meta: {
|
||||
label: "editCalendar",
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/edit-calendar",
|
||||
name: "edit-calendar",
|
||||
component: EditModules,
|
||||
meta: {
|
||||
label: "editCalendar",
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/calendar-link",
|
||||
name: "calendar-link",
|
||||
component: CalendarLink,
|
||||
meta: {
|
||||
label: "createCalendar"
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/edit",
|
||||
name: "edit",
|
||||
component: EditCalendarView,
|
||||
meta: {
|
||||
label: "editCalendar",
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/privacy-policy",
|
||||
@@ -86,6 +113,9 @@ const router = createRouter({
|
||||
window.location.href =
|
||||
"https://www.htwk-leipzig.de/hochschule/kontakt/datenschutzerklaerung/";
|
||||
},
|
||||
meta: {
|
||||
label: "privacy"
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/imprint",
|
||||
@@ -95,11 +125,17 @@ const router = createRouter({
|
||||
window.location.href =
|
||||
"https://www.htwk-leipzig.de/hochschule/kontakt/impressum/";
|
||||
},
|
||||
meta: {
|
||||
label: "imprint"
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/rename-modules",
|
||||
name: "rename-modules",
|
||||
component: RenameModules,
|
||||
meta: {
|
||||
label: "createCalendar"
|
||||
}
|
||||
},
|
||||
],
|
||||
});
|
||||
|
@@ -42,18 +42,18 @@ const hasContent = computed(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-column align-items-center mt-0">
|
||||
<heading class="flex flex-column align-items-center mt-0">
|
||||
<div
|
||||
class="flex align-items-center justify-content-center gap-3 mx-2 mb-4 transition-rolldown"
|
||||
:class="{ 'md:mt-8': hideContent }"
|
||||
>
|
||||
<h3 class="text-4xl">
|
||||
<h1 class="text-4xl">
|
||||
{{ headline }}
|
||||
</h3>
|
||||
</h1>
|
||||
<i v-if="icon" :class="icon" style="font-size: 2rem"></i>
|
||||
</div>
|
||||
<div v-if="subTitle" class="flex justify-content-center">
|
||||
<h5 class="text-2xl m-2">{{ subTitle }}</h5>
|
||||
<p class="subtitle text-2xl m-2">{{ subTitle }}</p>
|
||||
</div>
|
||||
<div class="flex flex-wrap mx-0 gap-2 my-4 w-full lg:w-8">
|
||||
<slot name="selection" flex-specs="flex-1 m-0"></slot>
|
||||
@@ -87,11 +87,15 @@ const hasContent = computed(() => {
|
||||
>
|
||||
<slot name="content"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</heading>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.transition-rolldown {
|
||||
transition: margin-top 0.5s ease-in-out;
|
||||
}
|
||||
.subtitle {
|
||||
font-weight: 100;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
</style>
|
||||
|
Reference in New Issue
Block a user