client/src/MobicoopBundle/Resources/assets/js/components/user/profile/UpdateProfile.vue
<template>
<v-container>
<!--SnackBar-->
<v-snackbar
v-model="snackbar"
:color="(errorUpdate) ? 'error' : 'success'"
top
>
{{ errorUpdate ? textSnackError : textSnackOk }}
<v-btn
color="white"
text
@click="snackbar = false"
>
<v-icon>mdi-close-circle-outline</v-icon>
</v-btn>
</v-snackbar>
<v-alert
v-if="savedCo2 > 0"
type="success"
outlined
>
{{ $t('savedCo2', { savedCo2: savedCo2 }) }} CO<sub>2</sub>
</v-alert>
<!-- Main form -->
<v-form
ref="form"
v-model="valid"
lazy-validation
>
<v-card
flat
color="grey lighten-4"
class="mb-8"
>
<v-card-title>
{{ $t('titles.personnalInfos') }}
<v-spacer />
<v-btn
color="primary"
class="mb-8"
rounded
@click="dialogPublicProfile = true"
>
{{ $t('publicProfile.see') }}
</v-btn>
</v-card-title>
<v-card-text>
<!-- Email -->
<v-row no-gutters>
<v-col :cols="email && emailVerified ? '12' : '6'">
<v-text-field
v-model="email"
:label="$t('email.label')"
type="email"
class="email"
>
<template v-slot:append>
<v-tooltip
color="info"
top
>
<template v-slot:activator="{ on }">
<v-icon
v-if="email && emailVerified"
color="success"
v-on="on"
>
mdi-check-circle-outline
</v-icon>
<v-icon
v-else-if="email && !emailVerified"
color="warning"
v-on="on"
>
mdi-alert-circle-outline
</v-icon>
</template>
<span v-if="email && emailVerified">{{ $t('email.tooltips.verified') }}</span>
<span v-else-if="email && !emailVerified">{{ $t('email.tooltips.notVerified') }}</span>
</v-tooltip>
</template>
</v-text-field>
</v-col>
<v-col
v-if="email && !emailVerified"
class="d-flex justify-center"
cols="6"
>
<v-btn
rounded
color="secondary"
:loading="loadingEmail"
@click="sendValidationEmail"
>
{{ !emailSended ? $t('email.buttons.label.generateEmail') : $t('email.buttons.label.generateEmailAgain')
}}
</v-btn>
</v-col>
</v-row>
<v-row
id="phone-number"
no-gutters
>
<!-- Telephone -->
<v-col
v-if="user.phoneCode"
cols="2"
>
<v-select
v-model="phoneCode"
:items="flags"
required
:label="$t('phoneCode.placeholder')"
item-value="value"
item-text="code"
clearable
:rules="phoneCodeRules"
name="phoneCode"
>
<template v-slot:item="{ item }">
<v-list-item>
<v-list-item-action>
<span :class="['fi fi-' + item.country]" />
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>
{{ item.code }}
</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-divider class="mt-1" />
</template>
<template v-slot:selection="{ item }">
<v-list-item class="mt-n6 mb-n6">
<v-list-item-action>
<span :class="['ml-n2 fi fi-' + item.country]" />
</v-list-item-action>
<v-list-item-content class="ml-n9">
<v-list-item-title>
{{ item.code }}
</v-list-item-title>
</v-list-item-content>
</v-list-item>
</template>
</v-select>
</v-col>
<v-col :cols="telephone && phoneVerified ? (phoneCode ? '10' : '12') : (phoneCode ? '4' : '6')">
<v-text-field
v-model="telephone"
:label="$t('phone.label')"
class="telephone"
:error-messages="phoneErrors"
>
<template v-slot:append>
<v-tooltip
color="info"
top
>
<template v-slot:activator="{ on }">
<v-icon
v-if="telephone && phoneVerified"
color="success"
v-on="on"
>
mdi-check-circle-outline
</v-icon>
<v-icon
v-else-if="telephone && !phoneVerified"
color="warning"
v-on="on"
>
mdi-alert-circle-outline
</v-icon>
</template>
<span v-if="telephone && phoneVerified">{{ $t('phone.tooltips.verified') }}</span>
<span v-if="telephone && !phoneVerified">{{ $t('phone.tooltips.notVerified') }}</span>
</v-tooltip>
</template>
</v-text-field>
</v-col>
<v-col
v-if="telephone && displayPhoneVerification && !phoneVerified"
class="d-flex justify-center"
cols="6"
>
<v-btn
rounded
color="secondary"
:loading="loadingToken"
@click="generateToken"
>
{{ phoneToken == null ? $t('phone.buttons.label.generateToken') :
$t('phone.buttons.label.generateNewToken') }}
</v-btn>
</v-col>
</v-row>
<v-row
v-if="phoneToken != null && telephone && !phoneVerified"
no-gutters
>
<v-col cols="6">
<v-text-field
v-model="token"
:rules="tokenRules"
:label="$t('phone.validation.label')"
/>
</v-col>
<v-col
cols="6"
class="d-flex justify-center"
>
<v-btn
rounded
color="secondary"
:loading="loadingValidatePhone"
@click="validateToken"
>
{{ $t('phone.buttons.label.validate') }}
</v-btn>
</v-col>
</v-row>
<v-row no-gutters>
<!-- Phone display preferences -->
<v-radio-group
v-model="phoneDisplay['value']"
:label="$t('phoneDisplay.label.general')"
>
<v-radio
v-for="(phDisplay, index) in phoneDisplays"
:key="index"
color="secondary"
:label="phDisplay.label"
:value="phDisplay.value"
/>
</v-radio-group>
<!--NewsSubscription-->
<v-switch
v-model="newsSubscription"
:label="$t('news.label', { platform: platform })"
inset
color="secondary"
@change="dialog = !newsSubscription"
>
<v-tooltip
slot="append"
left
color="info"
:max-width="'35%'"
>
<template v-slot:activator="{ on }">
<v-icon
justify="left"
v-on="on"
>
mdi-help-circle-outline
</v-icon>
</template>
<span>{{ $t('news.tooltip') }}</span>
</v-tooltip>
</v-switch>
<!--NewsSubscription Confirmation Popup-->
<v-dialog
v-model="dialog"
persistent
max-width="500"
>
<v-card>
<v-card-title class="text-h5">
{{ $t('news.confirmation.title') }}
</v-card-title>
<v-card-text v-html="$t('news.confirmation.content')" />
<v-card-actions>
<v-spacer />
<v-btn
color="primary darken-1"
text
@click="dialog = false; newsSubscription = true"
>
{{ $t('no') }}
</v-btn>
<v-btn
color="secondary darken-1"
text
@click="dialog = false"
>
{{ $t('yes') }}
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-switch
v-if="gratuityActive"
v-model="gratuitySubscription"
:label="$t('gratuity.label', { platform: platform })"
inset
color="secondary"
/>
</v-row>
<v-row
no-gutters
align="center"
>
<!-- Informations fields -->
<v-col cols="7">
<!--GivenName-->
<v-text-field
v-model="givenName"
:label="$t('givenName.label')"
class="givenName"
:rules="givenNameRules"
/>
<!--FamilyName-->
<v-text-field
v-model="familyName"
:label="$t('familyName.label')"
class="familyName"
:rules="familyNameRules"
/>
<!--Gender-->
<v-select
v-model="gender"
:label="$t('gender.label')"
:items="genders"
item-text="label"
item-value="value"
/>
<!-- Birthdate -->
<v-menu
ref="menu"
v-model="menu"
:close-on-content-click="false"
transition="scale-transition"
offset-y
min-width="290px"
>
<template v-slot:activator="{ on }">
<v-text-field
:value="computedBirthdateFormat"
:label="$t('birthDay.label')"
:rules="[birthdayRules.checkIfAdult, birthdayRules.required]"
readonly
v-on="on"
/>
</template>
<v-date-picker
ref="picker"
v-model="birthDay"
:max="maxDate()"
:locale="locale"
first-day-of-week="1"
@change="save"
/>
</v-menu>
<span id="driving-licence-number" />
<v-text-field
v-model="drivingLicenceNumber"
:label="$t('drivingLicenceNumber.label')"
class="drivingLicenceNumber"
@focusout="checkDrivingLicenceNumber"
@focusin="drivingLicenceNumberValid = true"
/>
<v-alert
v-if="!drivingLicenceNumberValid"
type="error"
>
{{ $t('checkDrivingLicenceNumber.error') }}
</v-alert>
</v-col>
<!-- Avatar -->
<v-col cols="5">
<v-row
justify="center"
align="center"
>
<v-col
align="center"
class="d-flex justify-center"
>
<v-avatar
color="lighten-3"
size="225px"
>
<img
id="avatar"
:src="urlAvatar"
alt="avatar"
>
</v-avatar>
</v-col>
</v-row>
<v-row justify="center">
<v-col
v-if="!displayFileUpload"
class="d-flex justify-center"
>
<v-btn
:loading="loadingDelete"
color="warning"
class="ma-2 white--text pa-2 pr-3"
rounded
@click="avatarDelete"
>
{{ $t('avatar.delete.label') }}
<v-icon
right
dark
>
mdi-delete
</v-icon>
</v-btn>
</v-col>
<v-col
v-else
cols="10"
class="d-flex justify-center"
>
<v-file-input
ref="avatar"
v-model="avatar"
:rules="avatarRules"
accept="image/png, image/jpeg, image/jpg"
:label="$t('avatar.label')"
prepend-icon="mdi-image"
:change="previewAvatar()"
:hint="$t('avatar.minPxSize', { size: imageMinPxSize }) + ', ' + $t('avatar.maxMbSize', { size: imageMaxMbSize })"
persistent-hint
show-size
@change="selectedAvatar"
/>
</v-col>
</v-row>
</v-col>
</v-row>
<v-row justify="center">
<v-col class="d-flex justify-center">
<!--Save Button-->
<v-btn
class="button saveButton"
color="secondary"
rounded
:disabled="!valid"
:loading="loading"
type="button"
:value="$t('save')"
@click="update"
>
{{ $t('save') }}
</v-btn>
<v-dialog
v-model="dialogEmail"
persistent
max-width="450"
>
<v-card>
<v-card-title class="headline">
{{ $t('dialogEmail.title') }}
</v-card-title>
<v-card-text v-html="$t('dialogEmail.content')" />
<v-card-actions>
<v-spacer />
<v-btn
color="error"
text
@click="cancel"
>
{{ $t('dialogEmail.buttons.cancelUpdate') }}
</v-btn>
<v-btn
color="primary darken-1"
text
@click="validate"
>
{{ $t('dialogEmail.buttons.confirmUpdate') }}
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-col>
</v-row>
</v-card-text>
</v-card>
</v-form>
<!-- Address form -->
<v-card
id="user-postalAddress"
flat
color="grey lighten-4"
class="mb-8"
>
<v-card-title>
{{ $t('homeTown.label') }}
</v-card-title>
<v-card-text>
<v-row no-gutters>
<v-col>
<geocomplete
:uri="geoSearchUrl"
:results-order="geoCompleteResultsOrder"
:palette="geoCompletePalette"
:chip="geoCompleteChip"
:show-name="false"
:restrict="['housenumber', 'street']"
:label="$t('homeTown.label')"
:hint="$t('homeTown.hint')"
:address="homeAddress"
@address-selected="homeAddressSelected"
/>
</v-col>
</v-row>
<v-row
no-gutters
justify="center"
>
<v-col class="d-flex justify-center">
<v-btn
rounded
color="secondary"
class="mt-4"
:disabled="!homeAddress || disabledAddress"
:loading="loadingAddress"
type="button"
@click="updateAddress"
>
{{ $t('address.update.label') }}
</v-btn>
</v-col>
</v-row>
</v-card-text>
</v-card>
<!-- Password form -->
<v-card
flat
color="grey lighten-4"
class="mb-8"
>
<v-card-title>
{{ $t('titles.password') }}
</v-card-title>
<v-card-text>
<ChangePassword />
</v-card-text>
</v-card>
<!-- EEC form -->
<EECIncentiveStatus
v-if="isEecblockDisplayed"
:id="$t('eec-incentive')"
:confirmed-phone-number="user.phoneValidatedDate ? true : false"
:driving-licence-number-filled="user.drivingLicenceNumber ? true : false"
:is-after-eec-subscription="isAfterEecSubscription"
:eec-sso-auth-error="eecSsoAuthError"
:api-uri="apiUri"
:platform="platform"
@changeTab="changeTab"
/>
<!-- Delete form -->
<v-card
flat
color="grey lighten-4"
class="mb-8"
>
<v-card-title>
{{ $t('buttons.supprimerAccount') }}
</v-card-title>
<v-card-text v-if="!ssoExternalAccountDeletion">
<v-row justify="center">
<v-col class="d-flex justify-center">
<v-dialog
v-model="dialogDelete"
width="500"
>
<template v-slot:activator="{ on }">
<!--Delete button -->
<v-btn
class="button"
color="error"
rounded
:disabled="!valid || disabledCreatedEvents || disabledOwnedCommunities"
:loading="loading"
type="button"
:value="$t('save')"
v-on="on"
>
{{ $t('buttons.supprimerAccount') }}
</v-btn>
</template>
<v-card>
<v-card-title
v-if="hasCreatedEvents || hasOwnedCommunities"
class="text-h5 error--text"
primary-title
>
{{ $t('dialog.titles.deletionImpossible') }}
</v-card-title>
<v-card-title
v-else
class="text-h5"
primary-title
>
{{ $t('dialog.titles.deleteAccount') }}
</v-card-title>
<v-card-text>
<p
v-if="hasOwnedCommunities"
v-html="$t('dialog.content.errorCommunities')"
/>
<p
v-else-if="hasCreatedEvents"
v-html="$t('dialog.content.errorEvents')"
/>
<p
v-else
v-html="$t('dialog.content.deleteAccount')"
/>
</v-card-text>
<v-divider />
<v-card-actions v-if="hasCreatedEvents || hasOwnedCommunities">
<v-spacer />
<v-btn
color="primary darken-1"
text
@click="dialogDelete = false; newsSubscription = true"
>
{{ $t('dialog.buttons.close') }}
</v-btn>
</v-card-actions>
<v-card-actions v-else>
<v-spacer />
<v-btn
color="primary darken-1"
text
@click="dialogDelete = false; newsSubscription = true"
>
{{ $t('no') }}
</v-btn>
<v-btn
color="primary"
text
:href="$t('route.supprimer')"
@click="dialogDelete = false"
>
{{ $t('dialog.buttons.confirmDelete') }}
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-col>
</v-row>
</v-card-text>
<v-card-text v-else>
<v-row>
<v-col col="12">
{{ $t('ssoDeleteAccountWarning', { 'service': ssoConnection.service }) }}
</v-col>
</v-row>
</v-card-text>
</v-card>
<!-- PUBLIC PROFILE DIALOG -->
<v-dialog
v-model="dialogPublicProfile"
width="100%"
>
<v-card>
<v-card-title class="headline grey lighten-2">
{{ $t('publicProfile.title') }}
</v-card-title>
<v-card-text>
<PublicProfile
:user-id="user.id"
:show-report-button="false"
:age-display="ageDisplay"
:carpool-settings-display="carpoolSettingsDisplay"
/>
</v-card-text>
<v-divider />
<v-card-actions>
<v-spacer />
<v-btn
color="primary"
text
@click="dialogPublicProfile = false"
>
{{ $t('publicProfile.close') }}
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-container>
</template>
<script>
import maxios from "@utils/maxios";
import moment from "moment";
import Geocomplete from "@components/utilities/geography/Geocomplete";
import ChangePassword from "@components/user/profile/ChangePassword";
import PublicProfile from "@components/user/profile/PublicProfile";
import EECIncentiveStatus from "@components/user/eecIncentiveStatus/EECIncentiveStatus";
import { merge } from "lodash";
import { messages_en, messages_fr, messages_eu, messages_nl } from "@translations/components/user/profile/UpdateProfile/";
import { messages_client_en, messages_client_fr, messages_client_eu, messages_client_nl } from "@clientTranslations/components/user/profile/UpdateProfile/";
let MessagesMergedEn = merge(messages_en, messages_client_en);
let MessagesMergedNl = merge(messages_nl, messages_client_nl);
let MessagesMergedFr = merge(messages_fr, messages_client_fr);
let MessagesMergedEu = merge(messages_eu, messages_client_eu);
export default {
i18n: {
messages: {
'en': MessagesMergedEn,
'nl': MessagesMergedNl,
'fr': MessagesMergedFr,
'eu': MessagesMergedEu
},
},
components: {
PublicProfile,
Geocomplete,
ChangePassword,
EECIncentiveStatus
},
props: {
geoSearchUrl: {
type: String,
default: null
},
user: {
type: Object,
default: null
},
ageMin: {
type: String,
default: null
},
ageMax: {
type: String,
default: null
},
ageDisplay: {
type: Boolean,
default: true
},
platform: {
type: String,
default: ""
},
imageMinPxSize: {
type: Number,
default: null
},
imageMaxMbSize: {
type: Number,
default: null
},
geoCompleteResultsOrder: {
type: Array,
default: null
},
geoCompletePalette: {
type: Object,
default: () => ({})
},
geoCompleteChip: {
type: Boolean,
default: false
},
carpoolSettingsDisplay: {
type: Boolean,
default: true
},
ceeDisplay: {
type: Boolean,
default: true
},
isAfterEecSubscription: {
type: Boolean,
default: false
},
eecSsoAuthError: {
type: String,
default: null
},
apiUri: {
type: String,
default: null
},
gendersList: {
type: Array,
default: () => []
},
eecInstance: { // The EEC service status for the instance
type: Object,
default: () => ({})
},
phoneCodes: {
type: Array,
default: () => []
}
},
data() {
return {
dialog: false,
dialogDelete: false,
dialogPublicProfile: false,
snackbar: false,
textSnackOk: this.$t('snackBar.profileUpdated'),
textSnackError: this.$t("snackBar.passwordUpdateError"),
errorUpdate: false,
valid: true,
errors: [],
loading: false,
loadingDelete: false,
gender: this.user.gender,
email: this.user.email,
telephone: this.user.telephone,
phoneCode: this.user.phoneCode,
phoneCodeRules: [
(v) => !!v || this.$t("phoneCode.errors.required"),
],
givenName: this.user.givenName,
givenNameRules: [
(v) => !!v || this.$t("givenName.errors.required"),
],
familyName: this.user.familyName,
familyNameRules: [
(v) => !!v || this.$t("familyName.errors.required"),
],
birthDay: this.user.birthDate ? this.user.birthDate.date : null,
homeAddress: this.user.homeAddress ? this.user.homeAddress : null,
drivingLicenceNumber: this.user.drivingLicenceNumber ? this.user.drivingLicenceNumber : null,
phoneErrors: [],
phoneToken: this.user.phoneToken,
phoneValidatedDate: this.user.phoneValidatedDate,
emailValidatedDate: this.user.validatedDate,
token: null,
menu: false,
phoneDisplay: {
value: this.user.phoneDisplay
},
phoneDisplays: [
{ value: 1, label: this.$t('phoneDisplay.label.restricted') },
{ value: 2, label: this.$t('phoneDisplay.label.all') }
],
avatar: null,
avatarHeight: null,
avatarWidth: null,
avatarRules: [
v => !v || v.size < this.imageMaxMbSize * 1024 * 1024 || this.$t("avatar.size") + " (Max " + (this.imageMaxMbSize) + "MB)",
v => !v || this.avatarHeight >= this.imageMinPxSize || this.$t("avatar.pxSize", { size: this.imageMinPxSize, height: this.avatarHeight, width: this.avatarWidth }),
v => !v || this.avatarWidth >= this.imageMinPxSize || this.$t("avatar.pxSize", { size: this.imageMinPxSize, height: this.avatarHeight, width: this.avatarWidth }),
],
tokenRules: [
v => (/^\d{4}$/).test(v) || this.$t("phone.token.inputError")
],
birthdayRules: {
required: v => !!v || this.$t("birthDay.errors.required"),
checkIfAdult: value => {
var d1 = new Date();
var d2 = moment(value, "DD/MM/YYYY").toDate();
var diff = (d1.getTime() - d2.getTime()) / 1000;
diff /= (60 * 60 * 24);
var diffYears = Math.abs(Math.floor(diff / 365.24));
return diffYears >= 16 || this.$t("birthDay.errors.notadult")
}
},
newsSubscription: this.user && this.user.newsSubscription !== null ? this.user.newsSubscription : null,
urlAvatar: this.user.avatars[this.user.avatars.length - 1],
displayFileUpload: this.user.images.length == 0,
phoneVerified: null,
emailVerified: false,
emailSended: false,
loadingEmail: false,
displayPhoneVerification: this.user.telephone ? true : false,
loadingToken: false,
loadingValidatePhone: false,
disabledAddress: true,
loadingAddress: false,
ownedCommunities: null,
createdEvents: null,
hasCreatedEvents: false,
hasOwnedCommunities: false,
disabledOwnedCommunities: false,
disabledCreatedEvents: false,
locale: null,
emailChanged: false,
dialogEmail: false,
ssoConnection: null,
drivingLicenceNumberValid: true,
gratuitySubscription: this.user && this.user.gratuity !== null ? this.user.gratuity : null,
flags: this.phoneCodes,
cleanedPhoneNumber: null,
};
},
computed: {
years() {
const currentYear = new Date().getFullYear();
const ageMin = Number(this.ageMin);
const ageMax = Number(this.ageMax);
return Array.from({ length: ageMax - ageMin }, (value, index) => (currentYear - ageMin) - index)
},
computedBirthdateFormat() {
if (this.birthDay) {
return moment.utc(this.birthDay).format("DD/MM/YYYY");
}
return null;
},
savedCo2() {
return Number.parseFloat(this.user.savedCo2 / 1000000).toPrecision(1);
},
isSsoLinked() {
if (this.user.ssoId && this.user.ssoProvider) {
return true;
}
return false;
},
ssoExternalAccountDeletion() {
if (this.isSsoLinked) {
if (this.ssoConnection && this.ssoConnection.externalAccountDeletion) {
return true;
}
}
return false;
},
genders() {
return this.$t("gender.values").filter((genderItem) => {
return this.gendersList.includes(parseInt(genderItem.value));
});
},
gratuityActive() {
return this.$store.getters['grt/isActive'];
},
isEecblockDisplayed() {
return (
this.ceeDisplay
&& (
this.eecInstance.available
|| (
!this.eecInstance.available
&& (this.user.longDistanceSubscription || this.user.shortDistanceSubscription)
)
)
);
}
},
watch: {
menu(val) {
val && setTimeout(() => (this.$refs.picker.activePicker = 'YEAR'))
},
telephone(val) {
this.phoneToken = null;
this.displayPhoneVerification = false;
this.cleanPhoneNumber();
maxios
.post(
this.$t("phone.checkValidity.url"),
{
telephone: this.cleanedPhoneNumber,
},
{
headers: {
"content-type": "application/json",
},
}
)
.then((response) => {
if (response.data.valid) {
this.phoneErrors = [];
}
else {
this.phoneErrors = [this.$t("phone.errors.valid")];
}
})
.catch(function (error) {
console.error(error);
this.phoneErrors = [this.$t("phone.errors.valid")];
});
},
phoneCode() {
this.phoneToken = null;
this.displayPhoneVerification = false;
this.cleanPhoneNumber();
maxios
.post(
this.$t("phone.checkValidity.url"),
{
telephone: this.cleanedPhoneNumber,
},
{
headers: {
"content-type": "application/json",
},
}
)
.then((response) => {
if (response.data.valid) {
this.phoneErrors = [];
}
else {
this.phoneErrors = [this.$t("phone.errors.valid")];
}
})
.catch(function (error) {
console.error(error);
this.phoneErrors = [this.$t("phone.errors.valid")];
});
},
email(val) {
this.emailChanged = true;
}
},
created() {
this.setMomentLocale();
},
mounted() {
this.setMomentLocale();
this.checkVerifiedPhone();
this.checkVerifiedEmail();
this.getOwnedCommunities();
this.getCreatedEvents();
if (this.isSsoLinked) {
this.getSso();
}
},
methods: {
setMomentLocale() {
this.locale = localStorage.getItem("X-LOCALE");
moment.locale(this.locale);
},
homeAddressSelected(address) {
this.homeAddress = address;
this.disabledAddress = false;
// this.$emit('updateUser', {"homeAddress": this.homeAddress})
},
save(date) {
this.$refs.menu.save(date)
},
validate() {
if (this.$refs.form.validate()) {
this.checkForm();
this.dialogEmail = false;
}
},
update() {
if (this.emailChanged) {
this.dialogEmail = true;
} else {
this.validate();
}
},
cancel() {
window.location.reload();
},
checkForm() {
this.loading = true;
let updateUser = new FormData();
updateUser.append("email", this.email);
updateUser.append("familyName", this.familyName);
updateUser.append("gender", this.gender);
updateUser.append("givenName", this.givenName);
updateUser.append("telephone", this.telephone);
updateUser.append("phoneCode", this.phoneCode);
updateUser.append("birthDay", this.birthDay);
updateUser.append("avatar", this.avatar);
updateUser.append("newsSubscription", this.newsSubscription);
updateUser.append("gratuitySubscription", this.gratuitySubscription);
updateUser.append("phoneDisplay", this.phoneDisplay.value);
updateUser.append("drivingLicenceNumber", this.drivingLicenceNumber);
maxios
.post(this.$t('route.update'), updateUser,
{
headers: {
'content-type': 'multipart/form-data'
}
})
.then(res => {
this.errorUpdate = res.data.state;
this.snackbar = true;
this.loading = false;
if (this.drivingLicenceNumber && this.user.drivingLicenceNumber != this.drivingLicenceNumber) {
this.$emit('updateUser', { "drivingLicenceNumber": this.drivingLicenceNumber })
}
if (this.user.telephone != this.telephone) {
this.phoneValidatedDate = null;
this.phoneToken = null;
this.displayPhoneVerification = true;
this.checkVerifiedPhone();
this.checkVerifiedEmail();
}
//this.urlAvatar = res.data.versions.square_800;
// this.displayFileUpload = false;
})
.catch(error => {
window.location.reload();
});
},
updateAddress() {
this.loadingAddress = true;
this.homeAddress.id = this.user.homeAddress ? this.user.homeAddress.id : null;
maxios
.post(this.$t('address.update.route'), this.homeAddress,
{
headers: {
'content-type': 'application/json'
}
})
.then(res => {
this.homeAddress = res.data;
this.loadingAddress = false;
this.disabledAddress = true;
this.$emit('updateUser', { "homeAddress": this.homeAddress })
});
},
avatarDelete() {
this.loadingDelete = true;
maxios
.get(this.$t('avatar.delete.route'))
.then(res => {
this.errorUpdate = res.data.state;
this.displayFileUpload = true;
this.loadingDelete = false;
this.urlAvatar = res.data[res.data.length - 1];
this.avatarWidth = null;
this.avatarHeight = null;
});
},
previewAvatar() {
if (this.avatar) {
let reader = new FileReader();
reader.addEventListener("load", function () {
this.urlAvatar = reader.result; // UPDATE PREVIEW
}.bind(this), false);
reader.readAsDataURL(this.avatar); // FIRE LOAD EVENT
}
// else {
// this.urlAvatar = this.user.avatars[this.user.avatars.length-1]; // RESET AVATAR
// }
},
selectedAvatar() {
this.avatarWidth = null;
this.avatarHeight = null;
if (!this.avatar) return;
let reader = new FileReader();
reader.readAsDataURL(this.avatar);
reader.onload = evt => {
let self = this;
let img = new Image();
img.onload = () => {
self.avatarHeight = img.height;
self.avatarWidth = img.width;
self.$refs.avatar.validate()
}
img.src = evt.target.result;
}
},
checkVerifiedPhone() {
if (this.telephone !== null) {
this.phoneVerified = this.phoneValidatedDate ? true : false;
}
},
checkVerifiedEmail() {
if (this.email !== null) {
this.emailVerified = this.emailValidatedDate ? true : false;
}
},
generateToken() {
this.loadingToken = true;
maxios
.get(this.$t('phone.token.route'))
.then(res => {
if (res.data.state) {
this.errorUpdate = true;
this.textSnackError = this.$t('snackBar.tokenError');
this.snackbar = true;
}
this.textSnackOk = this.$t('snackBar.tokenOk');
this.snackbar = true;
this.phoneToken = true;
this.token = null;
this.loadingToken = false;
})
},
sendValidationEmail() {
this.loadingEmail = true;
maxios
.get(this.$t('email.verificationRoute'))
.then(res => {
if (res.data.state) {
this.errorUpdate = true;
this.textSnackError = this.$t('snackBar.emailError');
this.snackbar = true;
}
this.textSnackOk = this.$t('snackBar.emailOk');
this.snackbar = true;
this.emailSended = true;
this.loadingEmail = false;
})
},
validateToken() {
this.loadingValidatePhone = true;
maxios
.post(this.$t('phone.validation.route'),
{
token: this.token,
telephone: this.telephone
}, {
headers: {
'content-type': 'application/json'
}
})
.then(res => {
if (!res.data) {
this.errorUpdate = true;
this.textSnackError = this.$t("snackBar.unknown");
this.snackbar = true;
}
else {
this.phoneVerified = true;
}
this.loadingValidatePhone = false;
})
// Todo create "emit" event to refresh the alerts
},
getOwnedCommunities() {
let params = {
'userId': this.user.id
}
this.disabledOwnedCommunities = true;
maxios.post(this.$t("communities.route"), params)
.then(res => {
if (res.data.length > 0) {
this.ownedCommunities = res.data;
this.hasOwnedCommunities = true;
}
this.disabledOwnedCommunities = false;
});
},
getCreatedEvents() {
let params = {
'userId': this.user.id
}
this.disabledCreatedEvents = true;
maxios.post(this.$t("events.route"), params)
.then(res => {
if (res.data.length > 0) {
this.createdEvents = res.data;
this.createdEvents.forEach(createdEvent => {
if (moment(createdEvent.toDate.date) >= moment(new Date())) {
this.hasCreatedEvents = true;
}
});
}
this.disabledCreatedEvents = false;
});
},
maxDate() {
let maxDate = new Date();
maxDate.setFullYear(maxDate.getFullYear() - this.ageMin);
return maxDate.toISOString().substr(0, 10);
},
getSso() {
let params = {
"service": this.user.ssoProvider
}
maxios.post(this.$t("urlGetSsoServices"), params)
.then(response => {
if (response.data.length > 0) {
this.ssoConnection = response.data[0];
}
});
},
changeTab(tab) {
this.$emit('changeTab', tab);
},
checkDrivingLicenceNumber() {
this.drivingLicenceNumberValid = true;
if (this.drivingLicenceNumber) {
maxios
.post(
this.$t("checkDrivingLicenceNumber.url"),
{
driverLicenceNumber: this.drivingLicenceNumber,
},
{
headers: {
"content-type": "application/json",
},
}
)
.then((response) => {
if (response.data.valid) {
this.drivingLicenceNumberValid = response.data.valid
}
else {
this.drivingLicenceNumberValid = false;
}
})
.catch(function (error) {
console.error(error);
this.drivingLicenceNumberValid = false;
});
}
},
cleanPhoneNumber() {
if (this.phoneCode == null) {
this.cleanedPhoneNumber = this.telephone;
} else {
this.cleanedPhoneNumber = '+' + this.phoneCode + this.telephone.replace(/^0+/, "");
}
}
}
}
</script>
<style lang="scss" scoped>
#avatar {
width: auto !important;
}
</style>