267 lines
7.2 KiB
Vue
267 lines
7.2 KiB
Vue
<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/lib/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>
|