add preloader after send query, add some errors messages
Gitea Actions Demo / build_and_push (push) Successful in 1m8s Details

This commit is contained in:
artem 2025-02-01 09:31:22 +03:00
parent 81a3b3db88
commit 7c12da31af
4 changed files with 108 additions and 17 deletions

View File

@ -4,11 +4,15 @@
<p class="text-base mb-4 leading-5"> <p class="text-base mb-4 leading-5">
Вам был выслан код, введите его и вы авторизуетесь, для смены пароля вам необходимо зайти в настройки профиля. Вам был выслан код, введите его и вы авторизуетесь, для смены пароля вам необходимо зайти в настройки профиля.
</p> </p>
<VaInput v-model="email" :rules="[(v) => !!v || 'Email обязательное поле']" class="mb-4" label="Введите ваш email" <VaInput v-model="email" :rules="[(v: string) => !!v || 'Email обязательное поле']" class="mb-4" label="Введите ваш email"
type="email" /> type="email" />
<VaInput v-model="code" :rules="[(v) => !!v || 'Код обязательное поле']" class="mb-4" label="Введите код из письма" <VaInput v-model="code" :rules="[(v: string) => !!v || 'Код обязательное поле']" class="mb-4" label="Введите код из письма"
type="text" /> type="text" />
<VaButton class="w-full mb-2" @click="submit">Авторизоваться</VaButton> <VaButton class="w-full mb-2" @click="submit">
<span v-if="!inProgress">Авторизоваться</span>
<va-progress-circle v-else
indeterminate
size="small" color="#a1a1a1"></va-progress-circle></VaButton>
</VaForm> </VaForm>
</template> </template>
@ -29,12 +33,17 @@ const { init } = useToast();
const submit = () => { const submit = () => {
if (form.validate()) { if (form.validate()) {
if (inProgress.value) {
return;
}
inProgress.value = true;
axiosAuth axiosAuth
.post(`/api/v0/profiles/passwords/confirm/recover`, { .post(`/api/v0/profiles/passwords/confirm/recover`, {
email: email.value, email: email.value,
code: code.value, code: code.value,
}) })
.then((response: AxiosResponse) => { .then((response: AxiosResponse) => {
resetProgress();
localStorage.setItem('token', response.data.token); localStorage.setItem('token', response.data.token);
localStorage.setItem('profile', JSON.stringify(response.data.profile)); localStorage.setItem('profile', JSON.stringify(response.data.profile));
@ -43,6 +52,7 @@ const submit = () => {
router.push({ name: "dashboard" }).catch((error) => { }); router.push({ name: "dashboard" }).catch((error) => { });
}).catch((error: any) => { }).catch((error: any) => {
resetProgress();
if (error.response.data.detail.code_string == "ObjectNotFound") { if (error.response.data.detail.code_string == "ObjectNotFound") {
init({ init({
message: "Неверный код", message: "Неверный код",
@ -53,5 +63,9 @@ const submit = () => {
} }
}; };
let inProgress = ref<boolean>();
const resetProgress = () => {
inProgress.value = false;
};
</script> </script>

View File

@ -13,12 +13,14 @@
class="mb-4" class="mb-4"
label="Email" label="Email"
type="email" type="email"
@change="resetProgress"
/> />
<VaValue v-slot="isPasswordVisible" :default-value="false"> <VaValue v-slot="isPasswordVisible" :default-value="false">
<VaInput <VaInput
v-model="formData.password" v-model="formData.password"
:rules="[validators.required]" :rules="[validators.required]"
:type="isPasswordVisible.value ? 'text' : 'password'" :type="isPasswordVisible.value ? 'text' : 'password'"
@change="resetProgress"
class="mb-4" class="mb-4"
label="Пароль" label="Пароль"
@clickAppendInner.stop=" @clickAppendInner.stop="
@ -49,13 +51,20 @@
</div> </div>
<div class="flex justify-center mt-4"> <div class="flex justify-center mt-4">
<VaButton class="w-full" @click="submit"> Вход</VaButton> <VaButton class="w-full" @click="submit">
<span v-if="!inProgress">Вход</span>
<va-progress-circle v-else
indeterminate
size="small" color="#a1a1a1"></va-progress-circle>
</VaButton>
</div> </div>
</VaForm> </VaForm>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { inject } from 'vue' import { inject, ref } from 'vue'
import axios from "axios"; import axios from "axios";
import { reactive } from "vue"; import { reactive } from "vue";
@ -72,20 +81,29 @@ const formData = reactive({
password: "", password: "",
keepLoggedIn: false, keepLoggedIn: false,
}); });
const token = localStorage.getItem("token"); const token = localStorage.getItem("token");
if (token != undefined && token.length > 0) { if (token != undefined && token.length > 0) {
push({ name: "dashboard" }).catch((error) => {}); push({ name: "dashboard" }).catch((error) => {});
} }
let inProgress = ref<boolean>();
const resetProgress = () => {
inProgress.value = false;
};
const submit = () => { const submit = () => {
if (validate()) { if (validate()) {
if (inProgress.value) {
return;
}
inProgress.value = true;
axios axios
.post(`/api/v0/signin`, { .post(`/api/v0/signin`, {
login: formData.email, login: formData.email,
password: formData.password, password: formData.password,
}) })
.then((response) => { .then((response) => {
resetProgress();
localStorage.setItem('token', response.data.token); localStorage.setItem('token', response.data.token);
localStorage.setItem('profile', JSON.stringify(response.data.profile)); localStorage.setItem('profile', JSON.stringify(response.data.profile));
localStorage.setItem('user', JSON.stringify(response.data.user)); localStorage.setItem('user', JSON.stringify(response.data.user));
@ -95,7 +113,7 @@ const submit = () => {
push({ name: "dashboard" }); push({ name: "dashboard" });
}) })
.catch((error) => { .catch((error) => {
resetProgress();
init({ init({
message: "Неверный логин или пароль", message: "Неверный логин или пароль",
color: "error", color: "error",

View File

@ -8,12 +8,16 @@
</p> </p>
<VaInput <VaInput
v-model="email" v-model="email"
:rules="[(v) => !!v || 'Email обязательное поле']" :rules="[(v: string) => !!v || 'Email обязательное поле']"
class="mb-4" class="mb-4"
label="Введите ваш email" label="Введите ваш email"
type="email" type="email"
/> />
<VaButton class="w-full mb-2" @click="submit">Отправить пароль</VaButton> <VaButton class="w-full mb-2" @click="submit">
<span v-if="!inProgress">Отправить пароль</span>
<va-progress-circle v-else
indeterminate
size="small" color="#a1a1a1"></va-progress-circle></VaButton>
<VaButton <VaButton
:to="{ name: 'login' }" :to="{ name: 'login' }"
class="w-full" class="w-full"
@ -26,23 +30,55 @@
<script lang="ts" setup> <script lang="ts" setup>
import axios from "axios"; import axios from "axios";
import {AxiosError, AxiosResponse} from "axios";
import { ref } from "vue"; import { ref } from "vue";
import { useForm } from "vuestic-ui"; import { useForm, useToast } from "vuestic-ui";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
const email = ref(""); const email = ref("");
const form = useForm("passwordForm"); const form = useForm("passwordForm");
const router = useRouter(); const router = useRouter();
const { init } = useToast();
const submit = () => { const submit = () => {
if (form.validate()) { if (form.validate()) {
if (inProgress.value) {
return;
}
inProgress.value = true;
axios axios
.post(`/api/v0/profiles/passwords/require/recover`, { .post(`/api/v0/profiles/passwords/require/recover`, {
email: email.value, email: email.value,
}) })
.then((response) => { .then((_response: AxiosResponse) => {
resetProgress();
init({
message: "Успешно",
color: "success",
});
router.push({ name: "recover-password-email", query: { email: email.value } }); router.push({ name: "recover-password-email", query: { email: email.value } });
})
.catch((error: AxiosError) => {
resetProgress();
if (error.status == 400) {
init({
message: "Неверный email",
color: "error",
});
return
}
init({
message: "Что-то пошло не так",
color: "error",
});
}); });
} }
}; };
let inProgress = ref<boolean>();
const resetProgress = () => {
inProgress.value = false;
};
</script> </script>

View File

@ -10,8 +10,8 @@
<VaInput <VaInput
v-model="formData.email" v-model="formData.email"
:rules="[ :rules="[
(v) => !!v || 'Email обязателен', (v: string) => !!v || 'Email обязателен',
(v) => /.+@.+\..+/.test(v) || 'Email должен быть валидным', (v: string) => /.+@.+\..+/.test(v) || 'Email должен быть валидным',
]" ]"
class="mb-4" class="mb-4"
label="Email" label="Email"
@ -44,8 +44,8 @@
ref="password2" ref="password2"
v-model="formData.repeatPassword" v-model="formData.repeatPassword"
:rules="[ :rules="[
(v) => !!v || 'Поле повторите пароль обязательное', (v: string) => !!v || 'Поле повторите пароль обязательное',
(v) => v === formData.password || 'Пароли не совпадают', (v: string) => v === formData.password || 'Пароли не совпадают',
]" ]"
:type="isPasswordVisible.value ? 'text' : 'password'" :type="isPasswordVisible.value ? 'text' : 'password'"
class="mb-4" class="mb-4"
@ -67,14 +67,18 @@
</VaValue> </VaValue>
<div class="flex justify-center mt-4"> <div class="flex justify-center mt-4">
<VaButton class="w-full" @click="submit"> Создать аккуант</VaButton> <VaButton class="w-full" @click="submit">
<span v-if="!inProgress">Создать аккаунт</span>
<va-progress-circle v-else
indeterminate
size="small" color="#a1a1a1"></va-progress-circle></VaButton>
</div> </div>
</VaForm> </VaForm>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import axios from "axios"; import axios from "axios";
import { reactive } from "vue"; import { reactive, ref } from "vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { useForm, useToast } from "vuestic-ui"; import { useForm, useToast } from "vuestic-ui";
@ -95,12 +99,17 @@ if (token != undefined && token.length > 0) {
const submit = () => { const submit = () => {
if (validate()) { if (validate()) {
if (inProgress.value) {
return;
}
inProgress.value = true;
axios axios
.post(`/api/v0/signup`, { .post(`/api/v0/signup`, {
email: formData.email, email: formData.email,
password: formData.password, password: formData.password,
}) })
.then((response) => { .then((response) => {
resetProgress();
localStorage.setItem('token', response.data.token); localStorage.setItem('token', response.data.token);
localStorage.setItem('profile', JSON.stringify(response.data.profile)); localStorage.setItem('profile', JSON.stringify(response.data.profile));
localStorage.setItem('user', JSON.stringify(response.data.user)); localStorage.setItem('user', JSON.stringify(response.data.user));
@ -110,6 +119,14 @@ const submit = () => {
color: "success", color: "success",
}); });
push({ name: "dashboard" }).catch((error) => {}); push({ name: "dashboard" }).catch((error) => {});
})
.catch((error) => {
resetProgress();
init({
message: "Что-то пошло не так",
color: "error",
});
}); });
} }
}; };
@ -118,4 +135,10 @@ const passwordRules: ((v: string) => boolean | string)[] = [
(v) => !!v || "Поле пароль обязательное", (v) => !!v || "Поле пароль обязательное",
(v) => (v && v.length >= 5) || "Пароль должен быть длинее 5-ти символов", (v) => (v && v.length >= 5) || "Пароль должен быть длинее 5-ти символов",
]; ];
let inProgress = ref<boolean>();
const resetProgress = () => {
inProgress.value = false;
};
</script> </script>