next/pages/register.vue

196 lines
4.5 KiB
Vue

<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>