UNPKG

@heymarco/next-auth

Version:

A complete authentication solution for web applications.

176 lines (175 loc) 7.43 kB
'use client'; // react: import { // react: default as React, // hooks: useRef, } from 'react'; // reusable-ui core: import { // react helper hooks: useEvent, useMergeEvents, } from '@reusable-ui/core'; // a set of reusable-ui packages which are responsible for building any component // reusable-ui components: import { ButtonIcon, // layout-components: CardBody, // status-components: Busy, ModalCard, useDialogMessage, } from '@reusable-ui/components'; // a set of official Reusable-UI components // internal components: import { // react components: ButtonWithBusy, } from './ButtonWithBusy.js'; import { // react components: ButtonWithSignIn, } from './ButtonWithSignIn.js'; import { // react components: AlternateSignInSeparator, } from './AlternateSignInSeparator.js'; import { FieldUsernameOrEmail, } from './FieldUsernameOrEmail.js'; import { FieldPassword, } from './FieldPassword.js'; // internals: import { // states: useSignInState, } from './states/signInState.js'; import { // handlers: handlePreventSubmit, } from './utilities.js'; export const TabSignIn = (props) => { // rest props: const { // auths: providers = [], // components: signInTitleComponent = React.createElement("h1", null, "Sign In"), usernameOrEmailInputComponent, passwordInputComponent, signInButtonComponent = React.createElement(ButtonWithBusy, { busyType: 'credentials', buttonComponent: React.createElement(ButtonIcon, { icon: 'login' }) }), signInWithButtonComponent = ((oAuthProvider) => React.createElement(ButtonWithBusy, { busyType: oAuthProvider, buttonComponent: React.createElement(ButtonIcon, { icon: oAuthProvider }) })), alternateSignInSeparatorComponent = React.createElement(AlternateSignInSeparator, null), emailValidationDialogComponent = React.createElement(ModalCard, { theme: 'primary', backdropStyle: 'static', inheritEnabled: false }), } = props; // states: const { // states: isSignInSection, emailVerified, // fields & validations: formRef, // actions: doSignIn, doSignInWith, // utilities: resolveProviderName } = useSignInState(); // handlers: const signInButtonHandleClickInternal = useEvent((event) => { // conditions: if (event.defaultPrevented) return; // the event was already handled by user => nothing to do event.preventDefault(); // actions: doSignIn(); }); const signInButtonHandleClick = useMergeEvents( // preserves the original `onClick` from `signInButtonComponent`: signInButtonComponent.props.onClick, // actions: signInButtonHandleClickInternal); // dialogs: const { showDialog, } = useDialogMessage(); // effects: const shouldEmailValidationDialogShown = (!!emailValidationDialogComponent // if no <Dialog> defined => nothing to display && (emailVerified === null) // if already verified => no need to display the <Dialog> ); const shownEmailValidationDialogRef = useRef(null); // initially no <Dialog> was shown if ((!!shownEmailValidationDialogRef.current) !== shouldEmailValidationDialogShown) { // detect changes // close prev shown <Dialog> (if any): shownEmailValidationDialogRef.current?.closeDialog(null); // show a new <Dialog> (if needed): if (emailValidationDialogComponent && shouldEmailValidationDialogShown) { shownEmailValidationDialogRef.current = showDialog(React.cloneElement(emailValidationDialogComponent, // props: { // global stackable: viewport: emailValidationDialogComponent.props.viewport ?? formRef, }, // children: (emailValidationDialogComponent.props.children ?? React.createElement(CardBody, null, React.createElement("p", null, React.createElement(Busy, null), "\u00A0Validating email confirmation token..."))))); } // if } // if // jsx: return (React.createElement("form", { // refs: ref: isSignInSection ? formRef : undefined, // validations: noValidate: true, // handlers: onSubmit: handlePreventSubmit }, React.cloneElement(signInTitleComponent, // props: { // classes: className: signInTitleComponent.props.className ?? 'signInTitle', }), React.createElement(FieldUsernameOrEmail // states: , { // states: isActiveSection: isSignInSection, // components: usernameOrEmailInputComponent: usernameOrEmailInputComponent }), React.createElement(FieldPassword // behaviors: , { // behaviors: isPasswordEntry: false, // states: isActiveSection: isSignInSection, isActionApplied: false, // components: passwordInputComponent: passwordInputComponent, passwordTooltipComponent: null }), React.cloneElement(signInButtonComponent, // props: { // actions: type: signInButtonComponent.props.type ?? 'submit', // classes: className: signInButtonComponent.props.className ?? 'doSignIn credentials', // handlers: onClick: signInButtonHandleClick, }, // children: signInButtonComponent.props.children ?? 'Sign In'), !!providers.length && React.createElement(React.Fragment, null, React.cloneElement(alternateSignInSeparatorComponent, // props: { // classes: className: alternateSignInSeparatorComponent.props.className ?? 'signinSeparator', }), React.createElement("div", { className: 'signinGroup' }, providers.map((providerType) => { const signInWithProviderButtonComponent = ((typeof (signInWithButtonComponent) === 'function') ? signInWithButtonComponent(providerType) : signInWithButtonComponent); // jsx: return (React.createElement(ButtonWithSignIn // identifiers: , { // identifiers: key: providerType, // auths: providerType: providerType, // components: buttonComponent: /* <SignInWithProviderButton> */ React.cloneElement(signInWithProviderButtonComponent, // props: { // identifiers: key: providerType, // actions: type: signInWithProviderButtonComponent.props.type ?? 'submit', // classes: className: signInWithProviderButtonComponent.props.className ?? `doSignIn ${providerType}`, }, // children: signInWithProviderButtonComponent.props.children ?? React.createElement(React.Fragment, null, "Sign In with ", resolveProviderName(providerType))), // handlers: onSignInWith: doSignInWith })); }))))); };