forked from mrwyndham/fastpocket
283 lines
11 KiB
TypeScript
283 lines
11 KiB
TypeScript
"use client";
|
|
|
|
import React, { Dispatch, SetStateAction } from "react";
|
|
import { useForm } from "react-hook-form";
|
|
import { yupResolver } from "@hookform/resolvers/yup";
|
|
import { signUpValidationSchema } from "@/utils/form";
|
|
import { companySizeList } from "@/constants";
|
|
import pb from "@/lib/pocketbase";
|
|
import { createCheckoutSession, login } from "@/app/actions";
|
|
import { toast } from "react-toastify";
|
|
import { Price, User } from "@/types";
|
|
import { useRouter } from "next/navigation";
|
|
import {Dismiss20Filled} from '@fluentui/react-icons'
|
|
|
|
function ModalSignUp({
|
|
setUser,
|
|
}: {
|
|
setUser: Dispatch<SetStateAction<User | undefined>>;
|
|
}) {
|
|
const {
|
|
register,
|
|
handleSubmit,
|
|
reset,
|
|
formState: { errors, isSubmitting },
|
|
} = useForm({
|
|
resolver: yupResolver(signUpValidationSchema),
|
|
});
|
|
const router = useRouter();
|
|
const generateCheckoutPage = async (price: Price, type: string) => {
|
|
try {
|
|
const checkoutSessionResponse = await createCheckoutSession(
|
|
price.price_id,
|
|
type
|
|
);
|
|
console.log(checkoutSessionResponse);
|
|
router.push(checkoutSessionResponse.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",
|
|
});
|
|
}
|
|
}
|
|
};
|
|
const onSubmit = async (data: any) => {
|
|
data = {
|
|
emailVisibility: false,
|
|
lastSeen: new Date(),
|
|
role: "Admin",
|
|
displayName: `${data.firstName} ${data.lastName}`,
|
|
passwordConfirm: data.password,
|
|
...data,
|
|
};
|
|
try {
|
|
//create organisation
|
|
const organisation = await pb.collection("organisation").create({
|
|
name: data.organisation,
|
|
organisationSize: data.organisationSize,
|
|
});
|
|
//create user
|
|
const user = await pb
|
|
.collection("user")
|
|
.create({ ...data, organisation: organisation.id });
|
|
//login user
|
|
if (
|
|
(await login({ email: data.email, password: data.password })).success
|
|
) {
|
|
reset();
|
|
document.getElementById("sign-up-modal")?.click();
|
|
const price = localStorage.getItem("price");
|
|
const type = localStorage.getItem("type");
|
|
setUser(user as User);
|
|
console.log("price", price);
|
|
console.log("type", type);
|
|
price
|
|
? generateCheckoutPage(JSON.parse(price), type ?? "")
|
|
: router.push("/account");
|
|
}
|
|
} catch (error) {
|
|
if (error instanceof Error) {
|
|
toast.error(
|
|
Object.values((error as any).data.data)
|
|
.map((x: any) => x.message)
|
|
.join(),
|
|
{
|
|
position: "bottom-left",
|
|
autoClose: 5000,
|
|
hideProgressBar: false,
|
|
closeOnClick: true,
|
|
pauseOnHover: true,
|
|
draggable: true,
|
|
progress: undefined,
|
|
theme: "colored",
|
|
}
|
|
);
|
|
}
|
|
}
|
|
};
|
|
return (
|
|
<>
|
|
<input
|
|
type="checkbox"
|
|
id="sign-up-modal"
|
|
className="modal-toggle"
|
|
name=""
|
|
onClick={() => {
|
|
reset();
|
|
}}
|
|
/>
|
|
<label htmlFor="sign-up-modal" className="modal cursor-pointer">
|
|
<label className="modal-box relative max-w-full md:max-w-[550px] py-4 px-3 md:p-6">
|
|
<div className="flex justify-end pb-2 select-none">
|
|
<label
|
|
htmlFor="sign-up-modal"
|
|
className="cursor-pointer text-base-content"
|
|
onClick={() => {
|
|
reset();
|
|
}}
|
|
>
|
|
<Dismiss20Filled />
|
|
</label>
|
|
</div>
|
|
<div className="flex flex-grow flex-col h-[30rem] lg:h-full overflow-y-scroll">
|
|
<div className="w-[100%] bg-gradient-to-r from-primary to-secondary px-6 mt-3 pb-6 rounded-lg text-primary-content">
|
|
<h3 className="pb-1 text-3xl font-bold md:text-3xl pt-6">
|
|
Want to 10X Your Dev Game?
|
|
</h3>
|
|
<p className="text-sm md:text-base">
|
|
Signup and get started using FastPocket
|
|
</p>
|
|
</div>
|
|
<form onSubmit={handleSubmit(onSubmit)} className="w-full pl-1">
|
|
<div className="relative mt-6">
|
|
<input
|
|
type="text"
|
|
className="py-3 px-4 block w-full bg-base-200 text-base-content border-primary/40 rounded-lg text-sm focus:border-secondary focus:ring-secondary disabled:opacity-50 disabled:pointer-events-none "
|
|
placeholder="Email…"
|
|
aria-label="Email…"
|
|
autoComplete="on"
|
|
{...register("email")}
|
|
/>
|
|
<div className="text-start text-sm italic text-error-content">
|
|
{errors.email?.message}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex flex-row gap-4">
|
|
<div className="relative mt-1 flex-grow">
|
|
<input
|
|
type="text"
|
|
className="py-3 px-4 block w-full bg-base-200 text-base-content border-primary/40 rounded-lg text-sm focus:border-secondary focus:ring-secondary disabled:opacity-50 disabled:pointer-events-none "
|
|
placeholder="First Name…"
|
|
aria-label="First Name…"
|
|
autoComplete="on"
|
|
{...register("firstName")}
|
|
/>
|
|
<div className="text-start text-sm italic text-error-content">
|
|
{errors.firstName?.message}
|
|
</div>
|
|
</div>
|
|
<div className="relative mt-1 flex-grow">
|
|
<input
|
|
type="text"
|
|
className="py-3 px-4 block w-full bg-base-200 text-base-content border-primary/40 rounded-lg text-sm focus:border-secondary focus:ring-secondary disabled:opacity-50 disabled:pointer-events-none "
|
|
placeholder="Last Name…"
|
|
aria-label="Last Name…"
|
|
{...register("lastName")}
|
|
/>
|
|
<div className="text-start text-sm italic text-error-content">
|
|
{errors.lastName?.message}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="relative mt-1 flex-grow">
|
|
<input
|
|
type="text"
|
|
className="py-3 px-4 block w-full bg-base-200 text-base-content border-primary/40 rounded-lg text-sm focus:border-secondary focus:ring-secondary disabled:opacity-50 disabled:pointer-events-none "
|
|
placeholder="Phone Number…"
|
|
aria-label="Phone Number…"
|
|
{...register("phoneNumber")}
|
|
/>
|
|
<div className="text-start text-sm italic text-error-content">
|
|
{errors.phoneNumber?.message}
|
|
</div>
|
|
</div>
|
|
<div className="flex flex-row gap-4">
|
|
<div className="relative mt-1 flex-grow">
|
|
<input
|
|
type="text"
|
|
className="py-3 px-4 block w-full bg-base-200 text-base-content border-primary/40 rounded-lg text-sm focus:border-secondary focus:ring-secondary disabled:opacity-50 disabled:pointer-events-none "
|
|
placeholder="Organisation…"
|
|
aria-label="Organisation…"
|
|
{...register("organisation")}
|
|
/>
|
|
<div className="text-start text-sm italic text-error-content">
|
|
{errors.organisation?.message}
|
|
</div>
|
|
</div>
|
|
<div className="relative mt-1 flex-grow">
|
|
<select
|
|
defaultValue={""}
|
|
className="py-3 px-4 block w-full bg-base-200 text-base-content border-primary/40 rounded-lg text-sm focus:border-secondary focus:ring-secondary disabled:opacity-50 disabled:pointer-events-none "
|
|
{...register("organisationSize")}
|
|
>
|
|
<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>
|
|
<div className="text-start text-sm italic text-error-content">
|
|
{errors.organisationSize?.message}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="flex flex-row gap-4">
|
|
<div className="relative mt-1 flex-grow">
|
|
<input
|
|
id="SignUpPwd"
|
|
type="password"
|
|
className="py-3 px-4 block w-full bg-base-200 text-base-content border-primary/40 rounded-lg text-sm focus:border-secondary focus:ring-secondary disabled:opacity-50 disabled:pointer-events-none "
|
|
placeholder="Password..."
|
|
aria-label="Password"
|
|
{...register("password")}
|
|
/>
|
|
<div className="text-start text-sm italic text-error-content">
|
|
{errors.password?.message}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex flex-row items-center gap-x-4">
|
|
<button
|
|
disabled={isSubmitting}
|
|
type="submit"
|
|
className="btn btn-primary"
|
|
>
|
|
Sign Up
|
|
{isSubmitting && <div className="loading"></div>}
|
|
</button>
|
|
<div className=" text-xs w-28 block">
|
|
<span className="whitespace-normal">
|
|
Already have an account?{" "}
|
|
</span>
|
|
|
|
<span
|
|
onClick={() => {
|
|
document.getElementById("sign-up-modal")?.click();
|
|
document.getElementById("sign-in-modal")?.click();
|
|
}}
|
|
className="text-primary hover:text-primary/60 cursor-pointer "
|
|
>
|
|
Sign in
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</label>
|
|
</label>
|
|
</>
|
|
);
|
|
}
|
|
|
|
export default ModalSignUp;
|