UNPKG

pagamio-frontend-commons-lib

Version:

Pagamio library for Frontend reusable components like the form engine and table container

116 lines (115 loc) 5.32 kB
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; /** * Generic Login Page component that works with different authentication configurations. * Provides a customizable login interface with support for different branding and text options. * * @template T - Type extending CustomAuthConfig that defines the shape of authentication data * * @example * ```tsx * // Usage with Pagamio configuration * <PagamioLoginPage<PagamioAuthConfig> * logo={{ * src: "/logo.svg", * alt: "Company Logo", * width: 280, * height: 250 * }} * onLoginSuccess={(response) => { * // Handle successful login * }} * /> * ``` */ import { useRef, useState } from 'react'; import { useToast } from '../../context'; import { FormEngine } from '../../form-engine'; import { AuthenticatorFactory } from '../authenticators'; import { useAuth } from '../context'; import { createFormSubmissionHandler } from './AuthFormUtils'; import { AuthPageLayout } from './AuthPageLayout'; export const loginPageDefaultText = { welcomeTitle: 'Welcome Back!', welcomeSubtitle: 'Sign in to your account to continue', usernameLabel: 'Username', passwordLabel: 'Password', rememberMeLabel: 'Remember me', loginButtonLabel: 'Login', loadingButtonLabel: 'Logging in...', forgotPasswordLabel: 'Forgot Password?', createAccountLabel: 'Create Account', }; /** * Generic Login Page component * @template T - Authentication configuration type */ export function PagamioLoginPage({ logo, text = loginPageDefaultText, appLabel, onForgotPassword, onLoginSuccess, onLoginError, hasCreateAccount = false, createAccountRoute, onCreateAccount, transformLoginData, authenticatorType, className = '', }) { const { login, error: authError } = useAuth(); const { addToast } = useToast(); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const formRef = useRef(); const loginFields = [ { name: 'username', label: text.usernameLabel, type: 'text', placeholder: 'Enter username', gridSpan: 12, validation: { required: 'Username is required', validate: (value) => !/\s/.test(value) || 'Username should not contain spaces', }, }, { name: 'password', label: text.passwordLabel, type: 'password', placeholder: 'Enter password', gridSpan: 12, validation: { required: 'Password is required', }, }, { name: 'rememberMe', label: text.rememberMeLabel, type: 'checkbox', gridSpan: 12, }, ]; const handleSubmit = createFormSubmissionHandler({ setIsLoading, setError, addToast, formRef, onSuccess: (response) => onLoginSuccess?.(response), onError: onLoginError, }, async (data) => { // Get the appropriate authenticator processor from the factory const authenticator = AuthenticatorFactory.getProcessor(authenticatorType); // Prepare credentials data let credentials; if (transformLoginData) { // Use the custom transform function if provided credentials = transformLoginData(data); } else { // Default behavior - extract username and password const { username, password } = data; credentials = { username, password }; } // Process the login with the selected authenticator return authenticator.processLogin(credentials, data.rememberMe ?? false, login); }, 'Logged in successfully', 'Login failed. Please check your credentials and try again.'); const handleCreateAccount = () => { if (onCreateAccount) { onCreateAccount(); } else if (createAccountRoute) { window.location.href = createAccountRoute; } }; return (_jsx(AuthPageLayout, { appLabel: appLabel, title: text.welcomeTitle, subtitle: text.welcomeSubtitle, errorMessage: error ?? authError?.message, logo: logo, className: className, horizontal: false, children: _jsxs("div", { className: "mt-8", children: [_jsx(FormEngine, { fields: loginFields, onSubmit: handleSubmit, layout: "vertical", className: "mb-0 px-0", submitButtonClass: "w-full", submitButtonText: isLoading ? text.loadingButtonLabel : text.loginButtonLabel, onCancel: () => { }, showCancelButton: false, showSubmittingText: false, formRef: formRef }), _jsxs("div", { className: "flex items-center justify-center gap-x-4 mt-4", children: [onForgotPassword && (_jsx("button", { type: "button", onClick: onForgotPassword, className: "text-sm text-primary-500 hover:underline dark:text-primary-500", children: text.forgotPasswordLabel })), hasCreateAccount && (_jsxs(_Fragment, { children: [onForgotPassword && _jsx("span", { className: "text-gray-500", children: "|" }), _jsx("button", { type: "button", onClick: handleCreateAccount, className: "text-sm text-primary-500 hover:underline dark:text-primary-500", children: text.createAccountLabel })] }))] })] }) })); } export default PagamioLoginPage;