feat(pages): create registration page
This commit is contained in:
		
							parent
							
								
									bed696b8ae
								
							
						
					
					
						commit
						3bfa7611bc
					
				
							
								
								
									
										195
									
								
								pages/register.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										195
									
								
								pages/register.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,195 @@ | ||||
| <script lang="ts" setup> | ||||
| 	import { ref, reactive } from "vue"; | ||||
| 	import { | ||||
| 		Form as veeForm, | ||||
| 		Field as veeField, | ||||
| 		useField, | ||||
| 		useForm, | ||||
| 		useSetFieldValue, | ||||
| 		useFormErrors, | ||||
| 		useFormValues, | ||||
| 		RuleExpression, | ||||
| 	} from "vee-validate"; | ||||
| 	import * as yup from "yup"; | ||||
| 	import { useRecaptchaProvider } from "vue-recaptcha"; | ||||
| 
 | ||||
| 	import { useChallengeV2 } from "vue-recaptcha"; | ||||
| 	import { notification } from "ant-design-vue"; | ||||
| 	import { log } from "~/lib/server/logger"; | ||||
| 	import termsOfServices from "~/components/tos.vue"; | ||||
| 	useRecaptchaProvider(); | ||||
| 
 | ||||
| 	interface FormState { | ||||
| 		username: string; | ||||
| 		password: string; | ||||
| 		email: string; | ||||
| 		recaptcha?: string | null; | ||||
| 		agree: boolean; | ||||
| 	} | ||||
| 	definePageMeta({ | ||||
| 		auth: { | ||||
| 			unauthenticatedOnly: true, | ||||
| 			navigateAuthenticatedTo: "/", | ||||
| 		}, | ||||
| 	}); | ||||
| 	// const { execute } = useChallengeV3('submit'); | ||||
| 	const vschema = yup.object<FormState>().shape({ | ||||
| 		username: yup | ||||
| 			.string() | ||||
| 			.ensure() | ||||
| 			.trim() | ||||
| 			.min(1) | ||||
| 			.required("Username is required!"), | ||||
| 		password: yup | ||||
| 			.string() | ||||
| 			.ensure() | ||||
| 			.trim() | ||||
| 			.min(8) | ||||
| 			.required("Password is required!"), | ||||
| 		email: yup.string().ensure().trim().email().required("Email is required!"), | ||||
| 		// recaptcha: yup.string().required('Please verify you are human.'), | ||||
| 		agree: yup | ||||
| 			.boolean() | ||||
| 			.oneOf([true], "Please agree to the terms.") | ||||
| 			.required("Please agree to the terms."), | ||||
| 	}); | ||||
| 	const dv: FormState = { | ||||
| 		username: "", | ||||
| 		password: "", | ||||
| 		email: "", | ||||
| 		agree: false, | ||||
| 	}; | ||||
| 
 | ||||
| 	const dark = inject<boolean>("dark"); | ||||
| 
 | ||||
| 	const { setValues, values, handleSubmit } = useForm({ | ||||
| 		validationSchema: vschema, | ||||
| 		keepValuesOnUnmount: true, | ||||
| 	}); | ||||
| 
 | ||||
| 	const { | ||||
| 		value: recaptchaValue, | ||||
| 		errorMessage: recaptchaError, | ||||
| 		name: recapName, | ||||
| 		setValue: srv, | ||||
| 	} = useField<string>("recaptcha", undefined, { syncVModel: true }); | ||||
| 
 | ||||
| 	const { root, execute, onVerify, widgetID } = useChallengeV2({ | ||||
| 		options: { | ||||
| 			size: "invisible", | ||||
| 		}, | ||||
| 	}); | ||||
| 	onVerify((resp) => { | ||||
| 		// log.debug("onverify called", resp); | ||||
| 		srv(resp); | ||||
| 	}); | ||||
| 	const onFinish = handleSubmit(async (values: any, actions: any) => { | ||||
| 		// log.debug(values, widgetID); | ||||
| 		// log.debug(widgetID); | ||||
| 		execute(); | ||||
| 		const { signUp } = useAuth(); | ||||
| 		let reso; | ||||
| 		try { | ||||
| 			reso = await signUp(values, { callbackUrl: "/" }); | ||||
| 		} catch (e: any) { | ||||
| 			// log.debug(e.data); | ||||
| 			if (e.data) { | ||||
| 				notification["error"]({ | ||||
| 					message: h("div", { innerHTML: e.data.message }), | ||||
| 				}); | ||||
| 			} | ||||
| 		} | ||||
| 		// log.debug(reso); | ||||
| 
 | ||||
| 		/* try { | ||||
| {data: reso } = await useApiFetch("/auth/register", { | ||||
| method: "post", | ||||
| body: values | ||||
| }) | ||||
| } catch (e: any) { | ||||
| // log.debug(reso.error.data) | ||||
| if (e.data) { | ||||
| notification[ "error" ]({ | ||||
| 	message: h("div", { innerHTML: reso.error.data.message }) | ||||
| }) | ||||
| } | ||||
| } */ | ||||
| 	}); | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
| 	<form @submit="onFinish"> | ||||
| 		<vee-field name="username" v-slot="{ field, errorMessage, value }"> | ||||
| 			<a-form-item | ||||
| 				label="Username" | ||||
| 				:name="field.name" | ||||
| 				:validate-status="!!errorMessage ? 'error' : undefined" | ||||
| 				:help="errorMessage" | ||||
| 			> | ||||
| 				<a-input v-bind="field" v-model:value="field.value" /> | ||||
| 			</a-form-item> | ||||
| 		</vee-field> | ||||
| 		<vee-field name="email" v-slot="{ field, errorMessage, value }"> | ||||
| 			<a-form-item | ||||
| 				label="Email address" | ||||
| 				:name="field.name" | ||||
| 				:validate-status="!!errorMessage ? 'error' : undefined" | ||||
| 				:help="errorMessage" | ||||
| 			> | ||||
| 				<a-input v-bind="field" v-model:value="field.value" /> | ||||
| 			</a-form-item> | ||||
| 		</vee-field> | ||||
| 		<vee-field name="password" v-slot="{ field, errorMessage, value }"> | ||||
| 			<a-form-item | ||||
| 				label="Password" | ||||
| 				:name="field.name" | ||||
| 				:validate-status="!!errorMessage ? 'error' : undefined" | ||||
| 				:help="errorMessage" | ||||
| 			> | ||||
| 				<a-input-password v-bind="field" v-model:value="field.value" /> | ||||
| 			</a-form-item> | ||||
| 		</vee-field> | ||||
| 
 | ||||
| 		<a-typography-title :level="4" :style="{ textAlign: 'center' }" | ||||
| 			>Terms</a-typography-title | ||||
| 		> | ||||
| 		<div class="maxHeightScroller"> | ||||
| 			<div style="height: 100%"> | ||||
| 				<terms-of-services /> | ||||
| 				<vee-field | ||||
| 					name="agree" | ||||
| 					:unchecked-value="false" | ||||
| 					type="checkbox" | ||||
| 					v-slot="{ field, value, errorMessage }" | ||||
| 				> | ||||
| 					<a-checkbox | ||||
| 						@update:checked=" | ||||
| 							(n) => { | ||||
| 								setValues({ agree: n }); | ||||
| 								if (!recaptchaValue) execute(); | ||||
| 							} | ||||
| 						" | ||||
| 					> | ||||
| 						I agree to the Terms and am <b>18 years of age or older.</b> | ||||
| 					</a-checkbox> | ||||
| 					<div style="color: red">{{ errorMessage }}</div> | ||||
| 				</vee-field> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 		<div ref="root" /> | ||||
| 		<a-row :align="'middle'" justify="center"> | ||||
| 			<a-col> | ||||
| 				<a-button size="large" type="primary" html-type="submit" | ||||
| 					>Sign me up!</a-button | ||||
| 				> | ||||
| 			</a-col> | ||||
| 		</a-row> | ||||
| 	</form> | ||||
| </template> | ||||
| <style scoped> | ||||
| 	.maxHeightScroller { | ||||
| 		max-height: 400px; | ||||
| 		overflow-y: scroll; | ||||
| 		display: block; | ||||
| 	} | ||||
| </style> | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user