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
715 lines
22 KiB
Vue
715 lines
22 KiB
Vue
<template>
|
|
<accordion-card title="Adressen">
|
|
<v-data-table
|
|
:headers="headers"
|
|
:items="addresses"
|
|
:options="options"
|
|
hide-default-footer
|
|
item-key="address"
|
|
flat
|
|
v-if="hasAddresses"
|
|
>
|
|
<template v-slot:item.type="{ item }">
|
|
{{ $t(`members.types.${item.type}`).toLowerCase() }}
|
|
</template>
|
|
|
|
<template v-slot:item.contact="{ item }">
|
|
{{
|
|
`${item.first_name_contact_person} ${item.last_name_contact_person}`
|
|
}}
|
|
</template>
|
|
|
|
<template v-slot:item.address="{ item }">{{
|
|
`${item.address ? item.address : ''} ${
|
|
item.postal ? ', ' + item.postal : ''
|
|
} ${item.city ? item.city : ''}`
|
|
}}</template>
|
|
|
|
<template v-slot:item.profiel="{ item }">
|
|
<v-icon :color="!item.approved_at ? 'accent' : 'success'">
|
|
{{
|
|
!item.approved_at ? 'mdi-alert-circle-outline' : 'icon-checkmark'
|
|
}}
|
|
</v-icon>
|
|
</template>
|
|
|
|
<template v-slot:item.actions="{ item }">
|
|
<v-btn
|
|
class="mx-4 white--text view"
|
|
style="height: 100%"
|
|
:color="$vuetify.theme.dark ? 'info' : 'txt'"
|
|
rounded
|
|
depressed
|
|
small
|
|
@click="viewItem(item)"
|
|
v-if="$store.getters.hasCharges"
|
|
>{{ $t('general.view') }}</v-btn
|
|
>
|
|
|
|
<v-menu offset-y v-if="editMode && $store.getters.isSuperAdminOrAdmin">
|
|
<template v-slot:activator="{ on }">
|
|
<v-hover v-slot:default="{ hover }">
|
|
<v-btn
|
|
:color="hover ? 'info' : ''"
|
|
:outlined="hover"
|
|
depressed
|
|
fab
|
|
small
|
|
v-on="on"
|
|
>
|
|
<v-icon>icon-options</v-icon>
|
|
</v-btn>
|
|
</v-hover>
|
|
</template>
|
|
<v-list width="200">
|
|
<v-list-item @click="editItem(item)">
|
|
<v-list-item-icon class="mr-1">
|
|
<v-icon small>icon-edit</v-icon>
|
|
</v-list-item-icon>
|
|
|
|
<v-list-item-content>
|
|
<v-list-item-subtitle>
|
|
{{ $t('general.edit') | capitalize }}
|
|
</v-list-item-subtitle>
|
|
</v-list-item-content>
|
|
</v-list-item>
|
|
|
|
<v-dialog
|
|
max-width="740"
|
|
:persistent="editModeComputed"
|
|
v-model="dialogDelete"
|
|
>
|
|
<template v-slot:activator="{ on }">
|
|
<v-list-item v-on="on">
|
|
<v-list-item-icon class="mr-1">
|
|
<v-icon small>icon-remove</v-icon>
|
|
</v-list-item-icon>
|
|
|
|
<v-list-item-content>
|
|
<v-list-item-subtitle>
|
|
{{ $t('general.delete') | capitalize }}
|
|
</v-list-item-subtitle>
|
|
</v-list-item-content>
|
|
</v-list-item>
|
|
</template>
|
|
<v-card class="primary pa-10" flat>
|
|
<v-card-title class="headline">{{
|
|
$t('learning.delete_addressmembers_confirmation')
|
|
}}</v-card-title>
|
|
<v-card-actions>
|
|
<div class="ma-4">
|
|
<v-btn
|
|
@click="deleteItem(item)"
|
|
class="mx-2"
|
|
color="accent"
|
|
depressed
|
|
rounded
|
|
>{{ $t('general.delete') }}</v-btn
|
|
>
|
|
<v-btn
|
|
@click="dialogDelete = false"
|
|
class="mx-2"
|
|
color="info"
|
|
depressed
|
|
rounded
|
|
>{{ $t('general.cancel') }}</v-btn
|
|
>
|
|
</div>
|
|
</v-card-actions>
|
|
</v-card>
|
|
</v-dialog>
|
|
</v-list>
|
|
</v-menu>
|
|
</template>
|
|
</v-data-table>
|
|
|
|
<v-dialog
|
|
v-model="dialogAddresses"
|
|
max-width="75%"
|
|
v-if="$store.getters.isSuperAdminOrAdmin"
|
|
>
|
|
<template v-slot:activator="{ on, attrs }">
|
|
<v-btn
|
|
v-if="editMode"
|
|
class="my-10 cta-secondary"
|
|
block
|
|
depressed
|
|
min-height="60px"
|
|
:disabled="isCreateMode"
|
|
v-on="on"
|
|
@click="addressEditMode = true"
|
|
>
|
|
<v-icon x-small class="mx-4">icon-add</v-icon>Nieuw adres toevoegen
|
|
</v-btn>
|
|
</template>
|
|
<v-form ref="form" v-model="valid" lazy-validation>
|
|
<v-card ref="card">
|
|
<v-card-title>
|
|
<span class="headline">{{ formTitle }}</span>
|
|
</v-card-title>
|
|
|
|
<v-card-text>
|
|
<v-container>
|
|
<v-row>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-subheader class="txt--text font-weight-black"
|
|
>Type</v-subheader
|
|
>
|
|
</v-col>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-select
|
|
v-model="editedItem.type"
|
|
:items="types"
|
|
:outlined="editModeComputed"
|
|
:solo="!editModeComputed"
|
|
:disabled="!editModeComputed"
|
|
:flat="!editModeComputed"
|
|
v-if="isCreatedModeAddress"
|
|
:rules="rules.type"
|
|
required
|
|
error
|
|
/>
|
|
|
|
<v-text-field
|
|
:outlined="editModeComputed"
|
|
:solo="!editModeComputed"
|
|
disabled
|
|
:flat="!editModeComputed"
|
|
v-model="editedItem.type"
|
|
v-else
|
|
></v-text-field>
|
|
</v-col>
|
|
</v-row>
|
|
|
|
<v-row>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-subheader class="txt--text font-weight-black"
|
|
>Onder vermelding van</v-subheader
|
|
>
|
|
</v-col>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-text-field
|
|
:outlined="editModeComputed"
|
|
:solo="!editModeComputed"
|
|
:disabled="!editModeComputed"
|
|
:flat="!editModeComputed"
|
|
v-model="editedItem.indicating"
|
|
></v-text-field>
|
|
</v-col>
|
|
</v-row>
|
|
|
|
<v-row>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-subheader class="txt--text font-weight-black"
|
|
>Aanhef</v-subheader
|
|
>
|
|
</v-col>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-text-field
|
|
:outlined="editModeComputed"
|
|
:solo="!editModeComputed"
|
|
:disabled="!editModeComputed"
|
|
:flat="!editModeComputed"
|
|
v-model="editedItem.title_contact_person"
|
|
></v-text-field>
|
|
</v-col>
|
|
</v-row>
|
|
|
|
<v-row>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-subheader class="txt--text font-weight-black"
|
|
>Voorletters</v-subheader
|
|
>
|
|
</v-col>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-text-field
|
|
:outlined="editModeComputed"
|
|
:solo="!editModeComputed"
|
|
:disabled="!editModeComputed"
|
|
:flat="!editModeComputed"
|
|
v-model="editedItem.initials_contact_person"
|
|
></v-text-field>
|
|
</v-col>
|
|
</v-row>
|
|
|
|
<v-row>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-subheader class="txt--text font-weight-black"
|
|
>T.a.v. voornaam</v-subheader
|
|
>
|
|
</v-col>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-text-field
|
|
:outlined="editModeComputed"
|
|
:solo="!editModeComputed"
|
|
:disabled="!editModeComputed"
|
|
:flat="!editModeComputed"
|
|
v-model="editedItem.first_name_contact_person"
|
|
:rules="rules.first_name"
|
|
required
|
|
error
|
|
></v-text-field>
|
|
</v-col>
|
|
</v-row>
|
|
|
|
<v-row>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-subheader class="txt--text font-weight-black"
|
|
>Tussenvoegsel</v-subheader
|
|
>
|
|
</v-col>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-text-field
|
|
:outlined="editModeComputed"
|
|
:solo="!editModeComputed"
|
|
:disabled="!editModeComputed"
|
|
:flat="!editModeComputed"
|
|
v-model="editedItem.middle_name_contact_person"
|
|
></v-text-field>
|
|
</v-col>
|
|
</v-row>
|
|
|
|
<v-row>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-subheader class="txt--text font-weight-black"
|
|
>T.a.v. achternaam</v-subheader
|
|
>
|
|
</v-col>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-text-field
|
|
:outlined="editModeComputed"
|
|
:solo="!editModeComputed"
|
|
:disabled="!editModeComputed"
|
|
:flat="!editModeComputed"
|
|
v-model="editedItem.last_name_contact_person"
|
|
:rules="rules.last_name"
|
|
required
|
|
error
|
|
></v-text-field>
|
|
</v-col>
|
|
</v-row>
|
|
|
|
<v-row>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-subheader class="txt--text font-weight-black"
|
|
>Mailadres</v-subheader
|
|
>
|
|
</v-col>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-text-field
|
|
:outlined="editModeComputed"
|
|
:solo="!editModeComputed"
|
|
:disabled="!editModeComputed"
|
|
:flat="!editModeComputed"
|
|
v-model="editedItem.email"
|
|
type="email"
|
|
:rules="rules.email"
|
|
required
|
|
error
|
|
></v-text-field>
|
|
</v-col>
|
|
</v-row>
|
|
|
|
<v-row>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-subheader class="txt--text font-weight-black"
|
|
>Functie</v-subheader
|
|
>
|
|
</v-col>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-text-field
|
|
:outlined="editModeComputed"
|
|
:solo="!editModeComputed"
|
|
:disabled="!editModeComputed"
|
|
:flat="!editModeComputed"
|
|
v-model="editedItem.job_title_contact_person"
|
|
></v-text-field>
|
|
</v-col>
|
|
</v-row>
|
|
|
|
<v-row>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-subheader class="txt--text font-weight-black"
|
|
>Telefoonnummer</v-subheader
|
|
>
|
|
</v-col>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-text-field
|
|
:outlined="editModeComputed"
|
|
:solo="!editModeComputed"
|
|
:disabled="!editModeComputed"
|
|
:flat="!editModeComputed"
|
|
v-model="editedItem.phone"
|
|
></v-text-field>
|
|
</v-col>
|
|
</v-row>
|
|
|
|
<v-row>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-subheader class="txt--text font-weight-black"
|
|
>Straatnaam</v-subheader
|
|
>
|
|
</v-col>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-text-field
|
|
:outlined="editModeComputed"
|
|
:solo="!editModeComputed"
|
|
:disabled="!editModeComputed"
|
|
:flat="!editModeComputed"
|
|
v-model="editedItem.address"
|
|
:rules="rules.address"
|
|
required
|
|
error
|
|
></v-text-field>
|
|
</v-col>
|
|
</v-row>
|
|
|
|
<v-row>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-subheader class="txt--text font-weight-black"
|
|
>Huisnummer</v-subheader
|
|
>
|
|
</v-col>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-text-field
|
|
:outlined="editModeComputed"
|
|
:solo="!editModeComputed"
|
|
:disabled="!editModeComputed"
|
|
:flat="!editModeComputed"
|
|
v-model="editedItem.house_number"
|
|
:rules="rules.house_number"
|
|
required
|
|
error
|
|
></v-text-field>
|
|
</v-col>
|
|
</v-row>
|
|
|
|
<v-row>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-subheader class="txt--text font-weight-black"
|
|
>Postcode</v-subheader
|
|
>
|
|
</v-col>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-text-field
|
|
:outlined="editModeComputed"
|
|
:solo="!editModeComputed"
|
|
:disabled="!editModeComputed"
|
|
:flat="!editModeComputed"
|
|
v-model="editedItem.postal"
|
|
:rules="rules.postal"
|
|
required
|
|
error
|
|
></v-text-field>
|
|
</v-col>
|
|
</v-row>
|
|
|
|
<v-row>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-subheader class="txt--text font-weight-black"
|
|
>Plaats</v-subheader
|
|
>
|
|
</v-col>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-text-field
|
|
:outlined="editModeComputed"
|
|
:solo="!editModeComputed"
|
|
:disabled="!editModeComputed"
|
|
:flat="!editModeComputed"
|
|
v-model="editedItem.city"
|
|
:rules="rules.city"
|
|
required
|
|
error
|
|
></v-text-field>
|
|
</v-col>
|
|
</v-row>
|
|
|
|
<v-row>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-subheader class="txt--text font-weight-black"
|
|
>Land</v-subheader
|
|
>
|
|
</v-col>
|
|
<v-col cols="12" sm="12" md="6">
|
|
<v-text-field
|
|
:outlined="editModeComputed"
|
|
:solo="!editModeComputed"
|
|
:disabled="!editModeComputed"
|
|
:flat="!editModeComputed"
|
|
v-model="editedItem.country"
|
|
></v-text-field>
|
|
</v-col>
|
|
</v-row>
|
|
</v-container>
|
|
</v-card-text>
|
|
|
|
<v-divider />
|
|
<v-card-actions v-if="editModeComputed">
|
|
<v-btn
|
|
class="ma-2 white--text"
|
|
color="info"
|
|
depressed
|
|
rounded
|
|
:disabled="loading"
|
|
@click="validate() && save()"
|
|
v-if="
|
|
$store.getters.isSuperAdmin ||
|
|
$store.getters.isAdmin ||
|
|
isUserDelegated
|
|
"
|
|
>{{ $t('general.save') }}</v-btn
|
|
>
|
|
<v-spacer />
|
|
<v-btn
|
|
class="ma-2 white--text"
|
|
color="txt"
|
|
depressed
|
|
text
|
|
:disabled="loading"
|
|
@click="close"
|
|
>{{ $t('general.cancel') }}</v-btn
|
|
>
|
|
</v-card-actions>
|
|
</v-card>
|
|
</v-form>
|
|
</v-dialog>
|
|
|
|
<p v-if="isCreateMode" class="text-center">
|
|
Bij het aanmaken van een nieuw lid kiest u eerst voor 'Tussentijds
|
|
Opslaan' om deze functie te activeren.
|
|
</p>
|
|
</accordion-card>
|
|
</template>
|
|
|
|
<script>
|
|
import accordionCard from '@/components/UI/AccordionCard/AccordionCard'
|
|
export default {
|
|
components: {
|
|
accordionCard,
|
|
},
|
|
props: {
|
|
editMode: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
isCreateMode: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
options: {
|
|
itemsPerPage: -1,
|
|
},
|
|
headers: [
|
|
{ text: 'type', value: 'type' },
|
|
{ text: 't.a.v.', value: 'contact' },
|
|
{ text: 'adres', value: 'address' },
|
|
{ text: 'mailadres', value: 'email' },
|
|
{ text: 'telefoonnummer', value: 'phone' },
|
|
{ text: 'profiel', value: 'profiel', sortable: false },
|
|
{ text: '', value: 'actions' },
|
|
],
|
|
typeKeys: ['main', 'visiting', 'invoice', 'other'],
|
|
addressEditMode: false,
|
|
dialogAddresses: false,
|
|
dialogDelete: false,
|
|
editedIndex: -1,
|
|
editedItem: {},
|
|
defaultItem: {},
|
|
loading: false,
|
|
rules: {
|
|
type: [(v) => !!v || 'Het type is verplicht.'],
|
|
address: [(v) => !!v || 'Straatnaam is verplicht.'],
|
|
house_number: [(v) => !!v || 'Huisnummer is verplicht.'],
|
|
postal: [
|
|
(v) => !!v || 'Postcode is verplicht.',
|
|
(v) =>
|
|
/^[1-9][0-9]{3} ?(?!sa|sd|ss)[a-z]{2}$/i.test(v) ||
|
|
'Ongeldige postcode',
|
|
],
|
|
|
|
city: [(v) => !!v || 'Plaats is verplicht.'],
|
|
first_name: [(v) => !!v || 'De voornaam is verplicht.'],
|
|
last_name: [(v) => !!v || 'De achternaam is verplicht.'],
|
|
email: [(v) => !!v || 'Het e-mailadres is verplicht.'],
|
|
},
|
|
valid: true,
|
|
}
|
|
},
|
|
computed: {
|
|
local() {
|
|
return this.$store.state.members.local
|
|
},
|
|
addresses() {
|
|
if (!this.local || !Array.isArray(this.local.addresses)) return []
|
|
return this.local.addresses
|
|
},
|
|
hasAddresses() {
|
|
if (!this.addresses) return false
|
|
return this.addresses.length > 0
|
|
},
|
|
formTitle() {
|
|
return this.editedIndex === -1 ? 'new' : 'edit'
|
|
},
|
|
isCreatedModeAddress() {
|
|
return this.editedIndex === -1
|
|
},
|
|
editModeComputed() {
|
|
return this.addressEditMode && this.editMode
|
|
},
|
|
isUserDelegated() {
|
|
return this.local.user_id === this.$store.getters.loggedInUser.id
|
|
},
|
|
types() {
|
|
return this.typeKeys.map((key) => ({
|
|
text: this.$t(`members.types.${key}`).toLowerCase(),
|
|
value: key,
|
|
}))
|
|
},
|
|
},
|
|
|
|
watch: {
|
|
dialogAddresses(val) {
|
|
val || this.close()
|
|
},
|
|
},
|
|
|
|
methods: {
|
|
close() {
|
|
this.dialogAddresses = false
|
|
this.$nextTick(() => {
|
|
this.editedItem = Object.assign({}, this.defaultItem)
|
|
this.editedIndex = -1
|
|
this.$refs.card.$el.scrollIntoView(true)
|
|
})
|
|
},
|
|
|
|
viewItem(item) {
|
|
this.addressEditMode = false
|
|
this.editedIndex = this.addresses.indexOf(item)
|
|
this.editedItem = Object.assign({}, item)
|
|
this.$forceUpdate()
|
|
this.dialogAddresses = true
|
|
},
|
|
|
|
editItem(item) {
|
|
if (!this.editMode) return
|
|
this.addressEditMode = true
|
|
this.setItemToEdit(item)
|
|
this.dialogAddresses = true
|
|
},
|
|
|
|
setItemToEdit(item) {
|
|
this.editedIndex = this.addresses.indexOf(item)
|
|
this.editedItem = Object.assign({}, item)
|
|
this.$forceUpdate()
|
|
},
|
|
|
|
validate() {
|
|
return this.$refs.form.validate()
|
|
},
|
|
|
|
async save() {
|
|
this.$nextTick(() => {
|
|
this.$refs.card.$el.scrollIntoView(true)
|
|
})
|
|
this.loading = true
|
|
this.$nextTick(() => this.$nuxt.$loading.start())
|
|
this.dialogAddresses = false
|
|
|
|
if (this.isCreatedModeAddress) {
|
|
try {
|
|
await this.$store.dispatch('members/storeAddress', this.editedItem)
|
|
this.loading = false
|
|
} catch (error) {
|
|
console.log('save -> error', error)
|
|
this.loading = false
|
|
}
|
|
} else {
|
|
// Edit mode
|
|
try {
|
|
await this.$store.dispatch('members/storeAddress', this.editedItem)
|
|
this.loading = false
|
|
this.dialogAddresses = false
|
|
} catch (error) {
|
|
this.loading = false
|
|
console.log('save -> error', error)
|
|
}
|
|
}
|
|
|
|
this.close()
|
|
this.$nuxt.$loading.finish()
|
|
},
|
|
|
|
async deleteItem(item) {
|
|
if (!item.id) {
|
|
this.$notifier.showMessage({
|
|
content: `No address to delete selected`,
|
|
color: 'error',
|
|
icon: 'icon-message',
|
|
})
|
|
}
|
|
|
|
this.$nextTick(() => this.$nuxt.$loading.start())
|
|
|
|
try {
|
|
await this.$store.dispatch('members/deleteAddress', item)
|
|
|
|
this.dialogDelete = false
|
|
this.dialogAddresses = false
|
|
this.$nuxt.$loading.finish()
|
|
} catch (error) {
|
|
console.log('deleteItem -> error', error)
|
|
this.$nuxt.$loading.finish()
|
|
}
|
|
},
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.v-card >>> table,
|
|
.v-card >>> .v-data-table-header tr,
|
|
.v-card >>> .v-data-footer {
|
|
background-color: var(--v-primary-base);
|
|
}
|
|
.v-card >>> .v-data-table-header th span {
|
|
color: var(--v-tertiary-base);
|
|
}
|
|
.v-card >>> .text-start,
|
|
.v-card >>> .v-icon,
|
|
.v-dialog__content >>> .v-subheader,
|
|
.v-dialog__content >>> i {
|
|
color: var(--v-txt-base);
|
|
font-weight: bold;
|
|
}
|
|
.v-card >>> .v-subheader {
|
|
padding: 0px !important;
|
|
}
|
|
.v-dialog__content >>> .v-dialog {
|
|
border: 4px solid var(--v-secAccent-base);
|
|
max-height: 68% !important;
|
|
/* box-shadow: inset 0px 0px 2px 2px var(--v-secAccent-base),
|
|
inset 6px 6px 14px -14px var(--v-secAccent-base) !important; */
|
|
}
|
|
.v-dialog .v-card {
|
|
background: var(--v-secondary-base);
|
|
}
|
|
|
|
.v-dialog__content >>> .v-input__slot {
|
|
background: var(--v-primary-base);
|
|
border: 1px solid var(--v-lines-base);
|
|
}
|
|
.v-menu__content >>> .v-date-picker-table {
|
|
height: 285px !important;
|
|
}
|
|
table tr button.view {
|
|
opacity: 0;
|
|
}
|
|
table tr:hover button.view {
|
|
opacity: 1;
|
|
}
|
|
</style>
|