Files
antigol-service/frontend/pages/reset-password.vue
talorr cda36918e8 init
2026-03-27 03:36:08 +03:00

131 lines
4.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
const route = useRoute();
const router = useRouter();
const token = computed(() => (typeof route.query.token === "string" ? route.query.token : ""));
const password = ref("");
const confirmPassword = ref("");
const showPassword = ref(false);
const showConfirmPassword = ref(false);
const error = ref("");
const success = ref("");
const pending = ref(false);
const handleSubmit = async () => {
error.value = "";
success.value = "";
if (!token.value) {
error.value = "Ссылка восстановления некорректна";
return;
}
pending.value = true;
try {
const result = await useApi<{ message: string }>("/auth/reset-password", {
method: "POST",
body: {
token: token.value,
password: password.value,
confirmPassword: confirmPassword.value
}
});
success.value = result.message;
password.value = "";
confirmPassword.value = "";
setTimeout(() => {
router.push("/login");
}, 1500);
} catch (submitError) {
error.value = submitError instanceof Error ? submitError.message : "Не удалось обновить пароль";
} finally {
pending.value = false;
}
};
</script>
<template>
<section class="mx-auto grid min-h-[calc(100vh-12rem)] w-full items-center gap-8 md:max-w-6xl md:grid-cols-[minmax(0,1.1fr)_minmax(22rem,28rem)] md:[min-height:calc(100vh-10rem)]">
<div class="grid max-w-lg gap-3">
<p class="m-0 text-xs font-semibold uppercase tracking-[0.18em] text-(--muted)">Alpinbet</p>
<h1 class="m-0 text-4xl font-semibold leading-tight">Новый пароль</h1>
<p class="m-0 text-base leading-7 text-(--muted)">
Установите новый пароль для аккаунта. После сохранения можно будет сразу войти в систему.
</p>
</div>
<form
class="grid w-full max-w-md gap-4 rounded-[28px] border p-4"
:style="{ borderColor: 'var(--border)', backgroundColor: 'var(--surface-strong)' }"
@submit.prevent="handleSubmit"
>
<p class="m-0 text-xs font-semibold uppercase tracking-[0.18em] text-(--muted)">Смена пароля</p>
<label class="grid gap-1">
<span>Новый пароль</span>
<div class="password-field">
<input
v-model="password"
:type="showPassword ? 'text' : 'password'"
autocomplete="new-password"
/>
<button
type="button"
class="password-field__toggle"
:aria-label="showPassword ? 'Скрыть пароль' : 'Показать пароль'"
@click="showPassword = !showPassword"
>
<i class="pi" :class="showPassword ? 'pi-eye-slash' : 'pi-eye'" aria-hidden="true" />
</button>
</div>
</label>
<label class="grid gap-1">
<span>Повторите пароль</span>
<div class="password-field">
<input
v-model="confirmPassword"
:type="showConfirmPassword ? 'text' : 'password'"
autocomplete="new-password"
/>
<button
type="button"
class="password-field__toggle"
:aria-label="showConfirmPassword ? 'Скрыть пароль' : 'Показать пароль'"
@click="showConfirmPassword = !showConfirmPassword"
>
<i class="pi" :class="showConfirmPassword ? 'pi-eye-slash' : 'pi-eye'" aria-hidden="true" />
</button>
</div>
</label>
<p
v-if="error"
class="rounded-2xl p-4 text-sm whitespace-pre-line"
:style="{ backgroundColor: 'var(--danger-bg)', color: 'var(--danger-text)' }"
>
{{ error }}
</p>
<p
v-if="success"
class="rounded-2xl p-4 text-sm"
:style="{ backgroundColor: 'var(--success-bg)', color: 'var(--success-text)' }"
>
{{ success }}
</p>
<button type="submit" :disabled="pending || !token">
{{ pending ? "Сохраняем..." : "Сохранить пароль" }}
</button>
<p class="m-0 text-(--muted)">
Нужна новая ссылка?
<NuxtLink class="text-(--accent-strong)" to="/forgot-password">Запросить повторно</NuxtLink>
</p>
</form>
</section>
</template>