import { CheckIcon } from "@heroicons/react/solid"; import { zodResolver } from "@hookform/resolvers/zod"; import classNames from "classnames"; import { GetServerSidePropsContext } from "next"; import { useRouter } from "next/router"; import { useState } from "react"; import { Controller, FormProvider, useForm } from "react-hook-form"; import * as z from "zod"; import { isPasswordValid } from "@calcom/lib/auth"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import prisma from "@calcom/prisma"; import { inferSSRProps } from "@calcom/types/inferSSRProps"; import { EmailField, Label, PasswordField, TextField, WizardForm } from "@calcom/ui"; import { ssrInit } from "@server/lib/ssr"; const StepDone = () => { const { t } = useLocale(); return (

{t("all_done")}

); }; const SetupFormStep1 = (props: { setIsLoading: (val: boolean) => void }) => { const router = useRouter(); const { t } = useLocale(); const formSchema = z.object({ username: z .string() .refine((val) => val.trim().length >= 1, { message: t("at_least_characters", { count: 1 }) }), email_address: z.string().email({ message: t("enter_valid_email") }), full_name: z.string().min(3, t("at_least_characters", { count: 3 })), password: z.string().superRefine((data, ctx) => { const isStrict = true; const result = isPasswordValid(data, true, isStrict); Object.keys(result).map((key: string) => { if (!result[key as keyof typeof result]) { ctx.addIssue({ code: z.ZodIssueCode.custom, path: [key], message: key, }); } }); }), }); const formMethods = useForm<{ username: string; email_address: string; full_name: string; password: string; }>({ resolver: zodResolver(formSchema), }); const onError = () => { props.setIsLoading(false); }; const onSubmit = formMethods.handleSubmit(async (data: z.infer) => { props.setIsLoading(true); const response = await fetch("/api/auth/setup", { method: "POST", body: JSON.stringify({ username: data.username.trim(), full_name: data.full_name, email_address: data.email_address.toLowerCase(), password: data.password, }), headers: { "Content-Type": "application/json", }, }); if (response.status === 200) { router.replace(`/auth/login?email=${data.email_address.toLowerCase()}`); } else { router.replace("/auth/setup"); } }, onError); const longWebsiteUrl = process.env.NEXT_PUBLIC_WEBSITE_URL.length > 30; return (
( <> {process.env.NEXT_PUBLIC_WEBSITE_URL}/ ) } id="username" labelSrOnly={true} value={value || ""} className={classNames("my-0", longWebsiteUrl && "rounded-t-none")} onBlur={onBlur} name="username" onChange={async (e) => { onChange(e.target.value); formMethods.setValue("username", e.target.value); await formMethods.trigger("username"); }} /> )} />
( { onChange(e.target.value); formMethods.setValue("full_name", e.target.value); await formMethods.trigger("full_name"); }} color={formMethods.formState.errors.full_name ? "warn" : ""} type="text" name="full_name" autoCapitalize="none" autoComplete="name" autoCorrect="off" className="my-0" /> )} />
( { onChange(e.target.value); formMethods.setValue("email_address", e.target.value); await formMethods.trigger("email_address"); }} className="my-0" name="email_address" /> )} />
( { onChange(e.target.value); formMethods.setValue("password", e.target.value); await formMethods.trigger("password"); }} hintErrors={["caplow", "admin_min", "num"]} name="password" className="my-0" autoComplete="off" /> )} />
); }; export default function Setup(props: inferSSRProps) { const { t } = useLocale(); const [isLoadingStep1, setIsLoadingStep1] = useState(false); const steps = [ { title: t("administrator_user"), description: t("lets_create_first_administrator_user"), content: props.userCount !== 0 ? : , enabled: props.userCount === 0, // to check if the wizard should show buttons to navigate through more steps isLoading: isLoadingStep1, }, ]; return ( <>
); } export const getServerSideProps = async (context: GetServerSidePropsContext) => { const ssr = await ssrInit(context); const userCount = await prisma.user.count(); return { props: { trpcState: ssr.dehydrate(), userCount, }, }; };