import { OnboardingLayout } from "@/components/layouts/onboarding-layout"; import { AlertBlock } from "@/components/shared/alert-block"; import { Logo } from "@/components/shared/logo"; import { Button } from "@/components/ui/button"; import { CardContent, CardDescription, CardTitle } from "@/components/ui/card"; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { authClient } from "@/lib/auth-client"; import { api } from "@/utils/api"; import { IS_CLOUD, getUserByToken } from "@dokploy/server"; import { zodResolver } from "@hookform/resolvers/zod"; import type { GetServerSidePropsContext } from "next"; import Link from "next/link"; import { useRouter } from "next/router"; import { type ReactElement, useEffect } from "react"; import { useForm } from "react-hook-form"; import { toast } from "sonner"; import { z } from "zod"; const registerSchema = z .object({ name: z.string().min(1, { message: "Name is required", }), email: z .string() .min(1, { message: "Email is required", }) .email({ message: "Email must be a valid email", }), password: z .string() .min(1, { message: "Password is required", }) .refine((password) => password === "" || password.length >= 8, { message: "Password must be at least 8 characters", }), confirmPassword: z .string() .min(1, { message: "Password is required", }) .refine( (confirmPassword) => confirmPassword === "" || confirmPassword.length >= 8, { message: "Password must be at least 8 characters", }, ), }) .refine((data) => data.password === data.confirmPassword, { message: "Passwords do not match", path: ["confirmPassword"], }); type Register = z.infer; interface Props { token: string; invitation: Awaited>; isCloud: boolean; userAlreadyExists: boolean; } const Invitation = ({ token, invitation, isCloud, userAlreadyExists, }: Props) => { const router = useRouter(); const { data } = api.user.getUserByToken.useQuery( { token, }, { enabled: !!token, initialData: invitation, }, ); const form = useForm({ defaultValues: { name: "", email: "", password: "", confirmPassword: "", }, resolver: zodResolver(registerSchema), }); useEffect(() => { if (data?.email) { form.reset({ email: data?.email || "", password: "", confirmPassword: "", }); } }, [form, form.reset, form.formState.isSubmitSuccessful, data]); const onSubmit = async (values: Register) => { try { const { error } = await authClient.signUp.email({ email: values.email, password: values.password, name: values.name, fetchOptions: { headers: { "x-dokploy-token": token, }, }, }); if (error) { toast.error(error.message); return; } const _result = await authClient.organization.acceptInvitation({ invitationId: token, }); toast.success("Account created successfully"); router.push("/dashboard/projects"); } catch { toast.error("An error occurred while creating your account"); } }; return (
Invitation {userAlreadyExists ? (
Valid Invitation! We detected that you already have an account with this email. Please sign in to accept the invitation.
) : ( <> Fill the form below to create your account
{/* {isError && (
{error?.message}
)} */}
( Name )} /> ( Email )} /> ( Password )} /> ( Confirm Password )} />
{isCloud && ( <> Login Lost your password? )}
)}
); }; // http://localhost:3000/invitation?token=CZK4BLrUdMa32RVkAdZiLsPDdvnPiAgZ // /f7af93acc1a99eae864972ab4c92fee089f0d83473d415ede8e821e5dbabe79c export default Invitation; Invitation.getLayout = (page: ReactElement) => { return {page}; }; export async function getServerSideProps(ctx: GetServerSidePropsContext) { const { query } = ctx; const token = query.token; // if (IS_CLOUD) { // return { // redirect: { // permanent: true, // destination: "/", // }, // }; // } if (typeof token !== "string") { return { redirect: { permanent: true, destination: "/", }, }; } try { const invitation = await getUserByToken(token); if (invitation.userAlreadyExists) { return { props: { isCloud: IS_CLOUD, token: token, invitation: invitation, userAlreadyExists: true, }, }; } if (invitation.isExpired) { return { redirect: { permanent: true, destination: "/", }, }; } return { props: { isCloud: IS_CLOUD, token: token, invitation: invitation, }, }; } catch (error) { console.log("error", error); return { redirect: { permanent: true, destination: "/", }, }; } }