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
237 lines
6.1 KiB
Vue
237 lines
6.1 KiB
Vue
<template>
|
|
<div>
|
|
<div class="pa-6">
|
|
<page-header class="d-flex justify-space-between">
|
|
<div class="subtitle-1">
|
|
<span
|
|
:class="{ 'display-1': selector === 'allMembers' }"
|
|
:style="{ cursor: 'pointer' }"
|
|
@click="selector = 'allMembers'"
|
|
class="mr-4"
|
|
>
|
|
Leden
|
|
<small class="font-weight-light">({{ allMembers.length }})</small>
|
|
</span>
|
|
|
|
<span
|
|
:class="{ 'display-1': selector === 'active' }"
|
|
:style="{ cursor: 'pointer' }"
|
|
@click="selector = 'active'"
|
|
class="mx-4"
|
|
v-if="$store.getters.isAdmin || $store.getters.isOperator"
|
|
>
|
|
Actieve leden
|
|
<small class="font-weight-light">({{ active.length }})</small>
|
|
</span>
|
|
|
|
<span
|
|
:class="{ 'display-1': selector === 'inactive' }"
|
|
:style="{ cursor: 'pointer' }"
|
|
@click="selector = 'inactive'"
|
|
class="mx-4"
|
|
v-if="$store.getters.isAdmin || $store.getters.isOperator"
|
|
>
|
|
Inactieve leden
|
|
<small class="font-weight-light">({{ inactive.length }})</small>
|
|
</span>
|
|
|
|
<span
|
|
:class="{ 'display-1': selector === 'deleted' }"
|
|
:style="{ cursor: 'pointer' }"
|
|
@click="selector = 'deleted'"
|
|
class="mx-4"
|
|
v-if="$store.getters.isAdmin || $store.getters.isOperator"
|
|
>
|
|
Verwijderd
|
|
<small class="font-weight-light">({{ deleted.length }})</small>
|
|
</span>
|
|
</div>
|
|
|
|
<div>
|
|
<!-- here checks -->
|
|
</div>
|
|
</page-header>
|
|
</div>
|
|
|
|
<members-table :members="membersComputed" />
|
|
|
|
<v-footer
|
|
fixed
|
|
style="z-index: 4"
|
|
height="90"
|
|
color="primary"
|
|
v-if="$store.getters.isSuperAdminOrAdmin"
|
|
>
|
|
<v-btn text nuxt :to="localePath('/manager')">
|
|
<v-icon>icon-arrow-left</v-icon>
|
|
</v-btn>
|
|
<div class="mx-10">
|
|
<v-btn
|
|
color="accent"
|
|
depressed
|
|
rounded
|
|
to="/manager/members/new"
|
|
class="ml-10"
|
|
>
|
|
<v-icon left size="8">icon-add</v-icon>
|
|
<small>Lid toevoegen</small>
|
|
</v-btn>
|
|
</div>
|
|
|
|
<v-spacer />
|
|
<v-btn class="ma-2" tile text small @click="exportCsv">
|
|
<v-icon class="mx-2" x-small>icon-export</v-icon>
|
|
{{ $t('general.export_csv') | capitalize }}
|
|
</v-btn>
|
|
</v-footer>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import csv from 'csv'
|
|
import {DateTime} from 'luxon'
|
|
import dayjs from 'dayjs'
|
|
import download from 'downloadjs'
|
|
import MembersTable from '~/components/Members/MembersTable'
|
|
import PageHeader from '~/components/UI/PageHeader/PageHeader'
|
|
|
|
const I18N_CSV_WRAPPER_KEY = 'csv.members'
|
|
const I18N_CSV_HEADER_KEYS = [
|
|
'id',
|
|
'type',
|
|
'informal_name',
|
|
'formal_name',
|
|
'start_membership',
|
|
'main_branch',
|
|
'sub_branches',
|
|
]
|
|
const CSV_VALUE_NONE = '-'
|
|
|
|
export default {
|
|
layout: `${process.env.CUSTOMER}Admin`,
|
|
// middleware: 'adminsOrOperatorsOrMemberEditors',
|
|
|
|
components: {
|
|
PageHeader,
|
|
MembersTable,
|
|
},
|
|
data() {
|
|
return {
|
|
selector: 'allMembers',
|
|
}
|
|
},
|
|
methods: {
|
|
exportCsv() {
|
|
let inputData = [
|
|
I18N_CSV_HEADER_KEYS.map((key) => {
|
|
return this.$t(`${I18N_CSV_WRAPPER_KEY}.${key}`)
|
|
}),
|
|
]
|
|
|
|
this.allMembers.forEach((member) => {
|
|
let subBranchTitles = member.sub_branches.map(branch => branch.title)
|
|
subBranchTitles.sort()
|
|
|
|
inputData.push([
|
|
member.id,
|
|
member.type ?? CSV_VALUE_NONE,
|
|
member.informal_name ?? CSV_VALUE_NONE,
|
|
member.formal_name ?? CSV_VALUE_NONE,
|
|
this.formatCsvDate(
|
|
member.start_membership,
|
|
'yyyy-LL-dd HH:mm:ss',
|
|
) ?? CSV_VALUE_NONE,
|
|
member.main_branch ?? CSV_VALUE_NONE,
|
|
subBranchTitles.length
|
|
? subBranchTitles.join(', ')
|
|
: CSV_VALUE_NONE,
|
|
])
|
|
})
|
|
|
|
inputData.sort((rowLeft, rowRight) => rowRight.id - rowLeft.id);
|
|
|
|
csv.stringify(inputData, { quoted: true }, (err, output) => {
|
|
if (err) {
|
|
// TODO: handle
|
|
} else {
|
|
download(
|
|
output,
|
|
this.$t(`${I18N_CSV_WRAPPER_KEY}.filename`),
|
|
'text/csv'
|
|
)
|
|
}
|
|
})
|
|
},
|
|
|
|
formatCsvDate: (input, inputFormat) => {
|
|
if (input) {
|
|
return DateTime.fromFormat(input, inputFormat).toFormat('yyyy-LL-dd')
|
|
} else {
|
|
return null;
|
|
}
|
|
},
|
|
},
|
|
computed: {
|
|
allMembers() {
|
|
return this.$store.getters['members/membersFiltered']
|
|
},
|
|
published() {
|
|
return this.allMembers.filter((member) => !member.deleted_at)
|
|
},
|
|
active() {
|
|
return this.published.filter(
|
|
(member) =>
|
|
!member.end_membership || dayjs().isBefore(member.end_membership)
|
|
)
|
|
},
|
|
inactive() {
|
|
return this.published.filter(
|
|
(member) =>
|
|
member.end_membership && !dayjs().isBefore(member.end_membership)
|
|
)
|
|
},
|
|
deleted() {
|
|
return this.allMembers.filter((member) => member.deleted_at)
|
|
},
|
|
membersComputed() {
|
|
if (
|
|
!['allMembers', 'active', 'inactive', 'deleted'].includes(this.selector)
|
|
) {
|
|
return []
|
|
}
|
|
return this[this.selector]
|
|
},
|
|
},
|
|
|
|
async asyncData({ $axios, store }) {
|
|
try {
|
|
await store.dispatch('members/pullBranches')
|
|
|
|
if (!store.getters['members/hasMembers']) {
|
|
await store.dispatch('members/pullData')
|
|
}
|
|
} catch (error) {
|
|
console.log('Data -> error', error)
|
|
}
|
|
},
|
|
|
|
// #warning Laravel Echo has been manually disabled until broadcasting issue is fixed.
|
|
// async mounted() {
|
|
// this.$echo.channel('updates').listen(`.members-updated`, async (e) => {
|
|
// await this.$store.dispatch('members/pullData')
|
|
//
|
|
// this.$notifier.showMessage({
|
|
// content: 'Members updated',
|
|
// color: 'success',
|
|
// icon: 'icon-message',
|
|
// })
|
|
// })
|
|
// },
|
|
|
|
async beforeRouteLeave(to, from, next) {
|
|
await this.$store.commit('members/RESET_MEMBERS')
|
|
next()
|
|
},
|
|
}
|
|
</script>
|