浏览代码

refactor(Register): Converted to composition API

Owen Diffey 2 年之前
父节点
当前提交
bdd1cb9c41
共有 1 个文件被更改,包括 190 次插入200 次删除
  1. 190 200
      frontend/src/components/modals/Register.vue

+ 190 - 200
frontend/src/components/modals/Register.vue

@@ -1,10 +1,193 @@
+<script setup lang="ts">
+import { useStore } from "vuex";
+import { defineAsyncComponent, ref, watch, onMounted } from "vue";
+import { useRoute } from "vue-router";
+import Toast from "toasters";
+import validation from "@/validation";
+
+const InputHelpBox = defineAsyncComponent(
+	() => import("@/components/InputHelpBox.vue")
+);
+
+const route = useRoute();
+
+const username = ref({
+	value: "",
+	valid: false,
+	entered: false,
+	message: "Only letters, numbers and underscores are allowed."
+});
+const email = ref({
+	value: "",
+	valid: false,
+	entered: false,
+	message: "Please enter a valid email address."
+});
+const password = ref({
+	value: "",
+	valid: false,
+	entered: false,
+	visible: false,
+	message:
+		"Include at least one lowercase letter, one uppercase letter, one number and one special character."
+});
+const recaptcha = ref({
+	key: "",
+	token: "",
+	enabled: false
+});
+const apiDomain = ref("");
+const registrationDisabled = ref(false);
+const passwordElement = ref();
+
+const store = useStore();
+
+const register = payload => store.dispatch("user/auth/register", payload);
+const openModal = payload =>
+	store.dispatch("modalVisibility/openModal", payload);
+const closeCurrentModal = () =>
+	store.dispatch("modalVisibility/closeCurrentModal");
+
+const submitModal = () => {
+	if (!username.value.valid || !email.value.valid || !password.value.valid)
+		return new Toast("Please ensure all fields are valid.");
+
+	return register({
+		username: username.value.value,
+		email: email.value.value,
+		password: password.value.value,
+		recaptchaToken: recaptcha.value.token
+	})
+		.then(res => {
+			if (res.status === "success") window.location.reload();
+		})
+		.catch(err => new Toast(err.message));
+};
+
+const togglePasswordVisibility = () => {
+	if (passwordElement.value.type === "password") {
+		passwordElement.value.type = "text";
+		password.value.visible = true;
+	} else {
+		passwordElement.value.type = "password";
+		password.value.visible = false;
+	}
+};
+
+const changeToLoginModal = () => {
+	closeCurrentModal();
+	openModal("login");
+};
+
+const githubRedirect = () => {
+	localStorage.setItem("github_redirect", route.path);
+};
+
+watch(
+	() => username.value.value,
+	value => {
+		username.value.entered = true;
+		if (!validation.isLength(value, 2, 32)) {
+			username.value.message =
+				"Username must have between 2 and 32 characters.";
+			username.value.valid = false;
+		} else if (!validation.regex.azAZ09_.test(value)) {
+			username.value.message =
+				"Invalid format. Allowed characters: a-z, A-Z, 0-9 and _.";
+			username.value.valid = false;
+		} else if (value.replaceAll(/[_]/g, "").length === 0) {
+			username.value.message =
+				"Invalid format. Allowed characters: a-z, A-Z, 0-9 and _, and there has to be at least one letter or number.";
+			username.value.valid = false;
+		} else {
+			username.value.message = "Everything looks great!";
+			username.value.valid = true;
+		}
+	}
+);
+watch(
+	() => email.value.value,
+	value => {
+		email.value.entered = true;
+		if (!validation.isLength(value, 3, 254)) {
+			email.value.message =
+				"Email must have between 3 and 254 characters.";
+			email.value.valid = false;
+		} else if (
+			value.indexOf("@") !== value.lastIndexOf("@") ||
+			!validation.regex.emailSimple.test(value)
+		) {
+			email.value.message = "Invalid format.";
+			email.value.valid = false;
+		} else {
+			email.value.message = "Everything looks great!";
+			email.value.valid = true;
+		}
+	}
+);
+watch(
+	() => password.value.value,
+	value => {
+		password.value.entered = true;
+		if (!validation.isLength(value, 6, 200)) {
+			password.value.message =
+				"Password must have between 6 and 200 characters.";
+			password.value.valid = false;
+		} else if (!validation.regex.password.test(value)) {
+			password.value.message =
+				"Include at least one lowercase letter, one uppercase letter, one number and one special character.";
+			password.value.valid = false;
+		} else {
+			password.value.message = "Everything looks great!";
+			password.value.valid = true;
+		}
+	}
+);
+
+onMounted(async () => {
+	apiDomain.value = await lofig.get("backend.apiDomain");
+	lofig.get("siteSettings.registrationDisabled").then(res => {
+		if (res) {
+			new Toast("Registration is disabled.");
+			closeCurrentModal();
+		} else {
+			registrationDisabled.value = res;
+		}
+	});
+
+	lofig.get("recaptcha").then(obj => {
+		recaptcha.value.enabled = obj.enabled;
+		if (obj.enabled === true) {
+			recaptcha.value.key = obj.key;
+
+			const recaptchaScript = document.createElement("script");
+			recaptchaScript.onload = () => {
+				grecaptcha.ready(() => {
+					grecaptcha
+						.execute(recaptcha.value.key, { action: "login" })
+						.then(token => {
+							recaptcha.value.token = token;
+						});
+				});
+			};
+
+			recaptchaScript.setAttribute(
+				"src",
+				`https://www.google.com/recaptcha/api.js?render=${recaptcha.value.key}`
+			);
+			document.head.appendChild(recaptchaScript);
+		}
+	});
+});
+</script>
+
 <template>
 <template>
 	<div>
 	<div>
 		<modal
 		<modal
 			title="Register"
 			title="Register"
 			class="register-modal"
 			class="register-modal"
 			:size="'slim'"
 			:size="'slim'"
-			@closed="closeRegisterModal()"
+			@closed="closeCurrentModal()"
 		>
 		>
 			<template #body>
 			<template #body>
 				<!-- email address -->
 				<!-- email address -->
@@ -15,11 +198,7 @@
 						class="input"
 						class="input"
 						type="email"
 						type="email"
 						placeholder="Email..."
 						placeholder="Email..."
-						@keypress="
-							onInput('email') &
-								submitOnEnter(submitModal, $event)
-						"
-						@paste="onInput('email')"
+						@keyup.enter="submitModal()"
 						autofocus
 						autofocus
 					/>
 					/>
 				</p>
 				</p>
@@ -39,11 +218,7 @@
 						class="input"
 						class="input"
 						type="text"
 						type="text"
 						placeholder="Username..."
 						placeholder="Username..."
-						@keypress="
-							onInput('username') &
-								submitOnEnter(submitModal, $event)
-						"
-						@paste="onInput('username')"
+						@keyup.enter="submitModal()"
 					/>
 					/>
 				</p>
 				</p>
 				<transition name="fadein-helpbox">
 				<transition name="fadein-helpbox">
@@ -64,13 +239,9 @@
 						v-model="password.value"
 						v-model="password.value"
 						class="input"
 						class="input"
 						type="password"
 						type="password"
-						ref="password"
+						ref="passwordElement"
 						placeholder="Password..."
 						placeholder="Password..."
-						@keypress="
-							onInput('password') &
-								submitOnEnter(submitModal, $event)
-						"
-						@paste="onInput('password')"
+						@keyup.enter="submitModal()"
 					/>
 					/>
 					<a @click="togglePasswordVisibility()">
 					<a @click="togglePasswordVisibility()">
 						<i class="material-icons">
 						<i class="material-icons">
@@ -95,11 +266,11 @@
 
 
 				<p>
 				<p>
 					By registering you agree to our
 					By registering you agree to our
-					<router-link to="/terms" @click="closeRegisterModal()">
+					<router-link to="/terms" @click="closeCurrentModal()">
 						Terms of Service
 						Terms of Service
 					</router-link>
 					</router-link>
 					and
 					and
-					<router-link to="/privacy" @click="closeRegisterModal()">
+					<router-link to="/privacy" @click="closeCurrentModal()">
 						Privacy Policy</router-link
 						Privacy Policy</router-link
 					>.
 					>.
 				</p>
 				</p>
@@ -134,187 +305,6 @@
 	</div>
 	</div>
 </template>
 </template>
 
 
-<script>
-import { mapActions } from "vuex";
-import Toast from "toasters";
-
-import validation from "@/validation";
-import InputHelpBox from "../InputHelpBox.vue";
-
-export default {
-	components: { InputHelpBox },
-	data() {
-		return {
-			username: {
-				value: "",
-				valid: false,
-				entered: false,
-				message: "Only letters, numbers and underscores are allowed."
-			},
-			email: {
-				value: "",
-				valid: false,
-				entered: false,
-				message: "Please enter a valid email address."
-			},
-			password: {
-				value: "",
-				valid: false,
-				entered: false,
-				visible: false,
-				message:
-					"Include at least one lowercase letter, one uppercase letter, one number and one special character."
-			},
-			recaptcha: {
-				key: "",
-				token: "",
-				enabled: false
-			},
-			apiDomain: "",
-			registrationDisabled: false
-		};
-	},
-	watch: {
-		// eslint-disable-next-line
-		"username.value": function (value) {
-			if (!validation.isLength(value, 2, 32)) {
-				this.username.message =
-					"Username must have between 2 and 32 characters.";
-				this.username.valid = false;
-			} else if (!validation.regex.azAZ09_.test(value)) {
-				this.username.message =
-					"Invalid format. Allowed characters: a-z, A-Z, 0-9 and _.";
-				this.username.valid = false;
-			} else if (value.replaceAll(/[_]/g, "").length === 0) {
-				this.username.message =
-					"Invalid format. Allowed characters: a-z, A-Z, 0-9 and _, and there has to be at least one letter or number.";
-				this.username.valid = false;
-			} else {
-				this.username.message = "Everything looks great!";
-				this.username.valid = true;
-			}
-		},
-		// eslint-disable-next-line
-		"email.value": function (value) {
-			if (!validation.isLength(value, 3, 254)) {
-				this.email.message =
-					"Email must have between 3 and 254 characters.";
-				this.email.valid = false;
-			} else if (
-				value.indexOf("@") !== value.lastIndexOf("@") ||
-				!validation.regex.emailSimple.test(value)
-			) {
-				this.email.message = "Invalid format.";
-				this.email.valid = false;
-			} else {
-				this.email.message = "Everything looks great!";
-				this.email.valid = true;
-			}
-		},
-		// eslint-disable-next-line
-		"password.value": function (value) {
-			if (!validation.isLength(value, 6, 200)) {
-				this.password.message =
-					"Password must have between 6 and 200 characters.";
-				this.password.valid = false;
-			} else if (!validation.regex.password.test(value)) {
-				this.password.message =
-					"Include at least one lowercase letter, one uppercase letter, one number and one special character.";
-				this.password.valid = false;
-			} else {
-				this.password.message = "Everything looks great!";
-				this.password.valid = true;
-			}
-		}
-	},
-	async mounted() {
-		this.apiDomain = await lofig.get("backend.apiDomain");
-
-		lofig
-			.get("siteSettings.registrationDisabled")
-			.then(registrationDisabled => {
-				this.registrationDisabled = registrationDisabled;
-				if (registrationDisabled) {
-					new Toast("Registration is disabled.");
-					this.closeModal("register");
-				}
-			});
-
-		lofig.get("recaptcha").then(obj => {
-			this.recaptcha.enabled = obj.enabled;
-			if (obj.enabled === true) {
-				this.recaptcha.key = obj.key;
-
-				const recaptchaScript = document.createElement("script");
-				recaptchaScript.onload = () => {
-					grecaptcha.ready(() => {
-						grecaptcha
-							.execute(this.recaptcha.key, { action: "login" })
-							.then(token => {
-								this.recaptcha.token = token;
-							});
-					});
-				};
-
-				recaptchaScript.setAttribute(
-					"src",
-					`https://www.google.com/recaptcha/api.js?render=${this.recaptcha.key}`
-				);
-				document.head.appendChild(recaptchaScript);
-			}
-		});
-	},
-	methods: {
-		submitOnEnter: (cb, event) => {
-			if (event.which === 13) cb();
-		},
-		togglePasswordVisibility() {
-			if (this.$refs.password.type === "password") {
-				this.$refs.password.type = "text";
-				this.password.visible = true;
-			} else {
-				this.$refs.password.type = "password";
-				this.password.visible = false;
-			}
-		},
-		changeToLoginModal() {
-			this.closeRegisterModal();
-			this.openModal("login");
-		},
-		closeRegisterModal() {
-			this.closeModal("register");
-		},
-		submitModal() {
-			if (
-				!this.username.valid ||
-				!this.email.valid ||
-				!this.password.valid
-			)
-				return new Toast("Please ensure all fields are valid.");
-
-			return this.register({
-				username: this.username.value,
-				email: this.email.value,
-				password: this.password.value,
-				recaptchaToken: this.recaptcha.token
-			})
-				.then(res => {
-					if (res.status === "success") window.location.reload();
-				})
-				.catch(err => new Toast(err.message));
-		},
-		onInput(inputName) {
-			this[inputName].entered = true;
-		},
-		githubRedirect() {
-			localStorage.setItem("github_redirect", this.$route.path);
-		},
-		...mapActions("modalVisibility", ["closeModal", "openModal"]),
-		...mapActions("user/auth", ["register"])
-	}
-};
-</script>
-
 <style lang="less" scoped>
 <style lang="less" scoped>
 .night-mode {
 .night-mode {
 	.modal-card,
 	.modal-card,