add additional contact component

This commit is contained in:
Matthieu Bessat 2020-07-22 23:14:12 +02:00
parent 4be9fea9fc
commit 419e6a1a71
4 changed files with 273 additions and 47 deletions

View file

@ -0,0 +1,221 @@
<template>
<div>
<div class="d-flex justify-end mb-5">
<v-btn @click="openAddModal()">
<v-icon left>person_add</v-icon>
Ajouter un contact
</v-btn>
</div>
<v-row class="justify-center">
<v-col
v-for="(people, index) in $store.state.data.contacts.peoples"
:key="index"
cols="12" sm="12" md="6" lg="4"
>
<v-card
class="mx-auto"
max-width="600px"
>
<v-card-title class="flex-column align-start">
<div class="text-h6">{{ people.name }}</div>
<div class="text-body-2">{{ people.role }}</div>
</v-card-title>
<v-card-text class="pa-0">
<v-list dense class="pt-0">
<v-list-item>
<v-list-item-action>
<v-icon>alternate_email</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>{{ people.email }}</v-list-item-title>
<v-list-item-subtitle>Email</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-list-item v-if="people.phone.length > 0">
<v-list-item-action>
<v-icon>call</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>{{ people.phone }}</v-list-item-title>
<v-list-item-subtitle>Numéro de téléphone</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</v-list>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn
icon outlined color="error"
:disabled="people.isResponsable"
@click="openDeleteModal(people)"
>
<v-icon small>delete</v-icon>
</v-btn>
<v-btn
icon outlined color="info"
@click="openEditModal(people)"
>
<v-icon small>edit</v-icon>
</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
<v-dialog
max-width="500px"
v-model="itemModal">
<v-card>
<v-card-title v-text="itemModalTitle + ' un contact'" />
<v-card-text>
<v-form ref="form" lazy-validation>
<v-text-field
label="Nom du contact"
prepend-icon="person"
v-model="item.name"
:disabled="item.isResponsable"
:rules="rules.name" />
<v-text-field
label="Rôle"
prepend-icon="grade"
v-model="item.role"
:disabled="item.isResponsable"
:rules="rules.role" />
<v-text-field
label="Email"
prepend-icon="alternate_email"
v-model="item.email"
:disabled="item.isResponsable"
:rules="rules.email" />
<v-text-field
label="N° de téléphone"
prepend-icon="call"
v-model="item.phone"
:rules="rules.phone" />
</v-form>
</v-card-text>
<v-card-actions>
<v-btn @click="itemModal = false" text color="primary">
Fermer
</v-btn>
<v-spacer />
<v-btn @click="save()" text color="success">
Valider
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-dialog
max-width="500px"
v-model="deleteModal">
<v-card>
<v-card-title>
Voulez vous vraiment supprimer ce contact ?
</v-card-title>
<v-card-actions>
<v-btn @click="deleteModal = false" text color="primary">
Fermer
</v-btn>
<v-spacer />
<v-btn @click="destroy()" text color="error">
Supprimer
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>
<script>
export default {
name: 'AdditionalContacts',
data: () => ({
defaultItem: {
name: '',
email: '',
role: '',
phone: ''
},
mode: 'add',
itemModal: false,
item: {},
oldEdit: {},
deleteModal: false,
toDelete: {},
rules: {
name: [
v => v.length >= 3 || 'Au minimum 3 caractères',
v => v.length <= 50 || 'Au maximum 50 caractères'
],
role: [
v => v.length >= 3 || 'Au minimum 2 caractères',
v => v.length <= 50 || 'Au maximum 20 caractères'
],
email: [v => /.+@.+\..+/.test(v) || "L'email est requis et doit être valide"],
phone: [
v => v.length === 0 || /^(\+[0-9]{2}|0)?([0-9](\s)?([0-9]{2}(\s)?){4})$/gm.test(v) || 'Le numéro de téléphone est requis et doit être valide'
]
}
}),
created () {
let peoples = this.$store.state.data.contacts.peoples
if (!Array.isArray(peoples)) {
peoples = []
}
this.setPeoples([{
isResponsable: true,
name: this.$store.state.data.contacts.person,
email: this.$store.state.data.contacts.email,
phone: this.$store.state.data.contacts.phone,
role: 'Responsable'
}].concat(peoples))
},
destroyed () {
this.setPeoples(this.$store.state.data.contacts.peoples.filter(p => !p.isResponsable))
},
computed: {
itemModalTitle () { return this.mode === 'add' ? 'Ajouter' : 'Editer' }
},
methods: {
setPeoples (peoples) {
this.$store.commit('SET_DATA', { contacts: { ...this.$store.state.data.contacts, peoples } })
},
openAddModal () {
this.mode = 'add'
this.item = Object.assign({}, this.defaultItem)
this.itemModal = true
},
save () {
if (!this.$refs.form.validate()) {
return
}
let peoples = this.$store.state.data.contacts.peoples
if (this.mode === 'add') {
this.item._id = Date.now().toString()
peoples.push(this.item)
} else {
if (this.item.isResponsable) {
this.$store.state.data.contacts.phone = this.item.phone
}
peoples = peoples.map(i => i === this.oldEdit ? this.item : i)
}
this.setPeoples(peoples)
this.itemModal = false
},
openEditModal (item) {
this.item = Object.assign({}, item)
this.oldEdit = item
this.mode = 'edit'
this.itemModal = true
},
openDeleteModal (item) {
this.deleteModal = true
this.toDelete = item
},
destroy () {
const peoples = this.$store.state.data.contacts.peoples.filter(item => item !== this.toDelete)
this.$store.commit('SET_DATA', { contacts: { ...this.$store.state.data.contacts, peoples } })
this.deleteModal = false
}
}
}
</script>

View file

@ -343,6 +343,12 @@ export default {
} }
return i return i
}) })
if (Array.isArray(data.contacts.peoples)) {
data.contacts.peoples = data.contacts.peoples.map(p => {
delete p._id
return p
})
}
this.$apitator.put('/delegate', data, { withAuth: true }).then(() => { this.$apitator.put('/delegate', data, { withAuth: true }).then(() => {
this.isSaving = false this.isSaving = false
this.$store.commit('ADD_ALERT', { this.$store.commit('ADD_ALERT', {

View file

@ -8,11 +8,11 @@
Ici vous pouvez préciser quelques manières de contacter votre association, aucun des champs indiqués n'est obligatoire. Ici vous pouvez préciser quelques manières de contacter votre association, aucun des champs indiqués n'est obligatoire.
</v-alert> </v-alert>
</div> </div>
<v-text-field <!-- <v-text-field
prepend-icon="call" prepend-icon="call"
label="Numéro de téléphone" label="Numéro de téléphone"
outlined outlined
v-model="$store.state.data.contacts.phone" /> v-model="$store.state.data.contacts.phone" /> -->
<v-text-field <v-text-field
prepend-icon="public" prepend-icon="public"
label="Site web" label="Site web"
@ -42,46 +42,55 @@
outlined outlined
v-model="$store.state.data.contacts.instagram" v-model="$store.state.data.contacts.instagram"
:rules="rules.instagram" /> :rules="rules.instagram" />
<p>Contacts additionels</p> <AdditionalContacts />
<v-btn @click="addContact()">Ajouter un contact additionel</v-btn> <!-- <v-card
<v-row
v-for="(contact, index) in $store.state.data.contacts.peoples" v-for="(contact, index) in $store.state.data.contacts.peoples"
:key="index"> :key="index">
<v-col cols="12" sm="4" class="py-0"> <v-row>
<v-col cols="12" sm="3" class="pr-2 py-0">
<v-text-field <v-text-field
prepend-icon="person"
label="Nom du contact" label="Nom du contact"
dense
outlined outlined
v-model="contact.name" v-model="contact.name"
:rules="rules.person" /> :rules="rules.person" />
</v-col> </v-col>
<v-col cols="12" sm="4" class="py-0"> <v-col cols="12" sm="3" class="px-2 py-0">
<v-text-field <v-text-field
label="Rôle" label="Rôle"
dense
outlined outlined
v-model="contact.role" v-model="contact.role"
:rules="rules.role" /> :rules="rules.role" />
</v-col> </v-col>
<v-col cols="12" sm="4" class="py-0"> <v-col cols="12" sm="3" class="px-2 py-0">
<v-text-field <v-text-field
label="Email" label="Email"
dense
outlined outlined
v-model="contact.email" v-model="contact.email"
:rules="rules.email" /> :rules="rules.email" />
</v-col> </v-col>
<v-col cols="12" sm="4" class="py-0"> <v-col cols="12" sm="3" class="pl-2 py-0">
<v-text-field <v-text-field
label="N° de téléphone" label="N° de téléphone"
dense
outlined outlined
v-model="contact.phone" v-model="contact.phone"
:rules="rules.phone" /> :rules="rules.phone" />
</v-col> </v-col>
</v-row> </v-row>
</v-card> -->
</div> </div>
</template> </template>
<script> <script>
import AdditionalContacts from '../../components/AdditionalContacts'
export default { export default {
components: {
AdditionalContacts
},
data: () => ({ data: () => ({
rules: { rules: {
website: [ website: [
@ -100,16 +109,6 @@ export default {
v => v === '' || /(http(s)?:\/\/)?(www\.)?instagram\.com\/(\S+){3,}/g.test(v) || 'Ce champs doit être une url instagram valide' v => v === '' || /(http(s)?:\/\/)?(www\.)?instagram\.com\/(\S+){3,}/g.test(v) || 'Ce champs doit être une url instagram valide'
] ]
} }
}),
methods: {
addContact () {
this.$store.state.contacts.peoples.push({
name: '',
email: '',
role: '',
phone: ''
}) })
} }
}
}
</script> </script>

View file

@ -115,7 +115,7 @@ export default {
v => v.length <= 200 || 'Au maximum 200 caractères' v => v.length <= 200 || 'Au maximum 200 caractères'
], ],
tags: [v => (Array.isArray(v) && v.length > 0) || 'Vous devez choisir au minimum une catégorie'], tags: [v => (Array.isArray(v) && v.length > 0) || 'Vous devez choisir au minimum une catégorie'],
email: [v => /.+@.+\..+/.test(v) || "L'email est requis et dois être valide"], email: [v => /.+@.+\..+/.test(v) || "L'email est requis et doit être valide"],
person: [v => v.length >= 4 || 'Au minimum 4 caractères'] person: [v => v.length >= 4 || 'Au minimum 4 caractères']
} }
}), }),