import { useCurrentOrganisation } from '@documenso/lib/client-only/providers/organisation'; import { useSession } from '@documenso/lib/client-only/providers/session'; import { DOCUMENSO_CLOUD_ENTERPRISE_CTA_URL } from '@documenso/lib/constants/app'; import { Trans } from '@lingui/react/macro'; import { AnimatePresence, motion, useReducedMotion } from 'framer-motion'; import { FingerprintIcon } from 'lucide-react'; import type { ReactNode } from 'react'; import { EASE, POP, SPRING } from './motion'; import { SettingsUpsellCard } from './settings-upsell-card'; import { useTimedCycle } from './use-timed-cycle'; export const SsoPortalUpsell = () => { const isReducedMotion = useReducedMotion(); const sceneIndex = useTimedCycle(SSO_SCENE_DURATIONS_MS); return ( Enterprise} title={Unlock the Organisation SSO Portal} description={ Give your members a dedicated single sign-on portal. The SSO portal is available on the Enterprise plan. } features={[ Works with any OIDC provider — Okta, Entra ID, Google and more, Accounts are automatically added to your organisation on sign-in, Restrict sign-ins by email domain and choose the default role, ]} ctaLabel={Contact Sales} ctaTo={DOCUMENSO_CLOUD_ENTERPRISE_CTA_URL} ctaExternal preview={
{sceneIndex === 0 && } {sceneIndex === 1 && } {sceneIndex === 2 && }
} /> ); }; /** * Absolute-positioned panel each scene renders in, handling the shared * slide-and-fade transition between scenes. */ const ScenePanel = ({ children }: { children: ReactNode }) => { return ( {children} ); }; /** * Scene 1: the organisation's SSO portal, with a timed faux press on the * "Continue with SSO" button (cursor flies in, button dips, sheen sweeps). * * When `isStatic` is set (reduced motion) every element renders with * `initial={false}`, skipping entrance and press animations. */ const PortalScene = ({ isStatic }: { isStatic: boolean }) => { const organisation = useCurrentOrganisation(); const rise = (delay: number) => ({ initial: isStatic ? false : { y: 10, opacity: 0 }, animate: { y: 0, opacity: 1 }, transition: { ...SPRING, delay }, }); return (
{([...organisation.name][0] ?? 'D').toUpperCase()}
Welcome to {organisation.name} Single sign-on
Continue with SSO
); }; /** * Scene 2: redirecting to the identity provider, with a rotating ring around * a fingerprint tile and a filling progress bar. */ const RedirectScene = () => { return (
Redirecting to your identity provider
); }; /** * Scene 3: signed in, with an expanding pulse ring, a popping green circle, * a drawn checkmark and the signed-in member's email. */ const SuccessScene = () => { const { user } = useSession(); return (
Signed in {user.email}
); }; /** * Milliseconds each scene is shown before advancing: portal, redirect, * success. */ const SSO_SCENE_DURATIONS_MS = [3000, 2500, 3000];