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
JavaScript
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;