Files
nuxt-frontend/pages/manager/members/report.vue
Joris Slagter 791aebc346
Some checks failed
continuous-integration/drone/push Build is failing
Initial Nuxt frontend import
- 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
2025-12-02 17:48:48 +01:00

201 lines
4.4 KiB
Vue

<template>
<div>
<div class="pa-6">
<page-header class="d-flex justify-space-between">
<div class="subtitle-1">
<span class="mr-4 display-1"> Rapportage </span>
</div>
</page-header>
</div>
<v-row>
<v-col>
<v-data-table
:headers="headers"
:items="managementLinks"
:search="search"
item-key="informal_name"
hide-default-footer
:pagination="settings"
>
<template v-slot:item.title="{ item }">
<a
v-if="item.target === 'blank'"
:href="item.url"
@click="setActiveLink(item)"
target="_BLANK"
class="ma-4 dot"
:class="{ 'accent--text activeTab': activeLink === item }"
>{{ item.title || item.id }}</a
>
<a
v-else
@click="setActiveLink(item)"
class="ma-4 dot"
:class="{ 'accent--text activeTab': activeLink === item }"
>{{ item.title || item.id }}</a
>
</template>
<template v-slot:item.updated_at="{ item }">
{{ formatDate(item.updated_at) }}
</template>
</v-data-table>
<div
class="frame"
v-if="activeLink.url && activeLink.target === 'self'"
>
<iframe
:src="activeLink.url"
width="100%"
frameBorder="0"
height="800px"
/>
</div>
</v-col>
</v-row>
<v-footer fixed style="z-index: 4" height="90" color="primary">
<v-btn text nuxt :to="localePath('/manager')">
<v-icon>icon-arrow-left</v-icon>
</v-btn>
<div class="mx-10"></div>
<v-spacer />
</v-footer>
</div>
</template>
<script>
import dayjs from 'dayjs'
import PageHeader from '~/components/UI/PageHeader/PageHeader'
export default {
layout: `${process.env.CUSTOMER}Admin`,
middleware: 'adminsOrOperatorsOrMemberEditors',
components: {
PageHeader,
},
data() {
return {
activeLink: {
id: 0,
url: '',
title: '',
target: '',
},
dialog: false,
search: '',
headers: [
{ text: 'titel', value: 'title' },
{
text: 'leden',
align: 'start',
sortable: true,
value: 'informal_name',
},
{ text: 'bijgewerkt', value: 'updated_at' },
// { text: 'links', value: 'management_links', sortable: false },
],
settings: {
itemsPerPage: 5,
},
}
},
computed: {
members() {
return this.$store.getters['members/membersFiltered']
},
managementLinks() {
const links = []
this.members.forEach((member) => {
member.management_links.forEach((link) => {
links.push({ ...link, informal_name: member.informal_name })
})
})
return links
},
},
methods: {
setActiveLink(link) {
this.activeLink = link
this.dialog = true
},
formatDate(date) {
return dayjs(date).format('D MMM YYYY, HH:mm').toLowerCase()
},
},
async asyncData({ $axios, store }) {
try {
if (!store.getters['members/hasMembers']) {
await store.dispatch('members/pullData')
this.activeLink = this.members[0]
}
} catch (error) {
console.log('Data -> error', error)
}
},
}
</script>
<style scoped>
.v-card >>> .v-btn__content,
.v-select .v-select__selection--comma,
.v-chip__content,
.v-list-item:not(.v-list-item--active):not(.v-list-item--disabled),
.v-select.v-select--chips:not(.v-text-field--single-line).v-text-field--enclosed
.v-select__selections,
.v-list-item .v-list-item__title,
.v-list-item .v-list-item__subtitle,
.v-list-item span,
.v-input--is-disabled input,
.v-input--is-disable,
.dot,
h2,
p {
/* color: var(--v-txt-base); */
}
.v-card >>> .v-chip--disabled {
opacity: 1 !important;
}
.v-card >>> .v-chip {
padding-left: 0 !important;
}
.dot {
cursor: pointer;
color: #333333;
font-weight: bold;
display: inline-block;
position: relative;
text-decoration: none;
}
.dot::before {
content: '\A';
width: 5px;
height: 5px;
border-radius: 50%;
background: #e54e0f;
display: block;
position: relative;
top: 35px;
left: 50%;
opacity: 0;
}
.dot:hover::before {
opacity: 0.5 !important;
}
.dot.activeTab::before {
opacity: 1 !important;
}
.frame {
margin-top: 35px;
}
</style>