forked from mrwyndham/fastpocket
318 lines
11 KiB
TypeScript
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;
|