import communityCardsImage from '@documenso/assets/images/community-cards.png'; import { authClient } from '@documenso/auth/client'; import { useAnalytics } from '@documenso/lib/client-only/hooks/use-analytics'; import { ZNameSchema } from '@documenso/lib/constants/auth'; import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error'; import { env } from '@documenso/lib/utils/env'; import { zEmail } from '@documenso/lib/utils/zod'; import { ZPasswordSchema } from '@documenso/trpc/server/auth-router/schema'; import { cn } from '@documenso/ui/lib/utils'; import { Button } from '@documenso/ui/primitives/button'; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@documenso/ui/primitives/form/form'; import { Input } from '@documenso/ui/primitives/input'; import { PasswordInput } from '@documenso/ui/primitives/password-input'; import { SignaturePadDialog } from '@documenso/ui/primitives/signature-pad/signature-pad-dialog'; import { useToast } from '@documenso/ui/primitives/use-toast'; import { zodResolver } from '@hookform/resolvers/zod'; import type { MessageDescriptor } from '@lingui/core'; import { msg } from '@lingui/core/macro'; import { useLingui } from '@lingui/react'; import { Trans } from '@lingui/react/macro'; import type { TurnstileInstance } from '@marsidev/react-turnstile'; import { Turnstile } from '@marsidev/react-turnstile'; import { useEffect, useRef } from 'react'; import { useForm } from 'react-hook-form'; import { FaIdCardClip } from 'react-icons/fa6'; import { FcGoogle } from 'react-icons/fc'; import { Link, useNavigate, useSearchParams } from 'react-router'; import { z } from 'zod'; import { UserProfileTimur } from '~/components/general/user-profile-timur'; export const ZSignUpFormSchema = z .object({ name: ZNameSchema, email: zEmail().min(1), password: ZPasswordSchema, signature: z.string().min(1, { message: msg`We need your signature to sign documents`.id }), }) .refine( (data) => { const { name, email, password } = data; return !password.includes(name) && !password.includes(email.split('@')[0]); }, { message: msg`Password should not be common or based on personal information`.id, path: ['password'], }, ); export const SIGNUP_ERROR_MESSAGES: Record = { SIGNUP_DISABLED: msg`Signup is currently disabled or not available for your email domain.`, SIGNUP_DISPOSABLE_EMAIL: msg`Disposable email addresses are not allowed. Please sign up with a permanent email address.`, [AppErrorCode.ALREADY_EXISTS]: msg`We were unable to create your account. If you already have an account, try signing in instead.`, [AppErrorCode.INVALID_REQUEST]: msg`We were unable to create your account. Please review the information you provided and try again.`, }; export type TSignUpFormSchema = z.infer; export type SignUpFormProps = { className?: string; initialEmail?: string; isEmailPasswordSignupEnabled?: boolean; isGoogleSignupEnabled?: boolean; isMicrosoftSignupEnabled?: boolean; isOidcSignupEnabled?: boolean; returnTo?: string; }; export const SignUpForm = ({ className, initialEmail, isEmailPasswordSignupEnabled = true, isGoogleSignupEnabled, isMicrosoftSignupEnabled, isOidcSignupEnabled, returnTo, }: SignUpFormProps) => { const { _ } = useLingui(); const { toast } = useToast(); const analytics = useAnalytics(); const navigate = useNavigate(); const [searchParams] = useSearchParams(); const utmSrc = searchParams.get('utm_source') ?? null; const turnstileSiteKey = env('NEXT_PUBLIC_TURNSTILE_SITE_KEY'); const turnstileRef = useRef(null); const hasSocialAuthEnabled = isGoogleSignupEnabled || isMicrosoftSignupEnabled || isOidcSignupEnabled; const form = useForm({ values: { name: '', email: initialEmail ?? '', password: '', signature: '', }, mode: 'onBlur', resolver: zodResolver(ZSignUpFormSchema), }); const isSubmitting = form.formState.isSubmitting; const onFormSubmit = async ({ name, email, password, signature }: TSignUpFormSchema) => { try { let token: string | undefined; if (turnstileSiteKey) { token = await turnstileRef.current?.getResponsePromise(3000).catch((_err) => undefined); if (!token) { toast({ title: _(msg`Human verification required`), description: _(msg`Please complete the CAPTCHA challenge before signing in.`), variant: 'destructive', }); return; } } await authClient.emailPassword.signUp({ name, email, password, signature, captchaToken: token ?? undefined, }); await navigate(returnTo ? returnTo : '/unverified-account'); toast({ title: _(msg`Registration Successful`), description: _( msg`You have successfully registered. Please verify your account by clicking on the link you received in the email.`, ), duration: 5000, }); analytics.capture('App: User Sign Up', { email, timestamp: new Date().toISOString(), custom_campaign_params: { src: utmSrc }, }); } catch (err) { const error = AppError.parseError(err); const errorMessage = SIGNUP_ERROR_MESSAGES[error.code] ?? SIGNUP_ERROR_MESSAGES.INVALID_REQUEST; toast({ title: _(msg`An error occurred`), description: _(errorMessage), variant: 'destructive', }); turnstileRef.current?.reset(); } }; const onSignUpWithGoogleClick = async () => { try { await authClient.google.signIn(); } catch { toast({ title: _(msg`An unknown error occurred`), description: _(msg`We encountered an unknown error while attempting to sign you Up. Please try again later.`), variant: 'destructive', }); } }; const onSignUpWithMicrosoftClick = async () => { try { await authClient.microsoft.signIn(); } catch { toast({ title: _(msg`An unknown error occurred`), description: _(msg`We encountered an unknown error while attempting to sign you Up. Please try again later.`), variant: 'destructive', }); } }; const onSignUpWithOIDCClick = async () => { try { await authClient.oidc.signIn(); } catch { toast({ title: _(msg`An unknown error occurred`), description: _(msg`We encountered an unknown error while attempting to sign you Up. Please try again later.`), variant: 'destructive', }); } }; useEffect(() => { const hash = window.location.hash.slice(1); const params = new URLSearchParams(hash); const email = params.get('email'); if (email) { form.setValue('email', email); } }, [form]); return (
community-cards
User profiles are here!

Create a new account

Create your account and start using state-of-the-art document signing. Open and beautiful signing is within your grasp.


{isEmailPasswordSignupEnabled && ( <> ( Full Name )} /> ( Email Address )} /> ( Password )} /> ( Sign Here onChange(v ?? '')} /> )} /> )} {turnstileSiteKey && ( )} {hasSocialAuthEnabled && (
Or
)} {isGoogleSignupEnabled && ( )} {isMicrosoftSignupEnabled && ( )} {isOidcSignupEnabled && ( )}

Already have an account?{' '} Sign in instead

{isEmailPasswordSignupEnabled && ( )}

By proceeding, you agree to our{' '} Terms of Service {' '} and{' '} Privacy Policy .

); };