<template> <div class="sign-up"> <div class="sign-up__text-number">{{ usernameemail }}</div> <div class="sign-up__text">کد ایمیل شده را وارد کنید</div> <div class="sign-up__form"> <div class="sign-up__form-row sign-up__simple-input"> <div class="form-group position-relative" :class="{ 'form-group--error': $v.code.$error }" > <input class="form-control elem__placeholder-gray" v-model.trim="$v.code.$model" type="text" placeholder="کد ارسالی" name="" id="" dir="ltr" /> </div> <div v-if="submitStatus === 'ERROR'"> <div class="error" v-if="!$v.code.required"> {{ $t("IsRequired") }} </div> </div> </div> <div class="sign-up__form-row sign-up__simple-input"> <div class="form-group position-relative" :class="{ 'form-group--error': $v.password.$error }" > <input class="form-control elem__placeholder-gray" :type="passwordFieldType" name="" id="" v-model.trim="$v.password.$model" placeholder="رمز عبور" dir="ltr" @focus="isFocusedOnPassword = true" @blur="isFocusedOnPassword = false" /> <button type="button" @click="togglePasswordVisibility" class="toggle-password-btn" > <svg v-if="isPasswordVisible" class="icon icon-eye"> <use xlink:href="#icon-eye"></use> </svg> <svg v-else class="icon icon-Eye-Slash"> <use xlink:href="#icon-Eye-Slash"></use> </svg> </button> </div> <transition name="fade"> <div v-if="isFocusedOnPassword" class="password-requirements"> <ul> <li :class="{ 'text-success': !$v.password.$pending && $v.password.minLength, 'text-danger': !$v.password.minLength, }" > طول آن حداقل باید 8 کاراکتر باشد </li> <li :class="{ 'text-success': !$v.password.$pending && $v.password.hasLowerCase, 'text-danger': !$v.password.hasLowerCase, }" > حداقل شامل یک حرف کوچک باشد </li> <li :class="{ 'text-success': !$v.password.$pending && $v.password.hasUpperCase, 'text-danger': !$v.password.hasUpperCase, }" > حداقل شامل یک حرف بزرگ باشد </li> <li :class="{ 'text-success': !$v.password.$pending && $v.password.hasSpecialChar, 'text-danger': !$v.password.hasSpecialChar, }" > حداقل شامل یک کاراکتر خاص باشد </li> </ul> </div> </transition> <div v-if="submitStatus === 'ERROR'"> <div class="error" v-if="!$v.password.required"> {{ $t("IsRequired") }} </div> <div class="error" v-if="!$v.password.minLength"> Password must have at least {{ $v.password.$params.minLength.min }} letters. </div> </div> </div> <div class="sign-up__form-row sign-up__simple-input"> <div class="form-group position-relative" :class="{ 'form-group--error': $v.repassword.$error }" > <input class="form-control elem__placeholder-gray" type="password" name="" id="" v-model.trim="$v.repassword.$model" placeholder="تکرار رمز عبور" dir="ltr" /> </div> <div v-if="submitStatus === 'ERROR'"> <div class="error" v-if="!$v.repassword.required"> {{ $t("IsRequired") }} </div> <div class="error" v-if="!$v.repassword.sameAsPassword"> رمزهای عبور باید یکسان باشند. </div> </div> </div> <div class="sign-up__button-container"> <RouterLink :to="{ path: '/login' }">بازگشت</RouterLink> <button v-on:click="authBase('doActivate')">ثبت کد</button> </div> </div> </div> </template> <script> import authMixin from "~/mixins/authMixin"; import { required, minLength, maxLength, between, sameAs, } from "@vuelidate/validators"; export default { validations: { password: { required, minLength: minLength(6), }, repassword: { required, sameAsPassword: sameAs("password"), minLength: minLength(8), hasLowerCase: (value) => /[a-z]/.test(value), hasUpperCase: (value) => /[A-Z]/.test(value), hasSpecialChar: (value) => /[!@#$%^&*(),.?":{}|<>]/.test(value), }, code: { required, }, }, props: ["usernameemail"], mixins: [authMixin], data() { return { code: "", password: "", repassword: "", isFocusedOnPassword: false, isPasswordVisible: true, }; }, computed: { passwordFieldType() { return this.isPasswordVisible ? "text" : "password"; }, }, methods: { doActivate() { var vm = this; this.$v.$touch(); if (this.$v.$invalid) { this.submitStatus = "ERROR"; } else { if (this.loading) return false; this.loading = true; this.resetPassword({ username: this.usernameemail, activationcode: this.code, newpass: this.password, }) .then((res) => { mySwalToast({ title: res.message, icon: "success", }); this.submitStatus = "OK"; this.$router.push({ name: "login", }); }) .catch((err) => { mySwalToast({ title: err.message, icon: "error", }); }) .finally(() => { this.loading = false; }); } }, togglePasswordVisibility() { this.isPasswordVisible = !this.isPasswordVisible; }, }, }; </script> <style> .toggle-password-btn { position: absolute; left: 0; min-width: 26px !important; height: 48px !important; border: 0 !important; top: 50%; transform: translateY(-50%); background: none; border: none; cursor: pointer; font-size: 16px; } .password-requirements { /* position: absolute; top: 100%; left: 0; */ background-color: #f9f9f9; padding: 10px; border-radius: 5px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); z-index: 10; } .password-requirements ul { list-style-type: disc; padding-left: 20px; margin: 0; } .password-requirements li { margin-bottom: 5px; font-size: 14px; color: #333; } </style>