'use client'; //=========================================== // THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template //=========================================== import { KnownError } from '@hexclave/shared'; import { captureError } from '@hexclave/shared/dist/utils/errors'; import { runAsynchronously } from '@hexclave/shared/dist/utils/promises'; import { use } from '@hexclave/shared/dist/utils/react'; import { Skeleton, Tabs, TabsContent, TabsList, TabsTrigger, Typography, cn } from '@hexclave/ui'; import { Suspense, useMemo } from 'react'; import { useStackApp, useUser } from '..'; import { CredentialSignIn } from '../components/credential-sign-in'; import { CredentialSignUp } from '../components/credential-sign-up'; import { MaybeFullPage } from '../components/elements/maybe-full-page'; import { SeparatorWithText } from '../components/elements/separator-with-text'; import { StyledLink } from '../components/link'; import { KnownErrorMessageCard } from '../components/message-cards/known-error-message-card'; import { MessageCard } from '../components/message-cards/message-card'; import { NoAuthMethodsMessageCard } from '../components/message-cards/no-auth-methods-message-card'; import { MagicLinkSignIn } from '../components/magic-link-sign-in'; import { PredefinedMessageCard } from '../components/message-cards/predefined-message-card'; import { OAuthButtonGroup } from '../components/oauth-button-group'; import { PasskeyButton } from '../components/passkey-button'; import { useTranslation } from '../lib/translations'; type Props = { noPasswordRepeat?: boolean, firstTab?: 'magic-link' | 'password', fullPage?: boolean, type: 'sign-in' | 'sign-up', automaticRedirect?: boolean, extraInfo?: React.ReactNode, mockProject?: { config: { signUpEnabled: boolean, credentialEnabled: boolean, passkeyEnabled: boolean, magicLinkEnabled: boolean, oauthProviders: { id: string, }[], }, }, } type AutomaticRedirectResult = | { status: "success" } | { status: "known-error", error: KnownError } | { status: "unknown-error" }; export function AuthPage(props: Props) { return }> ; } function Fallback(props: Props) { return (
); } function AutomaticRedirect(props: { fullPage?: boolean, isRestricted: boolean, type: 'sign-in' | 'sign-up', }) { const hexclaveApp = useStackApp(); const { t } = useTranslation(); const redirectResultPromise = useMemo(async (): Promise => { try { await ( props.isRestricted ? hexclaveApp.redirectToOnboarding({ replace: true }) : props.type === 'sign-in' ? hexclaveApp.redirectToAfterSignIn({ replace: true }) : hexclaveApp.redirectToAfterSignUp({ replace: true }) ); return { status: "success" }; } catch (e) { if (KnownError.isKnownError(e)) { return { status: "known-error", error: e }; } captureError("", e); return { status: "unknown-error" }; } }, [hexclaveApp, props.isRestricted, props.type]); const redirectResult = use(redirectResultPromise); if (redirectResult.status === "known-error") { return ; } if (redirectResult.status === "unknown-error") { return ; } return ; } function Inner(props: Props) { const hexclaveApp = useStackApp(); const user = useUser({ includeRestricted: true }); const projectFromHook = hexclaveApp.useProject(); const project = props.mockProject || projectFromHook; const { t } = useTranslation(); if (props.automaticRedirect && user && !props.mockProject) { return }> ; } if (user && !props.mockProject && !props.automaticRedirect) { return ; } if (props.type === 'sign-up' && !project.config.signUpEnabled) { return ; } const hasOAuthProviders = project.config.oauthProviders.length > 0; const hasPasskey = (project.config.passkeyEnabled === true && props.type === "sign-in"); const enableSeparator = (project.config.credentialEnabled || project.config.magicLinkEnabled) && (hasOAuthProviders || hasPasskey); // Note that we check passkeys regardless of `props.type` here (unlike `hasPasskey`); a project with only // passkeys enabled can't sign up with them, but it is configured correctly, so the sign-up page should // keep pointing at the sign-in page instead of claiming that the project is misconfigured. const hasAnyAuthMethod = hasOAuthProviders || project.config.passkeyEnabled === true || project.config.credentialEnabled || project.config.magicLinkEnabled; if (!hasAnyAuthMethod) { return ; } return (
{props.type === 'sign-in' ? t("Sign in to your account") : t("Create a new account")} {props.type === 'sign-in' ? ( project.config.signUpEnabled && ( {t("Don't have an account?")}{" "} { runAsynchronously(hexclaveApp.redirectToSignUp()); e.preventDefault(); }}>{t("Sign up")} ) ) : ( {t("Already have an account?")}{" "} { runAsynchronously(hexclaveApp.redirectToSignIn()); e.preventDefault(); }}>{t("Sign in")} )}
{(hasOAuthProviders || hasPasskey) && (
{hasOAuthProviders && } {hasPasskey && }
)} {enableSeparator && } {project.config.credentialEnabled && project.config.magicLinkEnabled ? ( {t("Email")} {t("Email & Password")} {props.type === 'sign-up' ? : } ) : project.config.credentialEnabled ? ( props.type === 'sign-up' ? : ) : project.config.magicLinkEnabled ? ( ) : !(hasOAuthProviders || hasPasskey) ? ( // Only reachable on the sign-up page of a passkey-only project: the project is configured // correctly, there is just no way to create an account with a passkey alone. {t("New accounts can't be created with the sign-in methods enabled for this app. Sign in instead.")} ) : null} {props.extraInfo && (
{props.extraInfo}
)}
); }