import { GetServerSidePropsContext } from "next"; import { getCsrfToken, signIn } from "next-auth/client"; import Link from "next/link"; import { useRouter } from "next/router"; import { useState } from "react"; import { ErrorCode, getSession } from "@lib/auth"; import { WEBSITE_URL } from "@lib/config/constants"; import { useLocale } from "@lib/hooks/useLocale"; import { inferSSRProps } from "@lib/types/inferSSRProps"; import AddToHomescreen from "@components/AddToHomescreen"; import Loader from "@components/Loader"; import { EmailInput } from "@components/form/fields"; import { HeadSeo } from "@components/seo/head-seo"; import { ssrInit } from "@server/lib/ssr"; export default function Login({ csrfToken }: inferSSRProps) { const { t } = useLocale(); const router = useRouter(); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [code, setCode] = useState(""); const [isSubmitting, setIsSubmitting] = useState(false); const [secondFactorRequired, setSecondFactorRequired] = useState(false); const [errorMessage, setErrorMessage] = useState(null); const errorMessages: { [key: string]: string } = { [ErrorCode.SecondFactorRequired]: t("2fa_enabled_instructions"), [ErrorCode.IncorrectPassword]: `${t("incorrect_password")} ${t("please_try_again")}`, [ErrorCode.UserNotFound]: t("no_account_exists"), [ErrorCode.IncorrectTwoFactorCode]: `${t("incorrect_2fa_code")} ${t("please_try_again")}`, [ErrorCode.InternalServerError]: `${t("something_went_wrong")} ${t("please_try_again_and_contact_us")}`, }; const callbackUrl = typeof router.query?.callbackUrl === "string" ? router.query.callbackUrl : "/"; async function handleSubmit(e: React.SyntheticEvent) { e.preventDefault(); if (isSubmitting) { return; } setIsSubmitting(true); setErrorMessage(null); try { const response = await signIn("credentials", { redirect: false, email, password, totpCode: code, callbackUrl, }); if (!response) { throw new Error("Received empty response from next auth"); } if (!response.error) { // we're logged in! let's do a hard refresh to the desired url window.location.replace(callbackUrl); return; } if (response.error === ErrorCode.SecondFactorRequired) { setSecondFactorRequired(true); setErrorMessage(errorMessages[ErrorCode.SecondFactorRequired]); } else { setErrorMessage(errorMessages[response.error] || t("something_went_wrong")); } setIsSubmitting(false); } catch (e) { setErrorMessage(t("something_went_wrong")); setIsSubmitting(false); } } return (
{isSubmitting && (
)}
Cal.com Logo

{t("sign_in_account")}

setEmail(e.currentTarget.value)} className="block w-full px-3 py-2 placeholder-gray-400 border rounded-sm shadow-sm appearance-none border-neutral-300 focus:outline-none focus:ring-neutral-900 focus:border-neutral-900 sm:text-sm" />
setPassword(e.currentTarget.value)} className="block w-full px-3 py-2 placeholder-gray-400 border rounded-sm shadow-sm appearance-none border-neutral-300 focus:outline-none focus:ring-neutral-900 focus:border-neutral-900 sm:text-sm" />
{secondFactorRequired && (
setCode(e.currentTarget.value)} className="block w-full px-3 py-2 placeholder-gray-400 border rounded-sm shadow-sm appearance-none border-neutral-300 focus:outline-none focus:ring-neutral-900 focus:border-neutral-900 sm:text-sm" />
)}
{errorMessage &&

{errorMessage}

}
{t("dont_have_an_account")} {/* replace this with your account creation flow */} {t("create_an_account")}
); } export async function getServerSideProps(context: GetServerSidePropsContext) { const { req } = context; const session = await getSession({ req }); const ssr = await ssrInit(context); if (session) { return { redirect: { destination: "/", permanent: false, }, }; } return { props: { csrfToken: await getCsrfToken(context), trpcState: ssr.dehydrate(), }, }; }