feat(Contact): add formatted address modal

fix: better UI/UX for additional contacts
MAY REQUIRE SOME DATA MIGRATION
This commit is contained in:
Matthieu Bessat 2020-08-25 15:27:36 +02:00
parent 18163aa2ac
commit 6b3f96c196
2 changed files with 169 additions and 24 deletions

View file

@ -1,20 +1,24 @@
<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 cols="12" md="6">
<div class="text-h6">Personnes à contacter</div>
</v-col>
<v-col cols="12" md="6" class="d-flex justify-end">
<v-btn @click="openAddModal()">
<v-icon left>person_add</v-icon>
Ajouter un contact
</v-btn>
</v-col>
</v-row>
<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"
cols="12" sm="12" md="6" lg="5"
>
<v-card
class="mx-auto"
max-width="600px"
>
<v-card-title class="flex-column align-start">
<div class="text-h6">{{ people.name }}</div>
@ -40,22 +44,32 @@
<v-list-item-subtitle>Numéro de téléphone</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-list-item v-else>
<v-list-item-action>
<v-icon>call</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-subtitle @click="openEditModal(people)" style="cursor: pointer">Ajoutez un 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"
text color="error"
v-if="!people.isResponsable"
@click="openDeleteModal(people)"
>
<v-icon small>delete</v-icon>
<!-- <v-icon small>delete</v-icon> -->
Supprimer
</v-btn>
<v-spacer />
<v-btn
icon outlined color="info"
text
color="info"
@click="openEditModal(people)"
>
<v-icon small>edit</v-icon>
Modifier
</v-btn>
</v-card-actions>
</v-card>
@ -155,7 +169,7 @@ export default {
],
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'
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 optionel et doit être valide'
]
},
formValid: false

View file

@ -20,6 +20,53 @@
label="Numéro de téléphone"
outlined
v-model="$store.state.data.contacts.phone" /> -->
<v-row class="justify-center">
<v-col cols="12" md="6">
<div class="text-h6">Adresse</div>
</v-col>
<v-col cols="12" md="6" class="d-flex justify-end">
<v-btn @click="addressModal = true">
<v-icon left>room</v-icon>
<span>Changer votre adresse</span>
</v-btn>
</v-col>
</v-row>
<!-- <v-row
v-if="address !== ''"
class="justify-center pb-6">
<v-card
class="mx-auto"
max-width="600px"
>
<v-card-text>
{{ address }}
</v-card-text>
<v-card-actions>
<v-spacer />
<v-tooltip top>
<template v-slot:activator="{ on, attrs }">
<v-btn
v-bind="attrs" v-on="on"
icon outlined color="info"
@click="addressModal = true"
>
<v-icon small>edit</v-icon>
</v-btn>
</template>
<span>Editer votre adresse</span>
</v-tooltip>
</v-card-actions>
</v-card>
</v-row> -->
<!--
<v-textarea
prepend-icon="room"
label="Adresse"
outlined
v-model="$store.state.data.contacts.address"
:rules="rules.address" /> -->
<v-divider />
<div class="text-h6 pt-5 pb-5">Réseaux sociaux et site web</div>
<v-form v-model="formValid" ref="form">
<v-text-field
prepend-icon="public"
@ -27,12 +74,6 @@
outlined
:rules="rules.website"
v-model="$store.state.data.contacts.website" />
<v-textarea
prepend-icon="room"
label="Adresse"
outlined
v-model="$store.state.data.contacts.address"
:rules="rules.address" />
<v-text-field
prepend-icon="$vuetify.icons.facebook"
label="Compte facebook"
@ -52,6 +93,7 @@
v-model="$store.state.data.contacts.instagram"
:rules="rules.instagram" />
</v-form>
<v-divider />
<AdditionalContacts />
<!-- <v-card
v-for="(contact, index) in $store.state.data.contacts.peoples"
@ -91,6 +133,54 @@
</v-col>
</v-row>
</v-card> -->
<v-dialog v-model="addressModal" max-width="500px">
<v-card>
<v-card-title>
Renseignez une adresse physique
</v-card-title>
<v-card-text>
<p>
Préférez une adresse à laquelle vous acceuillez du public plutôt qu'une adresse personelle.
</p>
<p>
Dans le cas ou votre association opère à plusieurs adresses, mettez celle qui est la plus importante selon vous ou ne renseignez pas d'adresse.
</p>
<v-row>
<v-col cols="12" sm="6" class="py-0">
<v-text-field
label="Première ligne"
v-model="firstLine"
:rules="rules.firstLine" />
</v-col>
<v-col cols="12" sm="6" class="py-0">
<v-text-field
label="Deuxième ligne"
v-model="secondLine"
:rules="rules.secondLine" />
</v-col>
<v-col cols="12" sm="4" class="py-0">
<v-text-field
label="Code postal"
type="number"
v-model="postalCode"
:rules="rules.postalCode" />
</v-col>
<v-col cols="12" sm="8" class="py-0">
<v-text-field
label="Ville"
v-model="city"
:rules="rules.city" />
</v-col>
</v-row>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn color="primary" text @click="addressModal = false">
Fermer
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>
@ -104,14 +194,51 @@ export default {
mounted () {
this.$refs.form.validate()
},
watch: {
addressModal (val) {
if (val) {
// decode address
let raw = this.$store.state.data.contacts.address.split('\n')
this.firstLine = raw[0]
if (raw.length === 3) {
this.secondLine = raw[1]
raw = raw[2].split('%postalsep%')
} else {
raw = raw[1].split('%postalsep%')
}
this.postalCode = raw[0]
this.city = raw[1]
} else {
// encode address
let encoded = ''
encoded += this.firstLine
if (this.secondLine !== '') {
encoded += '\n' + this.secondLine
}
encoded += '\n' + this.postalCode + '%postalsep%' + this.city
this.address = encoded.replace('%postalsep%', '')
this.$store.state.data.contacts.address = encoded
}
}
},
data: () => ({
formValid: false,
addressModal: false,
rules: {
website: [
v => v === '' || /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w.-]+)+[\w\-._~:/?#[\]@!$&'()*+,;=.]+$/gm.test(v) || "L'adresse web doit être valide"
],
address: [
v => v.length < 200 || 'Maximum 200 caractères'
firstLine: [
v => /^[0-9,-.A-Za-zÀàÂâÆzÉéÈèÊêËëÏïÎîÙùÛûÜüÇç' ]{2,40}$/gm.test(v) || "Ce champs doit être une ligne d'adresse valide"
],
secondLine: [
v => v === '' || /^[0-9,-.A-Za-zÀàÂâÆzÉéÈèÊêËëÏïÎîÙùÛûÜüÇç' ]{2,40}$/gm.test(v) || "Ce champs doit être une ligne d'adresse valide"
],
postalCode: [
v => /^[0-9]{2,6}$/gm.test(v) || 'Ce champs doit être un code postal valide'
],
city: [
v => v === '' || /^[0-9-A-Za-zÀàÂâÆzÉéÈèÊêËëÏïÎîÙùÛûÜüÇç' ]{2,40}$/gm.test(v) || "Ce champs doit être une ligne d'adresse valide"
],
facebook: [
v => v === '' || /(http(s)?:\/\/)?(www\.)?facebook\.com\/(\S+){3,}/g.test(v) || 'Ce champs doit être une url facebook valide'
@ -122,7 +249,11 @@ export default {
instagram: [
v => v === '' || /(http(s)?:\/\/)?(www\.)?instagram\.com\/(\S+){3,}/g.test(v) || 'Ce champs doit être une url instagram valide'
]
}
},
firstLine: '',
secondLine: '',
postalCode: '',
city: ''
})
}
</script>