<template> <div> <b-button id="back-button" variant="primary" @click="goBackToNext" > <b-icon-arrow-bar-left/> Revenir </b-button> <div class="signup-container"> <div class="signup-header"> <img alt="logo" src="@/assets/logo_pigma.png"/> </div> <div class="signup-form"> <h4 class="title"> Compte existant <span class="sub-title">Modifiez les informations relatives à votre compte</span> </h4> <hr class="divider"> <ValidationObserver v-slot="{ handleSubmit }"> <b-overlay :show="loadingUserInformation" rounded="lg" :style="'padding: 5px;'" variant="white" > <form> <h5>Vos informations personnelles</h5> <hr class="divider"> <div class="row g-2 align-items-center"> <div class="col-3"> <label class="col-form-label">Nom d'utilisateur</label> </div> <div class="col"> <div class="input-group flex-nowrap"> <input v-model="formUser.username" type="text" class="form-control" placeholder="Nom d'utilisateur" disabled > </div> </div> </div> <div class="row g-2 align-items-center"> <div class="col-3"> <label class="col-form-label required">Prénom</label> </div> <div class="col"> <ValidationProvider ref="first_name" rules="required" v-slot="{ classes, errors }"> <div class="control" :class="classes"> <input v-model="formUser.first_name" type="text" class="form-control" placeholder="Prénom" > <span class="form-errors">{{ errors[0] }}</span> </div> </ValidationProvider> </div> </div> <div class="row g-2 align-items-center"> <div class="col-3"> <label class="col-form-label required">Nom</label> </div> <div class="col"> <ValidationProvider ref="last_name" rules="required" v-slot="{ classes, errors }"> <div class="control" :class="classes"> <input v-model="formUser.last_name" type="text" class="form-control" placeholder="Nom" > <span class="form-errors">{{ errors[0] }}</span> </div> </ValidationProvider> </div> </div> <div class="row g-2 align-items-center"> <div class="col-3"> <label class="col-form-label"> Adresse e-mail </label> </div> <div class="col"> <ValidationProvider ref="email" rules="required|email" v-slot="{ classes, errors }"> <div class="control" :class="classes"> <input v-model="formUser.email" type="mail" class="form-control" placeholder="Adresse e-mail" disabled > <span class="form-errors">{{ errors[0] }}</span> </div> </ValidationProvider> </div> </div> <div class="row g-2 align-items-center"> <div class="col-3"> <label class="col-form-label">Numéro de téléphone</label> </div> <div class="col"> <ValidationProvider ref="phone_number" v-slot="{ classes, errors }"> <div class="control" :class="classes"> <input v-model="formUser.phone_number" type="text" class="form-control" placeholder="" > <span class="form-errors">{{ errors[0] }}</span> </div> </ValidationProvider> </div> </div> <div class="row g-2 align-items-center"> <div class="col-3"> <label class="col-form-label">Motif de l'inscription</label> </div> <div class="col"> <textarea v-model="formUser.comments" class="form-control" /> </div> </div> <div class="row g-2 align-items-center" style="margin-bottom: 0.5em;"> <div class="col-3"> <label class="col-form-label" style="font-size: 0.87em;">Organisation(s)/Groupe(s)</label> </div> <div v-if="userData" class="col"> <div v-if="userData.usergroup_roles.length === 0"> Vous n'êtes rattaché à aucune organisation. </div> <b-list-group v-else > <b-list-group-item v-for="usergroup of userData.usergroup_roles" :key="usergroup.usergroup.id" disabled > <b>{{ usergroup.usergroup.display_name }}</b> <em> en tant que </em> <b>{{ organisationsRoles.find(el => el.choice === usergroup.role).label }}</b> </b-list-group-item> </b-list-group> </div> </div> <div class="row g-2 align-items-center"> <div class="col-3"> </div> <div v-if="userData" class="col"> <div style="margin: 0 0.5em 0.5em 0.1em; font-size: 0.9em; font-style: italic;" > Pour toute demande de modification, merci de contacter <a href="mailto:admin@example.com">admin@example.com</a>. </div> </div> </div> </form> <div class="form-footer"> <b-button :disabled="(!formUser.first_name || !formUser.last_name || !formUser.email)" @click.prevent="handleSubmit(submitUserInformations)" variant="primary" > Valider </b-button> </div> </b-overlay> </ValidationObserver> <ValidationObserver v-slot="{ handleSubmit }"> <b-overlay :show="loadingUserEmail" rounded="lg" variant="white" :style="'padding: 5px;'" > <form> <h5>Changer votre adresse e-mail</h5> <hr class="divider"> <div class="row g-2 align-items-center"> <div class="col-3" style="padding-right: 0;"> <label class="col-form-label required" style="font-size: 0.9em;">Nouvelle adresse e-mail</label> </div> <div class="col"> <ValidationProvider ref="email" rules="email" v-slot="{ classes, errors }"> <div class="control" :class="classes"> <input v-model="formEmail.new_email" type="mail" class="form-control" placeholder="Adresse e-mail" > <span class="form-errors">{{ errors[0] }}</span> </div> </ValidationProvider> </div> </div> <div class="row g-2 align-items-center"> <div class="col-3"> </div> <div class="col"> <div style="margin: 0 0.5em 0.5em 0.5em; font-size: 0.8em; font-style: italic;" > Vous pouvez demander le changement de votre adresse mail en renseignant une nouvelle adresse. Un lien de confirmation vous sera envoyé sur la nouvelle adresse. </div> </div> </div> </form> <div class="form-footer"> <b-button :disabled="!formEmail.new_email" :pressed="btnPressed" @click.prevent="handleSubmit(submitNewEmail)" variant="primary" > Valider </b-button> </div> </b-overlay> </ValidationObserver> <ValidationObserver v-slot="{ handleSubmit }"> <b-overlay :show="loadingUserPassword" rounded="lg" variant="white" :style="'padding: 5px;'" > <form> <h5>Changer votre mot de passe</h5> <hr class="divider"> <div class="row g-2 align-items-center"> <div class="col-3" style="padding-right: 0;"> <label class="col-form-label required" style="font-size: 0.9em;">Ancien mot de passe</label> </div> <div class="col"> <ValidationProvider ref="password" rules="required" v-slot="{ classes, errors }"> <div class="control" :class="classes"> <div class="input-group flex-nowrap"> <input v-model="formPassword.password" class="form-control" :type="showPassword ? 'text' : 'password'" placeholder="Ancien mot de passe" > <span v-if="!showPassword" class="input-group-text" > <b-icon icon="eye-fill" @click="showPassword = !showPassword" /> </span> <span v-else class="input-group-text" > <b-icon icon="eye-slash-fill" @click="showPassword = !showPassword" /> </span> </div> <span class="form-errors">{{ errors[0] }}</span> </div> </ValidationProvider> </div> </div> <div class="row g-2 align-items-center"> <div class="col-3" style="padding-right: 0;"> <label class="col-form-label required" style="font-size: 0.9em;">Nouveau mot de passe</label> </div> <div class="col"> <ValidationProvider ref="newPassword1" v-slot="{ classes, errors }" vid="confirmation"> <div class="control" :class="classes"> <div class="input-group flex-nowrap"> <input v-model="formPassword.newPassword1" :type="showNewPassword2 ? 'text' : 'password'" class="form-control" placeholder="Nouveau mot de passe" > <span v-if="!showNewPassword2" class="input-group-text" > <b-icon icon="eye-fill" @click="showNewPassword2 = !showNewPassword2" /> </span> <span v-else class="input-group-text" > <b-icon icon="eye-slash-fill" @click="showNewPassword2 = !showNewPassword2" /> </span> </div> <span class="form-errors">{{ errors[0] }}</span> </div> </ValidationProvider> </div> </div> <div class="row g-2 align-items-center"> <div class="col-3" style="padding-right: 0;"> <label class="col-form-label" style="font-size: 0.9em;"></label> </div> <div class="col"> <ValidationProvider ref="newPassword2" rules="confirmed:confirmation" v-slot="{ classes, errors }"> <div class="control" :class="classes"> <div class="input-group flex-nowrap"> <input v-model="formPassword.newPassword2" class="form-control" :type="showNewPassword2 ? 'text' : 'password'" placeholder="Confirmez le mot de passe" > <span v-if="!showNewPassword2" class="input-group-text" > <b-icon icon="eye-fill" @click="showNewPassword2 = !showNewPassword2" /> </span> <span v-else class="input-group-text" > <b-icon icon="eye-slash-fill" @click="showNewPassword2 = !showNewPassword2" /> </span> </div> <span class="form-errors">{{ errors[0] }}</span> </div> </ValidationProvider> </div> </div> <div class="row g-2 align-items-center"> <div class="col-3"> </div> <div class="col"> <div class="infos"> <ul> <li>Votre mot de passe ne peut pas trop ressembler à vos autres informations personnelles.</li> <li>Votre mot de passe doit contenir au minimum 8 caractères.</li> <li>Votre mot de passe ne peut pas être un mot de passe couramment utilisé.</li> <li>Votre mot de passe ne peut pas être entièrement numérique.</li> </ul> </div> </div> </div> </form> <div class="form-footer"> <b-button :disabled="(!formPassword.password || !formPassword.newPassword1 || !formPassword.newPassword2)" :pressed="btnPressed" @click.prevent="handleSubmit(submitNewPassword)" variant="primary" > Valider </b-button> </div> </b-overlay> </ValidationObserver> </div> </div> <small class="footer"> <p> Propulsé par <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a> </p> </small> </div> </template> <script> import { mapState, mapMutations, mapActions } from 'vuex'; import Swal from "sweetalert2"; import "sweetalert2/dist/sweetalert2.min.css"; import { ValidationObserver, ValidationProvider, extend, configure, } from 'vee-validate'; import { required, email, confirmed } from 'vee-validate/dist/rules'; extend('required', { ...required, message: 'Ce champ est requis', }); extend('email', { ...email, message: 'Veuillez entrer une adresse e-mail valide', }); extend('confirmed', { ...confirmed, message: 'Les mots de passe doivent être identiques', }); configure({ classes: { valid: 'is-valid', invalid: 'is-invalid', }, }); export default { name: 'UserProfile', components: { ValidationObserver, ValidationProvider, }, data() { return { loadingUserInformation: false, loadingUserPassword: false, loadingUserEmail: false, formUser: { first_name: null, last_name: null, email: null, phone_number: null, comments: null, username: null }, formEmail: { new_email: null }, formPassword: { password: null, newPassword1: null, newPassword2: null }, isOrganisationSelected: false, organisation: null, btnPressed: false, showPassword: false, showNewPassword2: false, }; }, computed: { ...mapState('user', ['userData', 'success']), ...mapState('organisations', ['organisationsRoles']), ...mapState('sign-in', [ 'next' ]) }, created() { this.SET_NEXT(this.$route.query.next || process.env.VUE_APP_NEXT_DEFAULT); if (!this.userData) { this.loadingUserInformation = true; this.GET_USER_DETAIL() .then(() => { this.formUser = { ...this.formUser, ...this.userData }; this.loadingUserInformation = false; }); } if (this.organisationsRoles.length === 0) { this.GET_ORGANISATIONS_ROLES(); } }, methods: { ...mapMutations('sign-in', [ 'SET_NEXT' ]), ...mapActions('user', [ 'GET_USER_DETAIL', 'UPDATE_USER_DETAIL' ]), ...mapActions('organisations', [ 'GET_ORGANISATIONS_ROLES' ]), goBackToNext() { this.$router.push(this.$route.path); window.location.pathname = this.next; }, submitUserInformations() { this.loadingUserInformation = true this.UPDATE_USER_DETAIL(this.formUser) .then(() => { this.GET_USER_DETAIL() .then(() => { this.formUser = { ...this.formUser, ...this.userData }; this.loadingUserInformation = false; }); }) .catch(() => { this.loadingUserInformation = false; }); }, submitNewEmail() { const data = { new_email: this.formEmail.new_email, }; this.loadingUserEmail = true; this.UPDATE_USER_DETAIL(data) .then(() => { this.loadingUserEmail = false; Swal.fire({ position: 'center', heightAuto: false, icon: 'success', text: `Un e-mail est envoyé à votre nouvelle adresse. Il contient un lien de validation sur lequel vous devez cliquer pour confirmer le changement. `, showConfirmButton: true, confirmButtonText: 'OK', confirmButtonColor: '#187CC6' }); }); }, submitNewPassword() { const data = { password: this.formPassword.password, new_password: this.formPassword.newPassword2 }; this.loadingUserPassword = true; this.UPDATE_USER_DETAIL(data) .then(() => { this.loadingUserPassword = false; if (this.success && this.success.length) { Swal.fire({ position: 'center', heightAuto: false, icon: 'success', text: `Votre mot de passe a bien été modifié. Vous allez être redirigé vers la page de connexion. `, showConfirmButton: true, confirmButtonText: 'OK', confirmButtonColor: '#187CC6' }).then((result) => { if (result.isConfirmed) { this.$router.push({ name: 'SignIn' }); } }); } }); } } } </script> <style lang="less" scoped> #back-button { font-size: 1.5em; position: -webkit-sticky; /* Safari */ position: sticky; top: 5%; left: 40px; align-self: flex-start; border: 2px solid #9BD0FF; border-radius: 8px; letter-spacing: 1px; } .signup-container { margin: auto; width: 800px; height: fit-content; .signup-header { margin: 0 1rem 1rem 1rem; img { width: 440px; } } .signup-form { margin: 5rem 1rem; h4.title { color: #373b3d; .sub-title { font-size: 75%; color: #6b7479; } } hr.solid { border-top: 2px solid #373b3d; } h5 { color: #6b7479; } form { margin-top: 32px; h5 { margin-bottom: 20px; margin-top: 40px; color: #373b3d; } .row { margin-bottom: 1.6rem; } .input-group { span { cursor: pointer; border-bottom-left-radius: 0; border-top-left-radius: 0; border-left: none } } } .infos { font-size: 0.7em; font-style: italic; margin-right: 1em; ul { padding-left: 1rem; } } .form-footer { display: flex; justify-content: flex-end; margin-left: 7px; margin-top: 30px; button { margin-left: 2em; } button.btn-primary { border: 2px solid #9BD0FF; border-radius: 8px; } button.btn-outline-secondary { background-color: #F7F8FA; border: 2px solid #A9B2B9; border-radius: 8px; color: #2F3234; } button.btn-outline-secondary:hover { color: white; background-color: #4b4b4b; } } } } .form-errors { color: #EB0600 !important; } .form-success { color: #30C963 !important; } .footer { position: relative; bottom: 0; font-size: small; margin-top: 2rem; } .footer a { text-decoration: none; } </style>