mirror of
https://gitlab.dit.htwk-leipzig.de/htwk-software/htwkalender.git
synced 2025-07-24 21:39:14 +02:00
115 refactor dynamic page component
This commit is contained in:
@@ -47,7 +47,7 @@ function nextStep() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex flex-column mx-8 mt-2 w-full">
|
<div class="flex flex-column w-full">
|
||||||
<Button
|
<Button
|
||||||
:disabled="store.isEmpty()"
|
:disabled="store.isEmpty()"
|
||||||
class="col-12 md:col-4 mb-3 align-self-end"
|
class="col-12 md:col-4 mb-3 align-self-end"
|
||||||
|
@@ -4,6 +4,7 @@ import {
|
|||||||
fetchCourse,
|
fetchCourse,
|
||||||
fetchModulesByCourseAndSemester,
|
fetchModulesByCourseAndSemester,
|
||||||
} from "../api/fetchCourse";
|
} from "../api/fetchCourse";
|
||||||
|
import DynamicPage from "./DynamicPage.vue";
|
||||||
import ModuleSelection from "../components/ModuleSelection.vue";
|
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";
|
||||||
@@ -52,27 +53,13 @@ async function getModules() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<DynamicPage
|
||||||
class="flex flex-column align-items-center transition-all transition-duration-500 transition-ease-in-out mt-0"
|
:hideContent="selectedCourse.name === ''"
|
||||||
:class="{'md:mt-8': selectedCourse.name === ''}"
|
:headline="$t('courseSelection.headline')"
|
||||||
|
:subTitle="$t('courseSelection.subTitle')"
|
||||||
|
icon="pi pi-calendar"
|
||||||
>
|
>
|
||||||
<div class="flex align-items-center justify-content-center gap-2 mx-2">
|
<template #selection>
|
||||||
<h3 class="text-4xl">
|
|
||||||
{{ $t("courseSelection.headline") }}
|
|
||||||
</h3>
|
|
||||||
<i
|
|
||||||
class="pi pi-calendar"
|
|
||||||
style="font-size: 2rem"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="flex justify-content-center"
|
|
||||||
>
|
|
||||||
<h5 class="text-2xl m-2">{{ $t("courseSelection.subTitle") }}</h5>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="flex flex-wrap mx-0 gap-2 my-4 w-full lg:w-8"
|
|
||||||
>
|
|
||||||
<Dropdown
|
<Dropdown
|
||||||
v-model="selectedCourse"
|
v-model="selectedCourse"
|
||||||
:options="countries"
|
:options="countries"
|
||||||
@@ -92,11 +79,12 @@ async function getModules() {
|
|||||||
:placeholder="$t('courseSelection.semesterDropDown')"
|
:placeholder="$t('courseSelection.semesterDropDown')"
|
||||||
@change="getModules()"
|
@change="getModules()"
|
||||||
></Dropdown>
|
></Dropdown>
|
||||||
</div>
|
</template>
|
||||||
<ModuleSelection
|
<template #content>
|
||||||
:modules="modules"
|
<ModuleSelection
|
||||||
:selected-course="selectedCourse.name"
|
:modules="modules"
|
||||||
class="lg:w-8"
|
:selected-course="selectedCourse.name"
|
||||||
/>
|
/>
|
||||||
</div>
|
</template>
|
||||||
|
</DynamicPage>
|
||||||
</template>
|
</template>
|
||||||
|
63
frontend/src/view/DynamicPage.vue
Normal file
63
frontend/src/view/DynamicPage.vue
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed, useSlots } from 'vue';
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
hideContent: Boolean,
|
||||||
|
headline: String,
|
||||||
|
subTitle?: String,
|
||||||
|
icon?: String,
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const slots = useSlots()
|
||||||
|
const hasSlot = (name:string) => {
|
||||||
|
return !!slots[name];
|
||||||
|
}
|
||||||
|
const hasContent = computed(() => {
|
||||||
|
return hasSlot('content')
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="flex flex-column align-items-center transition-all transition-duration-500 transition-ease-in-out mt-0"
|
||||||
|
:class="{'md:mt-8': hideContent}"
|
||||||
|
>
|
||||||
|
<div class="flex align-items-center justify-content-center gap-2 mx-2">
|
||||||
|
<h3 class="text-4xl">
|
||||||
|
{{ headline }}
|
||||||
|
</h3>
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="flex flex-wrap mx-0 gap-2 my-4 w-full lg:w-8"
|
||||||
|
>
|
||||||
|
<slot
|
||||||
|
name="selection"
|
||||||
|
class="flex-1 m-0"
|
||||||
|
></slot>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="hasContent"
|
||||||
|
:class="
|
||||||
|
[hideContent?
|
||||||
|
['opacity-0', 'pointer-events-none', 'h-1rem', 'overflow-hidden'] :
|
||||||
|
['opacity-100', 'transition-all', 'transition-duration-500', 'transition-ease-in-out']
|
||||||
|
,
|
||||||
|
'w-full', 'lg:w-8']"
|
||||||
|
>
|
||||||
|
<slot
|
||||||
|
name="content"
|
||||||
|
></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
@@ -1,6 +1,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { Ref, ref } from "vue";
|
import { Ref, ref } from "vue";
|
||||||
import { fetchRoom } from "../api/fetchRoom.ts";
|
import { fetchRoom } from "../api/fetchRoom.ts";
|
||||||
|
import DynamicPage from "./DynamicPage.vue";
|
||||||
import RoomOccupation from "../components/RoomOccupation.vue";
|
import RoomOccupation from "../components/RoomOccupation.vue";
|
||||||
|
|
||||||
const rooms = async () => {
|
const rooms = async () => {
|
||||||
@@ -19,27 +20,13 @@ rooms().then(
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<DynamicPage
|
||||||
class="flex flex-column align-items-center transition-all transition-duration-500 transition-ease-in-out mt-0"
|
:hideContent="selectedRoom.name === ''"
|
||||||
:class="{'md:mt-8': selectedRoom.name === ''}"
|
:headline="$t('roomFinderPage.headline')"
|
||||||
|
:subTitle="$t('roomFinderPage.detail')"
|
||||||
|
icon="pi pi-search"
|
||||||
>
|
>
|
||||||
<div class="flex align-items-center justify-content-center gap-2 mx-2">
|
<template #selection>
|
||||||
<h3 class="text-4xl">
|
|
||||||
{{ $t("roomFinderPage.headline") }}
|
|
||||||
</h3>
|
|
||||||
<i
|
|
||||||
class="pi pi-search"
|
|
||||||
style="font-size: 2rem"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="flex justify-content-center"
|
|
||||||
>
|
|
||||||
<h5 class="text-2xl m-2">{{ $t("roomFinderPage.detail") }}</h5>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="flex flex-wrap mx-0 gap-2 my-4 w-full lg:w-8"
|
|
||||||
>
|
|
||||||
<Dropdown
|
<Dropdown
|
||||||
v-model="selectedRoom"
|
v-model="selectedRoom"
|
||||||
:options="roomsList"
|
:options="roomsList"
|
||||||
@@ -50,18 +37,11 @@ rooms().then(
|
|||||||
:empty-message="$t('roomFinderPage.noRoomsAvailable')"
|
:empty-message="$t('roomFinderPage.noRoomsAvailable')"
|
||||||
:auto-filter-focus="true"
|
:auto-filter-focus="true"
|
||||||
/>
|
/>
|
||||||
</div>
|
</template>
|
||||||
<div
|
<template #content>
|
||||||
:class="
|
|
||||||
[selectedRoom.name === ''?
|
|
||||||
['opacity-0', 'pointer-events-none', 'h-1rem', 'overflow-hidden'] :
|
|
||||||
['opacity-100', 'transition-all', 'transition-duration-500', 'transition-ease-in-out']
|
|
||||||
,
|
|
||||||
'w-full', 'lg:w-8']"
|
|
||||||
>
|
|
||||||
<RoomOccupation
|
<RoomOccupation
|
||||||
:room="selectedRoom.name"
|
:room="selectedRoom.name"
|
||||||
/>
|
/>
|
||||||
</div>
|
</template>
|
||||||
</div>
|
</DynamicPage>
|
||||||
</template>
|
</template>
|
||||||
|
Reference in New Issue
Block a user