184 lines
6.3 KiB
Vue
184 lines
6.3 KiB
Vue
<template>
|
|
<div>
|
|
<div class="container sm:px-10">
|
|
<div class="block xl:grid grid-cols-2 gap-4">
|
|
<!-- BEGIN: Login Info -->
|
|
<LogoInfo />
|
|
<!-- END: Login Info -->
|
|
|
|
<!-- BEGIN: Login Form -->
|
|
<div class="h-screen xl:h-auto md:flex py-5 xl:py-0 my-10 xl:my-0">
|
|
<div class="md:hidden mb-6">
|
|
<a>
|
|
<Logo class="mx-auto mb-2" />
|
|
<div class="text-center text-white text-lg ml-3">
|
|
Türkmenistanyň Döwlet haryt-çig mal biržasy
|
|
</div>
|
|
</a>
|
|
</div>
|
|
|
|
<div
|
|
class="my-auto mx-auto xl:ml-20 bg-white dark:bg-darkmode-600 xl:bg-transparent px-5 sm:px-8 py-8 xl:p-0 rounded-md shadow-md xl:shadow-none w-full sm:w-3/4 lg:w-2/4 xl:w-auto">
|
|
<h2 class="intro-x font-bold text-2xl xl:text-3xl text-center xl:text-left">
|
|
{{ $t('UPDATE_PWD') }}
|
|
</h2>
|
|
|
|
<div class="intro-x mt-8">
|
|
<input type="text" v-model.trim="validate.email.$model"
|
|
class="intro-x login__input form-control py-3 px-4 block mt-4"
|
|
:class="{ 'border-danger': validate.email.$error }" :placeholder="$t('EMAIL')" />
|
|
<template v-if="validate.email.$error">
|
|
<div v-for="(error, index) in validate.email.$errors" :key="index" class="text-danger mt-2">
|
|
{{ error.$message }}
|
|
</div>
|
|
</template>
|
|
|
|
<input type="text" v-model.trim="validate.token.$model"
|
|
class="intro-x login__input form-control py-3 px-4 block mt-4"
|
|
:class="{ 'border-danger': validate.token.$error }" :placeholder="$t('TYPE_TOKEN')" />
|
|
<template v-if="validate.token.$error">
|
|
<div v-for="(error, index) in validate.token.$errors" :key="index" class="text-danger mt-2">
|
|
{{ error.$message }}
|
|
</div>
|
|
</template>
|
|
|
|
<input type="password" v-model.trim="validate.password.$model"
|
|
class="intro-x login__input form-control py-3 px-4 block mt-4"
|
|
:class="{ 'border-danger': validate.password.$error }" :placeholder="$t('PASSWORD')" />
|
|
<template v-if="validate.password.$error">
|
|
<div v-for="(error, index) in validate.password.$errors" :key="index" class="text-danger mt-2">
|
|
{{ error.$message }}
|
|
</div>
|
|
</template>
|
|
|
|
<input type="password" v-model.trim="validate.confirm_password.$model"
|
|
class="intro-x login__input form-control py-3 px-4 block mt-4"
|
|
:class="{ 'border-danger': validate.confirm_password.$error }" :placeholder="$t('NEW_PASSWORD')" />
|
|
<template v-if="validate.confirm_password.$error">
|
|
<div v-for="(error, index) in validate.confirm_password.$errors" :key="index" class="text-danger mt-2">
|
|
{{ error.$message }}
|
|
</div>
|
|
</template>
|
|
</div>
|
|
<div class="intro-x mt-5 xl:mt-8 text-center xl:text-left">
|
|
<button class="btn btn-primary py-3 px-4 xl:mr-3 align-top w-full custom-btns" @click.prevent="onUpdate">
|
|
{{ $t('UPDATE') }}
|
|
<LoadingIcon icon="oval" color="white" class="w-4 h-4 ml-2" v-if="isLoading" />
|
|
</button>
|
|
</div>
|
|
<div class="intro-x mt-5 xl:mt-8 text-primary xl:text-left">
|
|
<p class="w-full text-center">
|
|
<a
|
|
@click.prevent="onLogin"
|
|
href="#"
|
|
class="font-bold underline"
|
|
>
|
|
{{ $t('SIGN_IN') }}
|
|
</a>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- END: Login Form -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { onMounted, reactive, toRefs, ref, watch } from "vue";
|
|
import dom from "@left4code/tw-starter/dist/js/dom";
|
|
import { useVuelidate } from "@vuelidate/core";
|
|
import { required, minLength, email, helpers } from "@vuelidate/validators";
|
|
import { useAlertStore } from "@/stores";
|
|
import i18nn from "@/i18n";
|
|
import router from "@/router";
|
|
import Logo from "@/components/logo/Main.vue";
|
|
import LogoInfo from "@/components/logo-info/Main.vue";
|
|
import { fetchWrapper } from "@/api";
|
|
|
|
const baseUrl = `${import.meta.env.VITE_API_URL}/api`;
|
|
|
|
const formData = reactive({
|
|
email: "",
|
|
token: "",
|
|
password: "",
|
|
confirm_password: "",
|
|
});
|
|
|
|
const isLoading = ref(false);
|
|
|
|
const rules = {
|
|
email: {
|
|
required: helpers.withMessage(i18nn.global.t("REQUIRED_VALIDATION"), required),
|
|
email: helpers.withMessage(i18nn.global.t("EMAIL_VALIDATION"), email),
|
|
},
|
|
|
|
password: {
|
|
required: helpers.withMessage(i18nn.global.t("REQUIRED_VALIDATION"), required),
|
|
minLength: helpers.withMessage(
|
|
i18nn.global.t("MIN_LENGTH_VALIDATION", { min: 8 }), minLength(8)
|
|
)
|
|
},
|
|
confirm_password: {
|
|
required: helpers.withMessage(i18nn.global.t("REQUIRED_VALIDATION"), required),
|
|
minLength: helpers.withMessage(
|
|
i18nn.global.t("MIN_LENGTH_VALIDATION", { min: 8 }), minLength(8)
|
|
)
|
|
},
|
|
token: {
|
|
required: helpers.withMessage(i18nn.global.t("REQUIRED_VALIDATION"), required),
|
|
minLength: helpers.withMessage(
|
|
i18nn.global.t("MIN_LENGTH_VALIDATION", { min: 4 }), minLength(4)
|
|
)
|
|
},
|
|
};
|
|
|
|
const validate = useVuelidate(rules, toRefs(formData));
|
|
|
|
const onLogin = () => router.push({ path: "/" });
|
|
|
|
const onUpdate = async () => {
|
|
validate.value.$touch();
|
|
|
|
// check form validation
|
|
if (validate.value.$invalid) return;
|
|
|
|
try {
|
|
const alertStore = useAlertStore();
|
|
|
|
isLoading.value = true;
|
|
|
|
const response = await fetchWrapper.post(`${baseUrl}/reset-password`, {
|
|
formData,
|
|
});
|
|
|
|
//console.log("update password", response);
|
|
|
|
isLoading.value = false;
|
|
|
|
alertStore.success(response.message);
|
|
|
|
// redirect to home page
|
|
router.push({ path: "/" });
|
|
} catch (error) {
|
|
isLoading.value = false;
|
|
}
|
|
};
|
|
|
|
onMounted(() => {
|
|
dom("body").removeClass("main").removeClass("error-page").addClass("login");
|
|
});
|
|
</script>
|
|
|
|
<style scoped>
|
|
.custom-btns {
|
|
min-width: 128px;
|
|
}
|
|
.form-check-input[type="radio"],
|
|
.login .login__input,
|
|
.form-select {
|
|
border-color: rgb(var(--color-slate-400) / var(--tw-border-opacity));;
|
|
}
|
|
</style>
|