Initial Nuxt frontend import
Some checks failed
continuous-integration/drone/push Build is failing

- Complete GGZ Ecademy Nuxt.js user portal
- Learning products browser and management
- Member management interface
- User authentication and roles
- Multi-language support (NL/EN)
- Vuex store for state management
- Component-based architecture
This commit is contained in:
Joris Slagter
2025-12-02 17:48:48 +01:00
parent 0f691e83e3
commit 791aebc346
290 changed files with 113801 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
<template>
<v-app>
<div class="app">
<v-margin>
<Header />
<nuxt />
<Newsletter />
<Footer />
</v-margin>
</div>
</v-app>
</template>
<script>
import Header from '~/components/layout/Header/Header'
import Newsletter from '@/components/Newsletter/Newsletter'
import Footer from '~/components/layout/Footer'
export default {
components: {
Header,
Newsletter,
Footer
}
}
</script>
<style lang="scss" scoped>
.app {
border-style: solid;
border-color: #ffcc00;
}
</style>

135
layouts/GgzAdmin.vue Normal file
View File

@@ -0,0 +1,135 @@
<template>
<v-app>
<v-navigation-drawer
app
overflow
temporary
v-model="primaryDrawer.model"
width="330"
>
<left-menu @close-left-menu="primaryDrawer.model = false"></left-menu>
</v-navigation-drawer>
<v-app-bar app tile flat height="90" color="primary" style="z-index: 999;">
<v-icon @click.stop="primaryDrawer.model = !primaryDrawer.model"
>icon-menu</v-icon
>
<router-link :to="localePath('/manager')">
<app-logo width="180" class="ml-10" />
</router-link>
<v-spacer />
<search-bar />
<v-spacer />
<div class="mr-4">
<dark-mode-switch />
<fullscreen />
<listener/>
</div>
<div
@click.stop="
$store.commit('navigation/SWITCH_RIGHT_DRAWER', {
component: 'Notifications',
})
"
:style="{ cursor: 'pointer' }"
>
<chip-user-logged v-if="$auth.loggedIn" />
</div>
</v-app-bar>
<v-main class="secondary">
<v-overlay :value="overlay" />
<v-container class="py-10">
<nuxt />
</v-container>
</v-main>
<v-navigation-drawer
app
right
overflow
temporary
disable-route-watcher
v-model="drawer"
width="480px"
>
<div class="d-flex flex-column justify-space-between fill-height">
<!-- Dynamic Component -->
<component :is="componentDrawer" />
<!-- <userMenu v-if="!isLearningProductPage" /> -->
<userMenu />
</div>
</v-navigation-drawer>
<footer-app />
<global-snackbar />
</v-app>
</template>
<script>
import AppLogo from '~/components/Logo'
import LeftMenu from '~/components/Admin/LeftMenu'
import FooterApp from '~/components/Admin/ggz/Footer/Footer'
import searchBar from '~/components/UI/SearchBar/SearchBar'
import fullscreen from '~/components/UI/FullScreen/FullScreen'
import darkModeSwitch from '~/components/UI/DarkModeSwitch/DarkModeSwitch'
import chipUserLogged from '~/components/UI/ChipUserLogged/ChipUserLogged'
import globalSnackbar from '~/components/UI/GlobalSnackbar/GlobalSnackbar'
import userMenu from '~/components/RightMenu/UserMenu'
import listener from '~/components/Listener/Listener'
export default {
middleware: ['auth'],
components: {
AppLogo,
LeftMenu,
FooterApp,
searchBar,
darkModeSwitch,
fullscreen,
chipUserLogged,
globalSnackbar,
userMenu,
listener,
// localeSwitch,
},
computed: {
drawer: {
get() {
return this.$store.getters.rightDrawer.display
},
set(v) {
return this.$store.commit('navigation/SWITCH_RIGHT_DRAWER', v)
},
},
overlay() {
return this.$store.getters.searchOverlay
},
componentDrawer() {
return this.$store.getters.rightDrawer.component
? () =>
import(
`@/components/RightMenu/${this.$store.getters.rightDrawer.component}`
)
: null
},
// isLearningProductPage() {
// return this.$route.name === 'manager-learning___nl'
// },
},
data() {
return {
primaryDrawer: {
model: null,
type: 'default (no property)',
clipped: false,
floating: false,
mini: false,
},
}
},
}
</script>

9
layouts/GgzDefault.vue Normal file
View File

@@ -0,0 +1,9 @@
<template>
<v-app>
<div class="app">
<v-main>
<nuxt />
</v-main>
</div>
</v-app>
</template>

98
layouts/admin.vue Normal file
View File

@@ -0,0 +1,98 @@
<template>
<v-app :dark="setTheme">
<v-app-bar app clipped-left id="top-navbar" tile flat :dark="setTheme">
<v-icon @click="drawer = !drawer">icon-menu</v-icon>
<span class="title ml-3 mr-5">31 10</span>
<v-spacer />
<v-btn fab text @click="switchDarkMode">
<v-icon :color="`${darkMode && 'yellow'}`">mdi-brightness-4</v-icon>
</v-btn>
<fullscreen />
<div class="mx-4">
<v-text-field
dense
id="search"
v-model="search"
append-icon="icon-search"
hide-details
placeholder="Search..."
single-line
color="#dfdbe3"
hint="For example, pages, items etc."
outlined
></v-text-field>
</div>
<chip-user-logged v-if="$auth.loggedIn" />
</v-app-bar>
<v-navigation-drawer v-model="drawer" app clipped>
<left-menu></left-menu>
</v-navigation-drawer>
<v-main class="body-content">
<div class="pa-4">
<nuxt />
</div>
</v-main>
<footer-app />
<global-snackbar />
</v-app>
</template>
<script>
import LeftMenu from '~/components/Admin/LeftMenu'
import FooterApp from '~/components/Admin/3110/Footer'
import fullscreen from '~/components/UI/FullScreen/FullScreen'
import chipUserLogged from '~/components/UI/ChipUserLogged/ChipUserLogged'
import globalSnackbar from '~/components/UI/GlobalSnackbar/GlobalSnackbar'
export default {
middleware: 'auth',
components: {
LeftMenu,
FooterApp,
fullscreen,
chipUserLogged,
globalSnackbar
},
props: {
source: String
},
data: () => ({
drawer: null,
search: '',
darkMode: false
}),
computed: {
setTheme() {
return this.darkMode
? (this.$vuetify.theme.dark = true)
: (this.$vuetify.theme.dark = false)
}
},
mounted() {
this.darkMode = localStorage.getItem('dark-mode') === 'true'
this.darkMode
? (this.$vuetify.theme.dark = true)
: (this.$vuetify.theme.dark = false)
},
methods: {
switchDarkMode() {
this.darkMode = !this.darkMode
localStorage.setItem('dark-mode', this.darkMode.toString())
}
}
}
</script>
<style>
#top-navbar {
border-bottom: 1px solid #dfdbe3 !important;
}
</style>

15
layouts/default.vue Normal file
View File

@@ -0,0 +1,15 @@
<template>
<v-app>
<div class="app">
<v-main>
<nuxt />
</v-main>
</div>
</v-app>
</template>
<script>
export default {
components: {}
}
</script>

7
layouts/empty.vue Normal file
View File

@@ -0,0 +1,7 @@
<template>
<v-app>
<div class="app">
<nuxt />
</div>
</v-app>
</template>

30
layouts/error.vue Normal file
View File

@@ -0,0 +1,30 @@
<template>
<div class="container">
<h1>Error {{ error.statusCode || '' }}</h1>
<span>{{ error.message }}</span>
<NuxtLink to="/">Home page</NuxtLink>
</div>
</template>
<script>
export default {
layout: `${process.env.CUSTOMER}Admin`,
props: {
error: {
type: Object,
default: null,
},
},
computed: {
errorMessage() {
if (this.error && this.error?.message) return this.error?.message
return 'An error occurred'
},
},
head() {
return {
title: this.errorMessage,
}
},
}
</script>