Skip to content

Commit

Permalink
refactor(ui): refactor registerView
Browse files Browse the repository at this point in the history
  • Loading branch information
ShiinaKin committed Dec 7, 2024
1 parent 36192f3 commit 36a4875
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 97 deletions.
37 changes: 26 additions & 11 deletions ui/src/locales/zh_cn.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,33 @@ loginView:
max: "密码长度必须小于等于32个字符"
invalid: "密码只能为大小写字母、数字和 {'@'}$!%*#?& 的组合"
toast:
loginFailedTitle: "登录失败"
loginSuccessTitle: "登录成功"
successTitle: "登录成功"
failedTitle: "登录失败"
registerView:
registerTitle: "注册"
registerUsernamePlaceholder: "请输入用户名"
registerUsernameRequirements: "用户名必须是4-20个字符,只能包含字母和数字。"
registerPasswordPlaceholder: "请输入密码"
registerPasswordRequirements: "密码长度必须在8到32个字符之间。只能为大小写字母、数字和特殊符号的组合,必须有字母和数字。"
registerEmailPlaceholder: "请输入邮箱"
registerEmailRequirements: "请输入正确的邮箱地址。"
registerSubmitButton: "注册"
registerLoginButton: "登录"
title: "注册"
form:
username: "用户名"
password: "密码"
email: "邮箱"
signupButton: "注册"
loginButton: "登录"
verify:
username:
required: "用户名不能为空"
min: "用户名必须大于等于4个字符"
max: "用户名必须小于等于20个字符"
invalid: "用户名只能包含字母和数字"
password:
required: "密码不能为空"
min: "密码长度必须大于等于8个字符"
max: "密码长度必须小于等于32个字符"
invalid: "密码只能为大小写字母、数字和 {'@'}$!%*#?& 的组合"
email:
required: "邮箱不能为空"
invalid: "邮箱格式不正确"
toast:
successTitle: "注册成功"
failedTitle: "注册失败"
userField:
menu:
overview: "概览"
Expand Down
171 changes: 85 additions & 86 deletions ui/src/views/auth/RegisterView.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
<script setup lang="ts">
import { ref } from "vue";
import { useRouter } from "vue-router";
import { useI18n } from "vue-i18n";
import { useToast } from "primevue/usetoast";
import { useCommonStore } from "@/stores/counter";
import { useForm } from "vee-validate";
import * as yup from "yup";
import { AuthApi, type UserInsertRequest } from "api-client";
import { Icon } from "@iconify/vue";
import { useToast } from "primevue/usetoast";
import VeeInputText from "@/components/vee-input/VeeInputText.vue";
import Button from "primevue/button";
const { t } = useI18n();
const commonStore = useCommonStore();
Expand All @@ -14,22 +16,53 @@ const toast = useToast();
const authApi = new AuthApi();
const userRegisterForm = ref<UserInsertRequest>({
username: "",
password: "",
email: ""
const signupFormSchema = yup.object({
username: yup
.string()
.trim()
.min(4, t("registerView.form.verify.username.min"))
.max(20, t("registerView.form.verify.username.min"))
.required(t("registerView.form.verify.username.required")),
password: yup
.string()
.trim()
.min(8, t("registerView.form.verify.password.min"))
.max(32, t("registerView.form.verify.password.min"))
.matches(
/^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,32}$/,
t("registerView.form.verify.password.invalid")
)
.required(t("registerView.form.verify.password.required")),
email: yup
.string()
.trim()
.email(t("registerView.form.verify.email.invalid"))
.required(t("registerView.form.verify.email.required"))
});
const { handleSubmit } = useForm({
validationSchema: signupFormSchema
});
const onSubmit = handleSubmit((values) => {
const signupRequest: UserInsertRequest = {
username: values.username,
password: values.password,
email: values.email
};
signup(signupRequest);
});
function handleSubmit() {
const userRegisterRequest = userRegisterForm.value;
function signup(signupRequest: UserInsertRequest) {
authApi
.apiUserSignupPost({ userInsertRequest: userRegisterRequest })
.apiUserSignupPost({ userInsertRequest: signupRequest })
.then((response) => {
const resp = response.data;
if (resp.isSuccessful) {
toast.add({ severity: "success", summary: t("registerView.toast.successTitle"), life: 3000 });
router.push({ name: "login" });
} else {
toast.add({ severity: "warn", summary: "Register Failed", detail: resp.message, life: 3000 });
toast.add({ severity: "warn", summary: t("registerView.toast.failedTitle"), detail: resp.message, life: 3000 });
}
})
.catch((error) => {
Expand All @@ -40,90 +73,56 @@ function handleSubmit() {
</script>

<template>
<div class="h-screen w-full flex justify-center items-center">
<div class="mx-auto min-w-96">
<h1 class="text-center text-2xl font-bold text-indigo-600 sm:text-3xl">{{ commonStore.title }}</h1>

<form
@submit.prevent="handleSubmit"
class="mb-0 mt-6 space-y-4 rounded-lg p-4 shadow-lg sm:p-6 lg:p-8"
<div class="h-screen w-full flex justify-center items-center bg-gray-300">
<div class="relative w-1/2 rounded-xl shadow-lg overflow-hidden">
<img src="@/assets/authBackground.png" alt="authBackground" class="w-full object-cover" />
<div
class="absolute top-0 right-0 w-1/2 h-full bg-white bg-opacity-75 backdrop-blur-sm flex flex-col items-center justify-center gap-4"
>
<p class="text-center text-lg font-medium">{{ t("registerView.registerTitle") }}</p>

<div>
<label for="username" class="sr-only">Username</label>

<div class="relative">
<input
id="username"
type="text"
autocomplete="username"
class="w-full rounded-lg border-gray-200 p-4 pe-12 text-sm shadow-sm"
:placeholder="t('registerView.registerUsernamePlaceholder')"
v-model="userRegisterForm.username"
pattern="^[a-zA-Z0-9]{4,20}$"
:title="t('registerView.registerUsernameRequirements')"
required
<h2 class="text-3xl text-gray-700">{{ commonStore.title }}</h2>

<h4 class="text-xl text-gray-700">{{ t("registerView.title") }}</h4>
<form @submit="onSubmit" class="flex flex-col gap-4 w-96">
<div class="flex flex-col gap-1">
<VeeInputText
id="signupFormUsername"
name="username"
:label="t('registerView.form.username')"
start-icon="mdi:user"
/>

<span class="absolute inset-y-0 end-0 grid place-content-center px-4">
<Icon icon="mdi:user" class="text-gray-400" />
</span>
</div>
</div>

<div>
<label for="password" class="sr-only">Password</label>

<div class="relative">
<input
id="password"
<div class="flex flex-col gap-1">
<VeeInputText
id="signupFormPassword"
name="password"
:label="t('registerView.form.password')"
type="password"
autocomplete="new-password"
class="w-full rounded-lg border-gray-200 p-4 pe-12 text-sm shadow-sm"
:placeholder="t('registerView.registerPasswordPlaceholder')"
v-model="userRegisterForm.password"
pattern="^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,32}$"
:title="t('registerView.registerPasswordRequirements')"
required
start-icon="mdi:password-outline"
/>

<span class="absolute inset-y-0 end-0 grid place-content-center px-4">
<Icon icon="mdi:password-outline" class="text-gray-400" />
</span>
</div>
</div>

<div>
<label for="email" class="sr-only">Email</label>

<div class="relative">
<input
id="email"
<div class="flex flex-col gap-1">
<VeeInputText
id="signupFormEmail"
name="email"
:label="t('siteInitView.form.email')"
type="email"
class="w-full rounded-lg border-gray-200 p-4 pe-12 text-sm shadow-sm"
:placeholder="t('registerView.registerEmailPlaceholder')"
v-model="userRegisterForm.email"
:title="t('registerView.registerEmailRequirements')"
required
start-icon="mdi:alternate-email"
/>

<span class="absolute inset-y-0 end-0 grid place-content-center px-4">
<Icon icon="mdi:alternate-email" class="text-gray-400" />
</span>
</div>
</div>

<button type="submit" class="block w-full rounded-lg bg-indigo-600 px-5 py-3 text-sm font-medium text-white">
{{ t("registerView.registerSubmitButton") }}
</button>

<p class="text-center text-sm text-gray-500">
<a class="underline" href="#" @click="router.push({ name: 'login' })">{{
t("registerView.registerLoginButton")
}}</a>
</p>
</form>
<div class="flex flex-col gap-2">
<Button type="submit" :label="t('registerView.form.signupButton')" fluid />
<div class="flex justify-center">
<a
v-if="commonStore.allowSignup"
class="text-gray-500 hover:underline hover:text-gray-700 hover:cursor-pointer"
@click="router.push({ name: 'login' })"
>
{{ t("loginView.form.loginButton") }}
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</template>
Expand Down

0 comments on commit 36a4875

Please sign in to comment.