Quiz-PDF/Frontend/sections/ModalSignUp/ModalSignUpForm.tsx

318 lines
11 KiB
TypeScript

"use client";
import React, {
forwardRef,
useEffect,
useImperativeHandle,
useState,
} from "react";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import { signUpValidationSchema } from "@/utils/form";
import {
login,
signup,
createCheckoutSession,
mailchimp,
} from "@/app/(auth)/actions";
import { CheckoutSession, ModalStatus, SignUpForm, TextOnUse } from "@/types";
import { toast } from "react-toastify";
import { useRouter } from "next/navigation";
import { FormRefMethods } from "../ModalSignIn/ModalSignInForm";
interface ModalSignUpFormProps {
generateCheckoutSession: boolean;
textOnUse: TextOnUse;
companySizeList: string[];
setStatus: React.Dispatch<React.SetStateAction<ModalStatus>>;
getPriceId: () => string | undefined;
}
const ModalSignUpForm = forwardRef<FormRefMethods, ModalSignUpFormProps>(
(
{
generateCheckoutSession,
companySizeList,
textOnUse,
setStatus,
getPriceId,
}: ModalSignUpFormProps,
ref
) => {
const router = useRouter();
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [organisation, setOrganisation] = useState("");
const {
register,
handleSubmit,
reset,
formState: { errors },
} = useForm({
resolver: yupResolver(signUpValidationSchema),
});
const submitForm = async (data: SignUpForm) => {
setEmail(data.email);
setPassword(data.password!);
setOrganisation(data.organisation);
setStatus(ModalStatus.Loading);
try {
await sendMailchimpRequest(data);
await sendSignUpRequest(data);
await sendSignInRequest(data);
const price_id = getPriceId();
console.log("price_id", price_id);
const checkoutSession = await checkoutSessionRequest(price_id);
setEmail("");
setPassword("");
setOrganisation("");
reset();
setStatus(ModalStatus.Success);
if (!!checkoutSession) {
router.push(checkoutSession.url);
}
} catch (error) {
if (error instanceof Error) {
toast.error(error.message, {
position: "bottom-left",
autoClose: 5000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
theme: "colored",
});
}
setStatus(ModalStatus.Default);
}
};
const sendMailchimpRequest = async (data: SignUpForm) => {
console.log("sendMailchimpRequest call initiated");
await mailchimp({
email: data.email,
first_name: data.first_name,
last_name: data.last_name,
phone_number: !data.phone_number ? "" : data.phone_number,
company_size: data.company_size,
source: textOnUse.source,
});
console.log("sendMailchimpRequest call success");
};
const checkoutSessionRequest = async (price_id?: string) => {
if (!price_id) {
return;
}
console.log("createCheckoutSession call initiated");
const checkoutSession = await createCheckoutSession(price_id);
console.log("createCheckoutSession successful");
return checkoutSession;
};
const sendSignUpRequest = async (data: SignUpForm) => {
try {
console.log("Signup call initiated");
await signup(data);
console.log("Signup successful");
} catch (error) {
if (error instanceof Error) {
console.error(
"Error during the signup or email process:",
error.message
);
}
throw error; // This will allow .catch block outside this function to capture the error
}
};
const sendSignInRequest = async (data: SignUpForm) => {
try {
console.log("SignIn call initiated");
await login({ email: data.email, password: data.password! });
console.log("SignIn successful");
} catch (error) {
if (error instanceof Error) {
console.error(
"Error during the SignIn or email process:",
error.message
);
}
throw error; // This will allow .catch block outside this function to capture the error
}
};
useImperativeHandle(ref, () => ({
resetForm: () => {
reset();
setEmail("");
setPassword("");
setOrganisation("");
},
}));
return (
<form onSubmit={handleSubmit(submitForm)} className="w-full md:w-1/2">
<div className="relative mt-3">
<input
{...register("email")}
type="text"
id="SignUpEmail"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:text-white dark:placeholder-white dark:border-white"
placeholder="Email…"
aria-label="Email…"
autoComplete="on"
/>
<label
htmlFor="SignUpEmail"
className="md:absolute top-[50%] translate-y-[-50%] left-[105%] w-[220px] text-red-400"
>
{errors.email ? "*" + errors.email.message : ""}
</label>
</div>
<div className="relative mt-1">
<input
{...register("first_name")}
id="SignUpFirstName"
type="text"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:text-white dark:placeholder-white dark:border-white"
placeholder="First Name…"
aria-label="First Name…"
autoComplete="on"
/>
<label
htmlFor="SignUpFirstName"
className="md:absolute top-[50%] translate-y-[-50%] left-[105%] w-[220px] text-red-400"
>
{errors.first_name ? "*" + errors.first_name.message : ""}
</label>
</div>
<div className="relative mt-1">
<input
{...register("last_name")}
id="SignUpLastName"
type="text"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:text-white dark:placeholder-white dark:border-white"
placeholder="Last Name…"
aria-label="Last Name…"
/>
<label
htmlFor="SignUpLastName"
className="md:absolute top-[50%] translate-y-[-50%] left-[105%] w-[220px] text-red-400"
>
{errors.last_name ? "*" + errors.last_name.message : ""}
</label>
</div>
<div className="relative mt-1">
<input
{...register("phone_number")}
id="SignUpPhoneNumber"
type="text"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:text-white dark:placeholder-white dark:border-white"
placeholder="Phone Number…"
aria-label="Phone Number…"
/>
<label
htmlFor="SignUpPhoneNumber"
className="md:absolute top-[50%] translate-y-[-50%] left-[105%] w-[220px] text-red-400"
>
{errors.phone_number ? "*" + errors.phone_number.message : ""}
</label>
</div>
<div className="relative mt-1">
<input
{...register("organisation")}
id="SignUpOrganisation"
type="text"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:text-white dark:placeholder-white dark:border-white"
placeholder="Organisation…"
aria-label="Organisation…"
/>
<label
htmlFor="SignUpOrganisation"
className="md:absolute top-[50%] translate-y-[-50%] left-[105%] w-[220px] text-red-400"
>
{errors.organisation ? "*" + errors.organisation.message : ""}
</label>
</div>
<div className="relative mt-1">
<select
{...register("company_size")}
id="SignUpCompanySize"
defaultValue={""}
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:text-white dark:placeholder-white dark:border-white"
>
<option className="bg-gray-850" value={""} disabled>
Company Size
</option>
{companySizeList.map((companySizeOption, i) => {
return (
<option
className="bg-gray-850"
value={companySizeOption}
key={i}
>
{companySizeOption}
</option>
);
})}
</select>
<label
htmlFor="SignUpCompanySize"
className="md:absolute top-[50%] translate-y-[-50%] left-[105%] w-[220px] text-red-400"
>
{errors.company_size ? "*" + errors.company_size.message : ""}
</label>
</div>
<div className="relative mt-1">
<input
{...register("password")}
id="SignUpPwd"
type="password"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:text-white dark:placeholder-white dark:border-white"
placeholder="Password..."
aria-label="Password"
/>
<label
htmlFor="SignUpPwd"
className="md:absolute top-[50%] translate-y-[-50%] left-[105%] w-[220px] text-red-400"
>
{errors.password ? "*" + errors.password.message : ""}
</label>
</div>
<div className="relative mt-1 mb-4">
<input
{...register("passwordConfirmation")}
id="SignUpPwdConfirm"
type="password"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:text-white dark:placeholder-white dark:border-white"
placeholder="Confirmed Password..."
aria-label="Confirmed Password"
/>
<label
htmlFor="SignUpPwd"
className="md:absolute top-[50%] translate-y-[-50%] left-[105%] w-[220px] text-red-400"
>
{errors.passwordConfirmation
? "*" + errors.passwordConfirmation.message
: ""}
</label>
</div>
<button
type="submit"
className="btn capitalize font-bold text-black bg-white hover:bg-white shadow"
>
{textOnUse.buttonText}
</button>
</form>
);
}
);
ModalSignUpForm.displayName = "ModalSignUpForm";
export default ModalSignUpForm;