<div class="flex flex-col justify-center gap-y-4">
<div>
<h2 class="h5">Mon profil</h2>
</div>
<form class="form form-edit-account" action="#" method="post" id="form-validate" enctype="multipart/form-data" x-data="Object.assign(hyva.formValidation($el), initForm())" @submit.prevent="submitForm()" autocomplete="off" novalidate="">
<fieldset class="fieldset info flex flex-col gap-y-4">
<input name="form_key" type="hidden" value="xxx">
<div class="relative flex flex-row items-center gap-x-3 field field-reserved">
<label for="prefix" class="flex items-center gap-x-1">
Civilité
<span class="required text-error">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M8.48605 7.23022L8.81938 7.03777L11.8608 5.28179C12.0734 5.15906 12.3452 5.23189 12.468 5.44446C12.5907 5.65704 12.5179 5.92886 12.3053 6.05159L9.26383 7.80757L8.9305 8.00002L9.26383 8.19247L12.3053 9.94845C12.5179 10.0712 12.5907 10.343 12.468 10.5556C12.3452 10.7681 12.0734 10.841 11.8608 10.7183L8.81938 8.96226L8.48605 8.76981V9.15471V12.6667C8.48605 12.9121 8.28706 13.1111 8.0416 13.1111C7.79614 13.1111 7.59716 12.9121 7.59716 12.6667V9.15472V8.76982L7.26382 8.96227L4.22237 10.7183L4.32568 10.8972L4.22237 10.7183C4.0098 10.841 3.73798 10.7681 3.61525 10.5556C3.49252 10.343 3.56536 10.0712 3.77793 9.94845L6.81938 8.19247L7.15272 8.00002L6.81938 7.80757L3.77794 6.05159L3.66964 6.23916L3.77794 6.05159C3.56536 5.92886 3.49253 5.65704 3.61526 5.44446C3.73799 5.23189 4.0098 5.15906 4.22238 5.28179L7.26382 7.03776L7.59716 7.23021V6.84531V3.33335C7.59716 3.08789 7.79614 2.88891 8.0416 2.88891C8.28706 2.88891 8.48605 3.08789 8.48605 3.33335V6.84532V7.23022Z" fill="currentColor" stroke="currentColor" stroke-width="0.444444" />
</svg>
</span>
</label>
<div class="flex space-x-3">
<!-- replace identifiers with normal values (for,id,name etc...) -->
<label class="selection-control-label selection-control-radio ">
<input checked required type="radio" id="prefix1" name="prefix" class="" value="M." @input.debounce="onChange">
<span class="
">
M.
</span>
</label>
<!-- replace identifiers with normal values (for,id,name etc...) -->
<label class="selection-control-label selection-control-radio ">
<input type="radio" id="prefix2" name="prefix" class="" value="Mme." @input.debounce="onChange">
<span class="
">
Mme.
</span>
</label>
</div>
</div>
<div class="flex flex-col gap-y-4 md:flex-row md:gutter-half">
<div class="field field-reserved w-full md:w-1/2">
<div class="flex flex-col w-full gap-y-1">
<div class="input-wrapper flex flex-col relative w-full floating-label">
<input type="text" name="firstname" id="firstname" value="Anakin" class="form-input w-full peer
required
" placeholder="" required @input.debounce="onChange">
<div class="label-wrapper ">
<label for="firstname" class="flex flex-row items-center gap-2">
<span class="flex-grow">Prénom</span>
<div class="required text-error">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M8.48605 7.23022L8.81938 7.03777L11.8608 5.28179C12.0734 5.15906 12.3452 5.23189 12.468 5.44446C12.5907 5.65704 12.5179 5.92886 12.3053 6.05159L9.26383 7.80757L8.9305 8.00002L9.26383 8.19247L12.3053 9.94845C12.5179 10.0712 12.5907 10.343 12.468 10.5556C12.3452 10.7681 12.0734 10.841 11.8608 10.7183L8.81938 8.96226L8.48605 8.76981V9.15471V12.6667C8.48605 12.9121 8.28706 13.1111 8.0416 13.1111C7.79614 13.1111 7.59716 12.9121 7.59716 12.6667V9.15472V8.76982L7.26382 8.96227L4.22237 10.7183L4.32568 10.8972L4.22237 10.7183C4.0098 10.841 3.73798 10.7681 3.61525 10.5556C3.49252 10.343 3.56536 10.0712 3.77793 9.94845L6.81938 8.19247L7.15272 8.00002L6.81938 7.80757L3.77794 6.05159L3.66964 6.23916L3.77794 6.05159C3.56536 5.92886 3.49253 5.65704 3.61526 5.44446C3.73799 5.23189 4.0098 5.15906 4.22238 5.28179L7.26382 7.03776L7.59716 7.23021V6.84531V3.33335C7.59716 3.08789 7.79614 2.88891 8.0416 2.88891C8.28706 2.88891 8.48605 3.08789 8.48605 3.33335V6.84532V7.23022Z" fill="currentColor" stroke="currentColor" stroke-width="0.444444" />
</svg>
</div>
</label>
</div>
</div>
</div>
</div>
<div class="field field-reserved w-full md:w-1/2">
<div class="flex flex-col w-full gap-y-1">
<div class="input-wrapper flex flex-col relative w-full floating-label">
<input type="text" name="lastname" id="lastname" value="Skywalker" class="form-input w-full peer
required
" placeholder="" required @input.debounce="onChange">
<div class="label-wrapper ">
<label for="lastname" class="flex flex-row items-center gap-2">
<span class="flex-grow">Nom</span>
<div class="required text-error">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M8.48605 7.23022L8.81938 7.03777L11.8608 5.28179C12.0734 5.15906 12.3452 5.23189 12.468 5.44446C12.5907 5.65704 12.5179 5.92886 12.3053 6.05159L9.26383 7.80757L8.9305 8.00002L9.26383 8.19247L12.3053 9.94845C12.5179 10.0712 12.5907 10.343 12.468 10.5556C12.3452 10.7681 12.0734 10.841 11.8608 10.7183L8.81938 8.96226L8.48605 8.76981V9.15471V12.6667C8.48605 12.9121 8.28706 13.1111 8.0416 13.1111C7.79614 13.1111 7.59716 12.9121 7.59716 12.6667V9.15472V8.76982L7.26382 8.96227L4.22237 10.7183L4.32568 10.8972L4.22237 10.7183C4.0098 10.841 3.73798 10.7681 3.61525 10.5556C3.49252 10.343 3.56536 10.0712 3.77793 9.94845L6.81938 8.19247L7.15272 8.00002L6.81938 7.80757L3.77794 6.05159L3.66964 6.23916L3.77794 6.05159C3.56536 5.92886 3.49253 5.65704 3.61526 5.44446C3.73799 5.23189 4.0098 5.15906 4.22238 5.28179L7.26382 7.03776L7.59716 7.23021V6.84531V3.33335C7.59716 3.08789 7.79614 2.88891 8.0416 2.88891C8.28706 2.88891 8.48605 3.08789 8.48605 3.33335V6.84532V7.23022Z" fill="currentColor" stroke="currentColor" stroke-width="0.444444" />
</svg>
</div>
</label>
</div>
</div>
</div>
</div>
</div>
<div class="grid md:grid-cols-2 md:gutter-half field field-reserved">
<div class="flex flex-col w-full gap-y-1">
<div x-data="initDatePicker()" class="input-wrapper flex flex-col relative w-full floating-label">
<input type="text" x-model="value" @click="showDatepicker = !showDatepicker" @keydown="onInputKeydown($event)" @paste="$event.preventDefault()" autocomplete="off" class="form-input w-full peer
required" placeholder="" name="dob" id="dob" required>
<div class="input-svg calendar">
<div type="button" @click="showDatepicker = true">
<svg class=" shrink-0" width="16" height="16" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path d="M6.75 3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 0 1 2.25-2.25h13.5A2.25 2.25 0 0 1 21 7.5v11.25m-18 0A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75m-18 0v-7.5A2.25 2.25 0 0 1 5.25 9h13.5A2.25 2.25 0 0 1 21 11.25v7.5m-9-6h.008v.008H12v-.008ZM12 15h.008v.008H12V15Zm0 2.25h.008v.008H12v-.008ZM9.75 15h.008v.008H9.75V15Zm0 2.25h.008v.008H9.75v-.008ZM7.5 15h.008v.008H7.5V15Zm0 2.25h.008v.008H7.5v-.008Zm6.75-4.5h.008v.008h-.008v-.008Zm0 2.25h.008v.008h-.008V15Zm0 2.25h.008v.008h-.008v-.008Zm2.25-4.5h.008v.008H16.5v-.008Zm0 2.25h.008v.008H16.5V15Z" stroke="currentColor" stroke-width="1.5" fill="none" />
</svg>
</div>
</div>
<div class="label-wrapper ">
<label for="dob" class="flex flex-row items-center gap-2">
<span class="flex-grow">Date de naissance</span>
<div class="required text-error">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M8.48605 7.23022L8.81938 7.03777L11.8608 5.28179C12.0734 5.15906 12.3452 5.23189 12.468 5.44446C12.5907 5.65704 12.5179 5.92886 12.3053 6.05159L9.26383 7.80757L8.9305 8.00002L9.26383 8.19247L12.3053 9.94845C12.5179 10.0712 12.5907 10.343 12.468 10.5556C12.3452 10.7681 12.0734 10.841 11.8608 10.7183L8.81938 8.96226L8.48605 8.76981V9.15471V12.6667C8.48605 12.9121 8.28706 13.1111 8.0416 13.1111C7.79614 13.1111 7.59716 12.9121 7.59716 12.6667V9.15472V8.76982L7.26382 8.96227L4.22237 10.7183L4.32568 10.8972L4.22237 10.7183C4.0098 10.841 3.73798 10.7681 3.61525 10.5556C3.49252 10.343 3.56536 10.0712 3.77793 9.94845L6.81938 8.19247L7.15272 8.00002L6.81938 7.80757L3.77794 6.05159L3.66964 6.23916L3.77794 6.05159C3.56536 5.92886 3.49253 5.65704 3.61526 5.44446C3.73799 5.23189 4.0098 5.15906 4.22238 5.28179L7.26382 7.03776L7.59716 7.23021V6.84531V3.33335C7.59716 3.08789 7.79614 2.88891 8.0416 2.88891C8.28706 2.88891 8.48605 3.08789 8.48605 3.33335V6.84532V7.23022Z" fill="currentColor" stroke="currentColor" stroke-width="0.444444" />
</svg>
</div>
</label>
</div>
<div class="absolute left-0 top-full p-3 bg-white rounded-lg shadow calendar-window z-30" x-cloak x-transition x-show="showDatepicker" @click.outside="showDatepicker = false" @keydown="onCalendarKeydown($event)">
<div class="flex justify-between items-center mb-2">
<div>
<select name="datepicker_month" x-model="month" class="text-sm rounded border-gray-300" @change="goToMonth(month)">
<template x-for="(monthName, index) in labels.monthNames">
<option :value="index" x-text="monthName"></option>
</template>
</select>
<select name="datepicker_year" x-model="year" class="text-sm rounded border-gray-300" @change="recalcDaysGrid()">
<template x-for="option in yearRange">
<option :value="option" x-text="option"></option>
</template>
</select>
</div>
<div class="min-w-16">
<button type="button" class="inline-flex p-1 rounded transition-colors cursor-pointer hover:bg-gray-100" :class="{'cursor-not-allowed opacity-25': isFirstMonth()}" :disabled="isFirstMonth()" :title="labels.prevText" @click="goToMonth(month - 1)">
<svg class=" shrink-0" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.7803 5.22431C12.0732 5.5172 12.0732 5.99208 11.7803 6.28497L8.06066 10.0046L11.7803 13.7243C12.0732 14.0172 12.0732 14.4921 11.7803 14.785C11.4874 15.0779 11.0126 15.0779 10.7197 14.785L6.46967 10.535C6.17678 10.2421 6.17678 9.7672 6.46967 9.47431L10.7197 5.22431C11.0126 4.93142 11.4874 4.93142 11.7803 5.22431Z" fill="currentColor" />
</svg> <span class="sr-only" x-text="labels.prevText"></span>
</button>
<button type="button" class="inline-flex p-1 rounded transition-colors cursor-pointer hover:bg-gray-100" :class="{'cursor-not-allowed opacity-25': isLastMonth() }" :disabled="isLastMonth()" :title="labels.nextText" @click="goToMonth(month + 1)">
<svg class=" shrink-0" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.21967 5.21967C8.51256 4.92678 8.98744 4.92678 9.28033 5.21967L13.5303 9.46967C13.8232 9.76256 13.8232 10.2374 13.5303 10.5303L9.28033 14.7803C8.98744 15.0732 8.51256 15.0732 8.21967 14.7803C7.92678 14.4874 7.92678 14.0126 8.21967 13.7197L11.9393 10L8.21967 6.28033C7.92678 5.98744 7.92678 5.51256 8.21967 5.21967Z" fill="currentColor" />
</svg> <span class="sr-only" x-text="labels.nextText"></span>
</button>
</div>
</div>
<div class="grid grid-cols-7 -mx-1">
<template x-for="(day, index) in labels.dayNamesShort" :key="index">
<div class="p-0.5">
<div x-text="day" class="text-gray-800 font-medium text-center text-xs h-6 flex items-centerjustify-center">
</div>
</div>
</template>
<template x-for="(date, dateIndex) in dayNumbers" :key="dateIndex">
<button type="button" class="p-1" :style="getDayStyle(date)" @click="if (canSelectDate(date)) { setDate(date) }">
<div x-text="date" class="text-center text-sm rounded-full transition-colors flex items-center justify-center h-8" :class="{
'cursor-pointer hover:bg-gray-100 hover:text-black': canSelectDate(date),
'bg-brand text-white': isToday(date),
'text-gray-500': isInFuture(date)
}"></div>
</button>
</template>
</div>
<button class="p-2 w-full text-sm text-center rounded border border-gray-300 hover:bg-gray-100" x-text="labels.currentText" @click.prevent="goToday()"></button>
</div>
</div>
</div>
<script>
// script from vendor/hyva-themes/magento2-default-theme/Magento_Customer/templates/widget/dob.phtml
function initDatePicker() {
const format = 'dd/MM/y';
const firstDayOfWeek = '1';
const labelsConfig = {
"closeText": "Termin\u00e9",
"prevText": "Pr\u00e9c",
"nextText": "Suivant",
"currentText": "Aujourd'hui",
"monthNames": ["janvier", "f\u00e9vrier", "mars", "avril", "mai", "juin", "juillet", "ao\u00fbt", "septembre", "octobre", "novembre", "d\u00e9cembre"],
"monthNamesShort": ["janv.", "f\u00e9vr.", "mars", "avr.", "mai", "juin", "juil.", "ao\u00fbt", "sept.", "oct.", "nov.", "d\u00e9c."],
"dayNames": ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"],
"dayNamesShort": ["dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam."],
"dayNamesMin": ["di", "lu", "ma", "me", "je", "ve", "sa"]
};
return {
showDatepicker: false,
value: '28/06/1974',
month: '',
year: '',
today: new Date(),
dayNumbers: [],
yearRange: [],
labels: labelsConfig,
dateFormatter: DateFormatter(format),
calendarWindow: null,
init() {
const today = new Date();
this.initYearsRange();
this.correctWeeks();
this.$nextTick(() => {
this.month = today.getMonth();
this.year = today.getFullYear();
this.recalcDaysGrid();
this.calendarWindow = this.$root.querySelector('.calendar-window');
});
},
initYearsRange() {
const today = new Date();
const thisYear = today.getFullYear();
const minimalYear = thisYear - 120;
const range = [];
for (let year = thisYear; year >= minimalYear; year--) {
range.unshift(year);
}
this.yearRange = range;
},
correctWeeks() {
if (firstDayOfWeek > 0) {
this.labels.dayNames = [
...this.labels.dayNames.slice(firstDayOfWeek),
...this.labels.dayNames.slice(0, firstDayOfWeek)
];
this.labels.dayNamesShort = [
...this.labels.dayNamesShort.slice(firstDayOfWeek),
...this.labels.dayNamesShort.slice(0, firstDayOfWeek)
];
}
},
isToday(date) {
const today = new Date();
const d = new Date(this.year, this.month, date);
return today.toDateString() === d.toDateString();
},
setDate(date) {
const selectedDate = new Date(this.year, this.month, date);
this.value = this.dateFormatter.format(selectedDate);
this.showDatepicker = false;
},
recalcDaysGrid() {
const daysInMonth = new Date(this.year, this.month + 1, 0).getDate();
const dayNumbers = [];
for (let i = 1; i <= daysInMonth; i++) {
dayNumbers.push(i);
}
this.dayNumbers = dayNumbers;
},
getDayStyle(day) {
const firstDayInWeek = this.correctDayOfWeek(new Date(this.year, this.month).getDay());
if (day.toString() === "1") {
return `grid-column-start: ${firstDayInWeek + 1}`;
}
return '';
},
correctDayOfWeek(day) {
let corrected = day - firstDayOfWeek;
if (corrected < 0) {
corrected += 7;
}
return corrected;
},
goToMonth(month) {
const date = new Date(this.year, this.month);
date.setMonth(month);
this.month = date.getMonth();
this.year = date.getFullYear();
this.recalcDaysGrid();
},
goToday() {
this.year = this.today.getFullYear();
this.month = this.today.getMonth();
this.recalcDaysGrid();
},
isInFuture(date) {
const today = new Date();
return this.year === today.getFullYear() &&
this.month === today.getMonth() &&
date > today.getDate()
},
isFirstMonth() {
return this.year === this.yearRange[0] && this.month === 0;
},
isLastMonth() {
return this.year === this.yearRange[this.yearRange.length - 1] &&
this.month === this.today.getMonth()
},
canSelectDate(date) {
return !this.isToday(date) && !this.isInFuture(date)
},
onInputKeydown(evt) {
const keyCode = evt.code;
if (keyCode === "Escape") {
this.showDatepicker = false;
}
if (keyCode === "Tab") {
return;
}
if (keyCode === "Enter") {
evt.preventDefault();
this.showDatepicker = true;
hyva.trapFocus(this.calendarWindow);
}
if (keyCode !== "Enter") {
evt.preventDefault();
}
},
onCalendarKeydown(evt) {
const keyCode = evt.code;
if (keyCode === "Escape") {
hyva.releaseFocus(this.calendarWindow);
this.showDatepicker = false;
}
}
}
}
function DateFormatter(template) {
return {
template: template,
map: {
'd': {
day: 'numeric'
},
'dd': {
day: '2-digit'
},
'D': {
weekday: 'short'
},
'DD': {
weekday: 'long'
},
'E': {
weekday: 'short'
},
'EE': {
weekday: 'short'
},
'EEE': {
weekday: 'short'
},
'EEEE': {
weekday: 'long'
},
'M': {
month: '2-digit'
},
'MM': {
month: '2-digit'
},
'MMM': {
month: 'short'
},
'MMMM': {
month: 'long'
},
'm': {
month: 'numeric'
},
'mm': {
month: '2-digit'
},
'y': {
year: 'numeric'
},
'Y': {
year: 'numeric'
},
'yy': {
year: 'numeric'
},
'yyyy': {
year: 'numeric'
}
},
format(date) {
const parsedFormat = template.match(new RegExp(/([mM]+)|([dD]+)|([yY]+)/g));
const options = parsedFormat.reduce((accumulator, match) => {
if (this.map[match]) {
return {
...accumulator,
...this.map[match]
}
}
return accumulator;
}, {})
const dateData = Intl.DateTimeFormat('en-US', options).formatToParts(date);
return parsedFormat.reduce((result, valueTemplate) => {
const dateItem = dateData.find(item => item.type === Object.keys(this.map[valueTemplate])[0]);
if (dateItem) {
return result.replace(valueTemplate, dateItem.value);
}
return result;
}, this.template);
}
}
}
</script>
</div>
<div>
<span class="text-body-xs">
Champs obligatoires<span class="text-error">*</span>
</span>
</div>
<div class="flex">
<!-- replace identifiers with normal values (for,id,name etc...) -->
<label class="selection-control-label selection-control-checkbox ">
<input @change="handleCheckboxChange('email-fields')" type="checkbox" id="change-email" name="change_email" class="" value="1" @input.debounce="onChange">
<span class="
">
Modifier l'adresse mail
</span>
</label>
</div>
<div class="flex">
<!-- replace identifiers with normal values (for,id,name etc...) -->
<label class="selection-control-label selection-control-checkbox ">
<input @change="handleCheckboxChange('password-fields')" type="checkbox" id="change-password" name="change_password" class="" value="1" @input.debounce="onChange">
<span class="
">
Modifier le mot de passe
</span>
</label>
</div>
<template x-if="showEmailField">
<div class="field field-reserved" id="email-fields">
<div class="flex flex-col w-full gap-y-1">
<div class="input-wrapper flex flex-col relative w-full floating-label">
<input type="email" name="email" id="email" value="test@gmail.com" class="form-input w-full peer
required
" placeholder="" required @input.debounce="onChange">
<div class="label-wrapper ">
<label for="email" class="flex flex-row items-center gap-2">
<span class="flex-grow">E-mail</span>
<div class="required text-error">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M8.48605 7.23022L8.81938 7.03777L11.8608 5.28179C12.0734 5.15906 12.3452 5.23189 12.468 5.44446C12.5907 5.65704 12.5179 5.92886 12.3053 6.05159L9.26383 7.80757L8.9305 8.00002L9.26383 8.19247L12.3053 9.94845C12.5179 10.0712 12.5907 10.343 12.468 10.5556C12.3452 10.7681 12.0734 10.841 11.8608 10.7183L8.81938 8.96226L8.48605 8.76981V9.15471V12.6667C8.48605 12.9121 8.28706 13.1111 8.0416 13.1111C7.79614 13.1111 7.59716 12.9121 7.59716 12.6667V9.15472V8.76982L7.26382 8.96227L4.22237 10.7183L4.32568 10.8972L4.22237 10.7183C4.0098 10.841 3.73798 10.7681 3.61525 10.5556C3.49252 10.343 3.56536 10.0712 3.77793 9.94845L6.81938 8.19247L7.15272 8.00002L6.81938 7.80757L3.77794 6.05159L3.66964 6.23916L3.77794 6.05159C3.56536 5.92886 3.49253 5.65704 3.61526 5.44446C3.73799 5.23189 4.0098 5.15906 4.22238 5.28179L7.26382 7.03776L7.59716 7.23021V6.84531V3.33335C7.59716 3.08789 7.79614 2.88891 8.0416 2.88891C8.28706 2.88891 8.48605 3.08789 8.48605 3.33335V6.84532V7.23022Z" fill="currentColor" stroke="currentColor" stroke-width="0.444444" />
</svg>
</div>
</label>
</div>
</div>
</div>
</div>
</template>
<template x-if="showEmailField || showPasswordFields">
<div class="field field-reserved password current required" id="password-fields">
<div class="flex flex-col w-full gap-y-1">
<div x-data="{showPassword: false}" class="input-wrapper flex flex-col relative w-full floating-label">
<div class="sr-only" aria-live="polite">
<template x-if="!showPassword">
<span>Password hidden</span>
</template>
<template x-if="showPassword">
<span>Password shown</span>
</template>
</div>
<!-- Keep input verification if Magento has one -->
<input type="password" class="form-input w-full peer required" required placeholder="" :type="showPassword ? 'text' : 'password'" name="current_password" id="current-password" @input.debounce="onChange">
<div class="input-svg password">
<button type="button" :aria-pressed="showPassword" x-on:click="showPassword = !showPassword" :aria-label="showPassword ? 'Hide Password' : 'Show Password'">
<template x-if="showPassword">
<svg class=" shrink-0" width="16" height="16" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z" fill="none" />
<path fill-rule="evenodd" clip-rule="evenodd" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" fill="none" />
</svg> </template>
<template x-if="!showPassword">
<svg class=" shrink-0" width="16" height="16" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path d="M3.98 8.223A10.477 10.477 0 0 0 1.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.451 10.451 0 0 1 12 4.5c4.756 0 8.773 3.162 10.065 7.498a10.522 10.522 0 0 1-4.293 5.774M6.228 6.228 3 3m3.228 3.228 3.65 3.65m7.894 7.894L21 21m-3.228-3.228-3.65-3.65m0 0a3 3 0 1 0-4.243-4.243m4.242 4.242L9.88 9.88" stroke="currentColor" stroke-width="1.5" fill="none" />
</svg> </template>
</button>
</div>
<div class="label-wrapper ">
<label for="current-password" class="flex flex-row items-center gap-2">
<span class="flex-grow">Current Password</span>
<div class="required text-error">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M8.48605 7.23022L8.81938 7.03777L11.8608 5.28179C12.0734 5.15906 12.3452 5.23189 12.468 5.44446C12.5907 5.65704 12.5179 5.92886 12.3053 6.05159L9.26383 7.80757L8.9305 8.00002L9.26383 8.19247L12.3053 9.94845C12.5179 10.0712 12.5907 10.343 12.468 10.5556C12.3452 10.7681 12.0734 10.841 11.8608 10.7183L8.81938 8.96226L8.48605 8.76981V9.15471V12.6667C8.48605 12.9121 8.28706 13.1111 8.0416 13.1111C7.79614 13.1111 7.59716 12.9121 7.59716 12.6667V9.15472V8.76982L7.26382 8.96227L4.22237 10.7183L4.32568 10.8972L4.22237 10.7183C4.0098 10.841 3.73798 10.7681 3.61525 10.5556C3.49252 10.343 3.56536 10.0712 3.77793 9.94845L6.81938 8.19247L7.15272 8.00002L6.81938 7.80757L3.77794 6.05159L3.66964 6.23916L3.77794 6.05159C3.56536 5.92886 3.49253 5.65704 3.61526 5.44446C3.73799 5.23189 4.0098 5.15906 4.22238 5.28179L7.26382 7.03776L7.59716 7.23021V6.84531V3.33335C7.59716 3.08789 7.79614 2.88891 8.0416 2.88891C8.28706 2.88891 8.48605 3.08789 8.48605 3.33335V6.84532V7.23022Z" fill="currentColor" stroke="currentColor" stroke-width="0.444444" />
</svg>
</div>
</label>
</div>
</div>
</div>
</div>
</template>
<template x-if="showPasswordFields">
<div class="flex flex-col gap-y-4">
<div x-data="passwordValidator()" x-init="init()" class="flex flex-col gap-y-1 field field-reserved">
<div class="flex flex-col w-full gap-y-1">
<div x-data="{showPassword: false}" class="input-wrapper flex flex-col relative w-full floating-label">
<div class="sr-only" aria-live="polite">
<template x-if="!showPassword">
<span>Password hidden</span>
</template>
<template x-if="showPassword">
<span>Password shown</span>
</template>
</div>
<!-- Keep input verification if Magento has one -->
<input type="password" class="form-input w-full peer required" required placeholder="" :type="showPassword ? 'text' : 'password'" name="password" id="password" x-model='password' @input.debounce="onChange">
<div class="input-svg password">
<button type="button" :aria-pressed="showPassword" x-on:click="showPassword = !showPassword" :aria-label="showPassword ? 'Hide Password' : 'Show Password'">
<template x-if="showPassword">
<svg class=" shrink-0" width="16" height="16" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z" fill="none" />
<path fill-rule="evenodd" clip-rule="evenodd" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" fill="none" />
</svg> </template>
<template x-if="!showPassword">
<svg class=" shrink-0" width="16" height="16" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path d="M3.98 8.223A10.477 10.477 0 0 0 1.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.451 10.451 0 0 1 12 4.5c4.756 0 8.773 3.162 10.065 7.498a10.522 10.522 0 0 1-4.293 5.774M6.228 6.228 3 3m3.228 3.228 3.65 3.65m7.894 7.894L21 21m-3.228-3.228-3.65-3.65m0 0a3 3 0 1 0-4.243-4.243m4.242 4.242L9.88 9.88" stroke="currentColor" stroke-width="1.5" fill="none" />
</svg> </template>
</button>
</div>
<div class="label-wrapper ">
<label for="password" class="flex flex-row items-center gap-2">
<span class="flex-grow">New Password</span>
<div class="required text-error">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M8.48605 7.23022L8.81938 7.03777L11.8608 5.28179C12.0734 5.15906 12.3452 5.23189 12.468 5.44446C12.5907 5.65704 12.5179 5.92886 12.3053 6.05159L9.26383 7.80757L8.9305 8.00002L9.26383 8.19247L12.3053 9.94845C12.5179 10.0712 12.5907 10.343 12.468 10.5556C12.3452 10.7681 12.0734 10.841 11.8608 10.7183L8.81938 8.96226L8.48605 8.76981V9.15471V12.6667C8.48605 12.9121 8.28706 13.1111 8.0416 13.1111C7.79614 13.1111 7.59716 12.9121 7.59716 12.6667V9.15472V8.76982L7.26382 8.96227L4.22237 10.7183L4.32568 10.8972L4.22237 10.7183C4.0098 10.841 3.73798 10.7681 3.61525 10.5556C3.49252 10.343 3.56536 10.0712 3.77793 9.94845L6.81938 8.19247L7.15272 8.00002L6.81938 7.80757L3.77794 6.05159L3.66964 6.23916L3.77794 6.05159C3.56536 5.92886 3.49253 5.65704 3.61526 5.44446C3.73799 5.23189 4.0098 5.15906 4.22238 5.28179L7.26382 7.03776L7.59716 7.23021V6.84531V3.33335C7.59716 3.08789 7.79614 2.88891 8.0416 2.88891C8.28706 2.88891 8.48605 3.08789 8.48605 3.33335V6.84532V7.23022Z" fill="currentColor" stroke="currentColor" stroke-width="0.444444" />
</svg>
</div>
</label>
</div>
</div>
</div>
<div class="text-body-xs text-black/40 flex flex-col gap-y-1">
<span class="font-bold">
Votre mot de passe doit contenir au moins :
</span>
<div class="flex flex-wrap items-start gap-x-1">
<template x-for="(rule, index) in rules" :key="index">
<div class="flex items-start gap-x-1" :class="rule.valid ? 'text-success' : 'text-black/40'">
<svg class=" shrink-0" width="16" height="16" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" stroke="currentColor" stroke-width="1.5" fill="none" />
</svg>
<div class="input-password-counter-label" x-text="rule.label"></div>
</div>
</template>
</div>
<div id="password-strength-meter-container" data-role="password-strength-meter" aria-live="polite">
<div id="password-strength-meter" class="password-strength-meter">
Fiabilité du mot de passe :
<span id="password-strength-meter-label" data-role="password-strength-meter-label" x-text="strengthLabel">
</span>
</div>
</div>
</div>
</div>
<div class="field field-reserved">
<div class="flex flex-col w-full gap-y-1">
<div x-data="{showPassword: false}" class="input-wrapper flex flex-col relative w-full floating-label">
<div class="sr-only" aria-live="polite">
<template x-if="!showPassword">
<span>Password hidden</span>
</template>
<template x-if="showPassword">
<span>Password shown</span>
</template>
</div>
<!-- Keep input verification if Magento has one -->
<input type="password" class="form-input w-full peer required" required placeholder="" :type="showPassword ? 'text' : 'password'" name="password_confirmation" id="password-confirmation" @input.debounce="onChange">
<div class="input-svg password">
<button type="button" :aria-pressed="showPassword" x-on:click="showPassword = !showPassword" :aria-label="showPassword ? 'Hide Password' : 'Show Password'">
<template x-if="showPassword">
<svg class=" shrink-0" width="16" height="16" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z" fill="none" />
<path fill-rule="evenodd" clip-rule="evenodd" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" fill="none" />
</svg> </template>
<template x-if="!showPassword">
<svg class=" shrink-0" width="16" height="16" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path d="M3.98 8.223A10.477 10.477 0 0 0 1.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.451 10.451 0 0 1 12 4.5c4.756 0 8.773 3.162 10.065 7.498a10.522 10.522 0 0 1-4.293 5.774M6.228 6.228 3 3m3.228 3.228 3.65 3.65m7.894 7.894L21 21m-3.228-3.228-3.65-3.65m0 0a3 3 0 1 0-4.243-4.243m4.242 4.242L9.88 9.88" stroke="currentColor" stroke-width="1.5" fill="none" />
</svg> </template>
</button>
</div>
<div class="label-wrapper ">
<label for="password-confirmation" class="flex flex-row items-center gap-2">
<span class="flex-grow">Confirm New Password</span>
<div class="required text-error">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M8.48605 7.23022L8.81938 7.03777L11.8608 5.28179C12.0734 5.15906 12.3452 5.23189 12.468 5.44446C12.5907 5.65704 12.5179 5.92886 12.3053 6.05159L9.26383 7.80757L8.9305 8.00002L9.26383 8.19247L12.3053 9.94845C12.5179 10.0712 12.5907 10.343 12.468 10.5556C12.3452 10.7681 12.0734 10.841 11.8608 10.7183L8.81938 8.96226L8.48605 8.76981V9.15471V12.6667C8.48605 12.9121 8.28706 13.1111 8.0416 13.1111C7.79614 13.1111 7.59716 12.9121 7.59716 12.6667V9.15472V8.76982L7.26382 8.96227L4.22237 10.7183L4.32568 10.8972L4.22237 10.7183C4.0098 10.841 3.73798 10.7681 3.61525 10.5556C3.49252 10.343 3.56536 10.0712 3.77793 9.94845L6.81938 8.19247L7.15272 8.00002L6.81938 7.80757L3.77794 6.05159L3.66964 6.23916L3.77794 6.05159C3.56536 5.92886 3.49253 5.65704 3.61526 5.44446C3.73799 5.23189 4.0098 5.15906 4.22238 5.28179L7.26382 7.03776L7.59716 7.23021V6.84531V3.33335C7.59716 3.08789 7.79614 2.88891 8.0416 2.88891C8.28706 2.88891 8.48605 3.08789 8.48605 3.33335V6.84532V7.23022Z" fill="currentColor" stroke="currentColor" stroke-width="0.444444" />
</svg>
</div>
</label>
</div>
</div>
</div>
</div>
</div>
</template>
<div>
<div class="flex items-center justify-end">
<button type="submit" class=" btn btn-dark btn-solid btn-size-lg">
Enregistrer
</button>
</div>
</div>
</fieldset>
</form>
<div class="text-body-xs text-black/64">
NAOS France (Etat Pur, Bioderma, Institut Esthederm) collecte les données personnelles ci-dessus afin de créer
votre compte Etat Pur, vous permettre de bénéficier des services associés et vous permettre de participer Ã
notre programme de fidélité. Pour en savoir plus sur l’utilisation de vos données et sur vos droits, cliquez-ici
</div>
</div>
<script>
// script from vendor/hyva-themes/magento2-default-theme/Magento_Customer/templates/form/edit.phtml
function initForm() {
return {
errors: 0,
hasCaptchaToken: 0,
displayErrorMessage: false,
errorMessages: [],
showEmailField: false,
showPasswordNew: false,
showPasswordConfirm: false,
showPasswordCurrent: false,
showPasswordFields: false,
setErrorMessages(messages) {
this.errorMessages = [messages]
this.displayErrorMessage = this.errorMessages.length
},
submitForm() {
this.validate()
.then(() => {
// Do not rename $form, the variable is expected to be declared in the recaptcha output
const $form = document.querySelector('#form-validate');
if (this.errors === 0) {
$form.submit();
}
})
.catch((invalid) => {
if (invalid.length > 0) {
invalid[0].focus();
}
})
},
handleCheckboxChange(checkboxId) {
if (checkboxId === 'email-fields') {
this.showEmailField = !this.showEmailField
}
if (checkboxId === 'password-fields') {
this.showPasswordFields = !this.showPasswordFields
}
this.$nextTick(() => {
const firstFocusableElement = document.querySelector(`
#${checkboxId} input,
#${checkboxId} textarea,
#${checkboxId} select
`)
firstFocusableElement && firstFocusableElement.focus()
})
}
}
}
</script>
<script>
function passwordValidator() {
return {
password: '',
rules: [{
label: '12 caractères',
test: pwd => pwd.length >= 12,
valid: false
},
{
label: '1 minuscule',
test: pwd => /[a-z]/.test(pwd),
valid: false
},
{
label: '1 majuscule',
test: pwd => /[A-Z]/.test(pwd),
valid: false
},
{
label: '1 chiffre',
test: pwd => /[0-9]/.test(pwd),
valid: false
},
{
label: '1 caractère spécial',
test: pwd => /[^a-zA-Z0-9]/.test(pwd),
valid: false
},
],
get strengthLabel() {
const validCount = this.rules.filter(r => r.valid).length;
if (!this.password) return 'Aucune';
if (validCount <= 2) return 'Faible';
if (validCount <= 4) return 'Moyen';
return 'Fort';
},
init() {
this.$watch('password', (value) => {
this.rules.forEach(rule => {
rule.valid = rule.test(value);
});
});
}
}
}
</script>
<div class="flex flex-col justify-center gap-y-4">
<div>
<h2 class="h5">Mon profil</h2>
</div>
<form class="form form-edit-account"
action="#"
method="post"
id="form-validate"
enctype="multipart/form-data"
x-data="Object.assign(hyva.formValidation($el), initForm())"
@submit.prevent="submitForm()"
autocomplete="off"
novalidate=""
>
<fieldset class="fieldset info flex flex-col gap-y-4">
<input name="form_key" type="hidden" value="xxx">
<div class="relative flex flex-row items-center gap-x-3 field field-reserved">
<label for="prefix" class="flex items-center gap-x-1">
Civilité
<span class="required text-error">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M8.48605 7.23022L8.81938 7.03777L11.8608 5.28179C12.0734 5.15906 12.3452 5.23189 12.468 5.44446C12.5907 5.65704 12.5179 5.92886 12.3053 6.05159L9.26383 7.80757L8.9305 8.00002L9.26383 8.19247L12.3053 9.94845C12.5179 10.0712 12.5907 10.343 12.468 10.5556C12.3452 10.7681 12.0734 10.841 11.8608 10.7183L8.81938 8.96226L8.48605 8.76981V9.15471V12.6667C8.48605 12.9121 8.28706 13.1111 8.0416 13.1111C7.79614 13.1111 7.59716 12.9121 7.59716 12.6667V9.15472V8.76982L7.26382 8.96227L4.22237 10.7183L4.32568 10.8972L4.22237 10.7183C4.0098 10.841 3.73798 10.7681 3.61525 10.5556C3.49252 10.343 3.56536 10.0712 3.77793 9.94845L6.81938 8.19247L7.15272 8.00002L6.81938 7.80757L3.77794 6.05159L3.66964 6.23916L3.77794 6.05159C3.56536 5.92886 3.49253 5.65704 3.61526 5.44446C3.73799 5.23189 4.0098 5.15906 4.22238 5.28179L7.26382 7.03776L7.59716 7.23021V6.84531V3.33335C7.59716 3.08789 7.79614 2.88891 8.0416 2.88891C8.28706 2.88891 8.48605 3.08789 8.48605 3.33335V6.84532V7.23022Z"
fill="currentColor" stroke="currentColor" stroke-width="0.444444"
/>
</svg>
</span>
</label>
<div class="flex space-x-3">
{% include "@template-checkbox" with {
label: 'M.',
type: 'radio',
value: 'M.',
input_identifier: 'prefix1',
name: 'prefix',
labelLinked: false,
required: true,
checked: true,
} %}
{% include "@template-checkbox" with {
label: 'Mme.',
type: 'radio',
value: 'Mme.',
input_identifier: 'prefix2',
name: 'prefix',
labelLinked: false,
require: true,
} %}
</div>
</div>
<div class="flex flex-col gap-y-4 md:flex-row md:gutter-half">
<div class="field field-reserved w-full md:w-1/2">
{% include "@template-input" with {
id: 'firstname',
name: 'firstname',
type: 'text',
label: 'Prénom',
required: true,
label_floating: true,
value: 'Anakin',
} %}
</div>
<div class="field field-reserved w-full md:w-1/2">
{% include "@template-input" with {
id: 'lastname',
name: 'lastname',
type: 'text',
label: 'Nom',
required: true,
label_floating: true,
value: 'Skywalker',
} %}
</div>
</div>
<div class="grid md:grid-cols-2 md:gutter-half field field-reserved">
{% include "@template-input-datepicker" with {
id: 'dob',
name: 'dob',
label: 'Date de naissance',
required: true,
label_floating: true,
dateValue: '28/06/1974'
} %}
</div>
<div>
<span class="text-body-xs">
Champs obligatoires<span class="text-error">*</span>
</span>
</div>
<div class="flex">
{% include "@template-checkbox" with {
label: 'Modifier l\'adresse mail',
type: 'checkbox',
value: 1,
input_identifier: 'change-email',
name: 'change_email',
required: false,
checkbox_attribute: ("@change=\"handleCheckboxChange('email-fields')\"")|replace({'\"': '"'}),
} %}
</div>
<div class="flex">
{% include "@template-checkbox" with {
label: 'Modifier le mot de passe',
type: 'checkbox',
value: 1,
input_identifier: 'change-password',
name: 'change_password',
required: false,
checkbox_attribute: ("@change=\"handleCheckboxChange('password-fields')\"")|replace({'\"': '"'}),
} %}
</div>
<template x-if="showEmailField">
<div class="field field-reserved" id="email-fields">
{% include "@template-input" with {
id: 'email',
name: 'email',
type: 'email',
label: 'E-mail',
required: true,
label_floating: true,
value: 'test@gmail.com',
} %}
</div>
</template>
<template x-if="showEmailField || showPasswordFields">
<div class="field field-reserved password current required" id="password-fields">
{% include "@template-input-password" with {
id: 'current-password',
name: 'current_password',
type: 'password',
label: 'Current Password',
required: true,
label_floating: true,
} %}
</div>
</template>
<template x-if="showPasswordFields">
<div class="flex flex-col gap-y-4">
<div x-data="passwordValidator()"
x-init="init()"
class="flex flex-col gap-y-1 field field-reserved"
>
{% include "@template-input-password" with {
id: 'password',
name: 'password',
type: 'password',
label: 'New Password',
required: true,
label_floating: true,
input_attribute: "x-model='password'"
} %}
<div class="text-body-xs text-black/40 flex flex-col gap-y-1">
<span class="font-bold">
Votre mot de passe doit contenir au moins :
</span>
<div class="flex flex-wrap items-start gap-x-1">
<template x-for="(rule, index) in rules" :key="index">
<div class="flex items-start gap-x-1"
:class="rule.valid ? 'text-success' : 'text-black/40'"
>
{% render "@icons-heroicons--check-circle-outline" with {
width: 16,
height: 16,
} %}
<div class="input-password-counter-label" x-text="rule.label"></div>
</div>
</template>
</div>
<div id="password-strength-meter-container"
data-role="password-strength-meter"
aria-live="polite"
>
<div id="password-strength-meter" class="password-strength-meter">
Fiabilité du mot de passe :
<span id="password-strength-meter-label" data-role="password-strength-meter-label" x-text="strengthLabel">
</span>
</div>
</div>
</div>
</div>
<div class="field field-reserved">
{% include "@template-input-password" with {
id: 'password-confirmation',
name: 'password_confirmation',
type: 'password',
label: 'Confirm New Password',
required: true,
label_floating: true,
} %}
</div>
</div>
</template>
<div>
{% render "@account-action-bar" with {
wrapper_class: 'justify-end',
back_button: null,
primary_button: {
label: "Enregistrer",
buttonType: 'submit',
}
} %}
</div>
</fieldset>
</form>
<div class="text-body-xs text-black/64">
NAOS France (Etat Pur, Bioderma, Institut Esthederm) collecte les données personnelles ci-dessus afin de créer
votre compte Etat Pur, vous permettre de bénéficier des services associés et vous permettre de participer Ã
notre programme de fidélité. Pour en savoir plus sur l’utilisation de vos données et sur vos droits, cliquez-ici
</div>
</div>
<script>
// script from vendor/hyva-themes/magento2-default-theme/Magento_Customer/templates/form/edit.phtml
function initForm() {
return {
errors: 0,
hasCaptchaToken: 0,
displayErrorMessage: false,
errorMessages: [],
showEmailField: false,
showPasswordNew: false,
showPasswordConfirm: false,
showPasswordCurrent: false,
showPasswordFields: false,
setErrorMessages(messages) {
this.errorMessages = [messages]
this.displayErrorMessage = this.errorMessages.length
},
submitForm() {
this.validate()
.then(() => {
// Do not rename $form, the variable is expected to be declared in the recaptcha output
const $form = document.querySelector('#form-validate');
if (this.errors === 0) {
$form.submit();
}
})
.catch((invalid) => {
if (invalid.length > 0) {
invalid[0].focus();
}
})
},
handleCheckboxChange(checkboxId) {
if(checkboxId === 'email-fields') {
this.showEmailField = !this.showEmailField
}
if(checkboxId ==='password-fields') {
this.showPasswordFields = !this.showPasswordFields
}
this.$nextTick(() => {
const firstFocusableElement = document.querySelector(`
#${checkboxId} input,
#${checkboxId} textarea,
#${checkboxId} select
`)
firstFocusableElement && firstFocusableElement.focus()
})
}
}
}
</script>
<script>
function passwordValidator() {
return {
password: '',
rules: [
{ label: '12 caractères', test: pwd => pwd.length >= 12, valid: false },
{ label: '1 minuscule', test: pwd => /[a-z]/.test(pwd), valid: false },
{ label: '1 majuscule', test: pwd => /[A-Z]/.test(pwd), valid: false },
{ label: '1 chiffre', test: pwd => /[0-9]/.test(pwd), valid: false },
{ label: '1 caractère spécial', test: pwd => /[^a-zA-Z0-9]/.test(pwd), valid: false },
],
get strengthLabel() {
const validCount = this.rules.filter(r => r.valid).length;
if (!this.password) return 'Aucune';
if (validCount <= 2) return 'Faible';
if (validCount <= 4) return 'Moyen';
return 'Fort';
},
init() {
this.$watch('password', (value) => {
this.rules.forEach(rule => {
rule.valid = rule.test(value);
});
});
}
}
}
</script>
/* No context defined. */
No notes defined.