253 lines
7.4 KiB
Vue
253 lines
7.4 KiB
Vue
<script setup>
|
|
import {reactive, onMounted} from 'vue';
|
|
import Icon from "../../../app/Views/Components/Icon.vue";
|
|
import GlobalWidgets from "../../../app/Views/Partials/GlobalWidgets/GlobalWidgets.vue";
|
|
import {toast} from "vue3-toastify";
|
|
import {useAjax} from "../components/ajaxHandler.js";
|
|
|
|
const { request } = useAjax()
|
|
|
|
const globalProps = reactive({
|
|
navbar: {
|
|
personal: [],
|
|
common: [],
|
|
costunits: [],
|
|
events: [],
|
|
},
|
|
tenant: '',
|
|
user: null,
|
|
currentPath: '/',
|
|
errors: {},
|
|
availableLocalGroups: [],
|
|
message: ''
|
|
});
|
|
|
|
onMounted(async () => {
|
|
const response = await fetch('/api/v1/core/retrieve-global-data');
|
|
const data = await response.json();
|
|
Object.assign(globalProps, data);
|
|
|
|
const messageResponse = await request('/api/v1/core/retrieve-messages', {
|
|
method: 'GET',
|
|
})
|
|
|
|
if (messageResponse.message !== '') {
|
|
if (messageResponse.messageType === 'success') {
|
|
toast.success(messageResponse.message)
|
|
} else {
|
|
toast.error(messageResponse.message)
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const currentPath = window.location.pathname;
|
|
|
|
const props = defineProps({
|
|
title: { type: String, default: 'App' },
|
|
flash: { type: Object, default: () => ({}) }
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div class="app-layout">
|
|
<!-- Sidebar -->
|
|
<!-- Main content -->
|
|
<div class="main">
|
|
<!-- Header -->
|
|
<div class="flexbox">
|
|
<div class="sidebar">
|
|
<div class="logo">
|
|
<img src="../../../public/images/logo.png" alt="Logo" />
|
|
|
|
</div>
|
|
<nav class="nav">
|
|
<ul class="nav-links" v-if="globalProps.navbar.personal.length > 0">
|
|
<li v-for="navlink in globalProps.navbar.personal">
|
|
<a
|
|
:class="{ navlink_active: navlink.url.endsWith(currentPath) }"
|
|
:href="navlink.url"
|
|
>{{navlink.display}}</a>
|
|
</li>
|
|
</ul>
|
|
<ul class="nav-links" v-if="globalProps.navbar.common.length > 0">
|
|
<li v-for="navlink in globalProps.navbar.common">
|
|
<a
|
|
:class="{ navlink_active: navlink.url.endsWith(currentPath) }"
|
|
:href="navlink.url"
|
|
>{{navlink.display}}</a>
|
|
</li>
|
|
</ul>
|
|
|
|
<ul class="nav-links" v-if="globalProps.navbar.costunits.length > 0">
|
|
<li v-for="navlink in globalProps.navbar.costunits">
|
|
<a
|
|
:class="{ navlink_active: navlink.url.endsWith(currentPath) }"
|
|
:href="navlink.url"
|
|
>{{navlink.display}}</a>
|
|
</li>
|
|
</ul>
|
|
|
|
<ul class="nav-links" v-if="globalProps.navbar.events.length > 0">
|
|
<li v-for="navlink in globalProps.navbar.events">
|
|
<a
|
|
:class="{ navlink_active: navlink.url.endsWith(currentPath) }"
|
|
:href="navlink.url"
|
|
>{{navlink.display}}</a>
|
|
</li>
|
|
</ul>
|
|
|
|
</nav>
|
|
</div>
|
|
|
|
<div class="main">
|
|
<div class="header">
|
|
<div class="left-side">
|
|
<h1>{{ props.title }}</h1>
|
|
<label id="show_username" v-if="globalProps.user !== null">Willkommen, {{ globalProps.user.nicename }}</label>
|
|
</div>
|
|
<div class="user-info" v-if="globalProps.user !== null">
|
|
<a href="/messages" class="header-link-anonymous" title="Meine Nachrichten">
|
|
<Icon name="envelope" />
|
|
</a>
|
|
|
|
<a href="/profile" class="header-link-anonymous" title="Mein Profil">
|
|
<Icon name="user" />
|
|
</a>
|
|
|
|
<a href="/logout" class="header-link-anonymous-logout" title="Abmelden">
|
|
<Icon name="lock" />
|
|
</a>
|
|
|
|
</div>
|
|
<div class="anonymous-actions" v-else>
|
|
<a href="/register" class="header-link-anonymous">Registrieren</a>
|
|
<a href="/login" class="header-link-anonymous"> Anmelden </a>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<global-widgets :user="globalProps.user" :tenant="globalProps.tenant" v-if="globalProps.user !== null" />
|
|
<div class="content">
|
|
<slot />
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
<!-- Footer -->
|
|
<footer class="footer">
|
|
<table>
|
|
<tr>
|
|
<td>Version 4.0.0</td>
|
|
<td>
|
|
mareike - Mdodernes Anmeldesystem und richti einfache Kostenerfassung
|
|
</td>
|
|
<td>
|
|
Impressum
|
|
</td>
|
|
<td>
|
|
Datenschutzerklärung
|
|
</td>
|
|
<td>
|
|
© 2022 - 2026
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</footer>
|
|
</div>
|
|
|
|
<!-- Toaster -->
|
|
<transition name="fade">
|
|
<div v-if="flash.message" class="toaster">
|
|
{{ flash.message }}
|
|
</div>
|
|
</transition>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
|
|
.header-link-anonymous,
|
|
.header-link-anonymous-logout {
|
|
color: #000000;
|
|
font-weight: bold;
|
|
text-decoration: none;
|
|
background-color: #ffffff;
|
|
padding: 10px 30px;
|
|
margin: 0 -20px 0 30px;
|
|
overflow: hidden !important;
|
|
}
|
|
|
|
.header-link-anonymous-logout {
|
|
padding-right: 35px !important;
|
|
}
|
|
|
|
.header-link-anonymous:hover {
|
|
background-color: #1d4899;
|
|
color: #ffffff;
|
|
}
|
|
|
|
.header-link-anonymous-logout:hover {
|
|
background-color: #ff0000;
|
|
color: #ffffff;
|
|
}
|
|
|
|
.nav-links {
|
|
border-bottom: 1px solid #ddd;
|
|
width: 285px;
|
|
}
|
|
|
|
.nav-links li a {
|
|
color: #b6b6b6;
|
|
background-color: #fff;
|
|
padding: 20px 25px;
|
|
display: block;
|
|
text-decoration: none;
|
|
width: calc(100% - 50px);
|
|
font-weight: bold;
|
|
margin-bottom: 0px;
|
|
}
|
|
|
|
|
|
.nav {
|
|
flex: 1;
|
|
margin-left: -10px;
|
|
width: 275px;
|
|
|
|
}
|
|
|
|
.nav ul {
|
|
list-style: none;
|
|
padding: 0;
|
|
}
|
|
|
|
.nav li {
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.nav a {
|
|
text-decoration: none;
|
|
color: #333;
|
|
padding: 8px 12px;
|
|
display: block;
|
|
transition: background 0.2s;
|
|
}
|
|
|
|
.nav a:hover {
|
|
background-color: #1d4899;
|
|
color: #ffffff;
|
|
}
|
|
|
|
.navlink_active {
|
|
background-color: #fae39c !important;
|
|
color: #1d4899 !important; /* Dunklere Schrift beim Hover */
|
|
}
|
|
</style>
|