pagamio-frontend-commons-lib
v0.8.172
Published
Pagamio library for Frontend reusable components like the form engine and table container
Downloads
1,162
Maintainers
Readme
pagamio-frontend-commons-library
A reusable React component library styled with Tailwind CSS, designed to streamline your frontend development process.
:rocket: Features
- A Form Engine: A package with all possible input components that can be used to build a form. This helps render forms in your project.
- Reusable Components: A collection of customizable components like DateInput, TextInput, and more.
- Tailwind CSS: Utility-first CSS framework for rapid UI development.
- TypeScript Support: Fully typed components for enhanced developer experience.
- Flexible Imports: Import components individually or collectively.
- Peer Dependencies: Ensures compatibility with React and React DOM versions.
- API Client: Robust API integration with authentication support, SWR data fetching, and mocking capabilities.
:package: Installation
Install the library via Yarn:
yarn add pagamio-frontend-commons-lib:art: Usage
Importing Styles
Import the compiled Tailwind CSS styles into your application's entry point (e.g., index.js or App.js):
import 'pagamio-frontend-commons-lib/lib/styles.css';Importing Components
You can import components individually or collectively.
a. Named Imports
Import multiple components from the main entry point:
import { DateInput, TextInput } from 'pagamio-frontend-commons-lib';
:shield: RBAC Module
The Role-Based Access Control (RBAC) module provides a flexible system for implementing permission-based access control in your applications.
Features
- Generic TypeScript implementation that works with any permission system
- Flexible configuration that can be initialized once at application startup
- Pure utility functions that can be used anywhere in your application
- React hooks for convenient use in components
- Support for role-based and permission-based access control
- Type-safe API with generics for custom user and permission types
Core Components
Initialization
Initialize the RBAC system with your application-specific configuration:
import { initializeRBAC } from 'pagamio-frontend-commons-lib/rbac';
import { Permissions } from './permissions';
// Define your permission enum
enum Permissions {
ALL = 'ALL',
VIEW_DASHBOARD = 'VIEW_DASHBOARD',
MANAGE_USERS = 'MANAGE_USERS',
// ... other permissions
}
// Define your RBAC configuration
const rbacConfig = {
'ADMIN': [Permissions.ALL],
'MANAGER': [Permissions.VIEW_DASHBOARD, Permissions.MANAGE_USERS],
'USER': [Permissions.VIEW_DASHBOARD],
};
// Initialize RBAC with your configuration
initializeRBAC({
rbacConfig,
allPermissionValue: Permissions.ALL,
allPermissions: Object.values(Permissions),
roleKey: 'roleName' // The property in your user object that contains the role
});Utility Functions
Use the RBAC utility functions to check permissions and roles:
import { hasPermission, hasRole, getUserPermissions } from 'pagamio-frontend-commons-lib/rbac';
import { Permissions } from './permissions';
// Check if a user has a specific permission
const canViewDashboard = hasPermission(user, Permissions.VIEW_DASHBOARD);
// Check if a user has a specific role
const isAdmin = hasRole(user, 'ADMIN');
// Get all permissions for a user
const userPermissions = getUserPermissions(user);React Hooks
Use the RBAC hooks in your React components:
import { useHasPermission, useHasRole } from 'pagamio-frontend-commons-lib/rbac';
import { useAuth } from 'pagamio-frontend-commons-lib/auth';
import { Permissions } from './permissions';
function Dashboard() {
const { user } = useAuth();
const canManageUsers = useHasPermission(user, Permissions.MANAGE_USERS);
return (
<div>
<h1>Dashboard</h1>
{canManageUsers && <UserManagement />}
</div>
);
}:globe_with_meridians: API Module
The API module provides a robust system for making API requests with built-in authentication, caching, and error handling capabilities.
Features
- TypeScript support with generic types for type-safe API operations
- Authentication integration with token management
- SWR integration for data fetching, caching, and revalidation
- Support for RESTful operations (GET, POST, PUT, PATCH, DELETE)
- Pagination support for large datasets
- Configurable retry logic and timeout handling
- Request and response interceptors
- Error handling and logging
- Mock API support for testing and development
Core Components
ApiClient
The ApiClient class provides a flexible HTTP client with authentication support, retry logic, and error handling.
import { ApiClient, createApiClient } from 'pagamio-frontend-commons-lib';
// Create a client with your custom auth configuration
const apiClient = createApiClient<MyAuthConfig>({
baseURL: 'https://api.example.com',
tokenManager: tokenManager,
defaultHeaders: {
'Content-Type': 'application/json',
},
timeout: 5000,
retries: 2,
});
// Making API calls
const data = await apiClient.get<MyResponseType>('/users');
const newUser = await apiClient.post<UserResponse>('/users', { name: 'John', email: '[email protected]' });SWR Integration
The API module includes SWR hooks for efficient data fetching with caching, revalidation, and focus refetching.
import { useApiSWR, usePaginatedApiSWR } from 'pagamio-frontend-commons-lib';
// Basic data fetching with SWR
function UserProfile({ userId }) {
const { data, error, isLoading } = useApiSWR<UserData>(`/users/${userId}`);
if (isLoading) return <div>Loading
...
</div>;
if (error) return <div>Error
loading
user
data < /div>;
return <div>Hello, { data.name }! < /div>;
}
// Paginated data fetching
function UserList() {
const { data, error, isLoading } = usePaginatedApiSWR<User>('/users', {
params: { page: 0, size: 10 }
});
if (isLoading) return <div>Loading
users
...
</div>;
return (
<div>
<h2>Users({ data.totalElements }) < /h2>
< ul >
{
data.content.map(user => <li key = { user.id } > { user.name } < /li>)}
< /ul>
< /div>
);
}API Context Provider
The ApiProvider component makes the API client available throughout your application.
import { ApiProvider, createApiClient } from 'pagamio-frontend-commons-lib';
// Create API client
const apiClient = createApiClient<MyAuthConfig>({
baseURL: 'https://api.example.com',
tokenManager: tokenManager,
});
// Wrap your application with the provider
function App() {
return (
<ApiProvider apiClient = { apiClient } >
<YourApplication / >
</ApiProvider>
);
}API Mutations
The API module provides hooks for performing mutations (create, update, delete operations).
import { useApiMutation, useApiSWRWithMutation } from 'pagamio-frontend-commons-lib';
// Using the mutation hook
function CreateUserForm() {
const mutation = useApiMutation<UserResponse>();
const handleSubmit = async (userData) => {
try {
const newUser = await mutation.post('/users', userData);
alert(`User ${newUser.name} created successfully!`);
} catch (error) {
console.error('Failed to create user:', error);
}
};
return <form onSubmit = { handleSubmit } > {/* form fields */ } < /form>;
}
// Combined SWR and mutation hook
function EditUserProfile({ userId }) {
const { data, error, isLoading, mutate } = useApiSWRWithMutation<UserData>(
`/users/${userId}`
);
const handleUpdate = async (updatedData) => {
try {
await mutate.patch(`/users/${userId}`, updatedData);
alert('Profile updated successfully!');
} catch (error) {
console.error('Failed to update profile:', error);
}
};
if (isLoading) return <div>Loading
...
</div>;
return <ProfileForm user = { data }
onSubmit = { handleUpdate }
/>;
}Mocking API Requests
The API module supports mocking API requests for testing and development.
import { ApiProvider, createApiClient, MockConfig } from 'pagamio-frontend-commons-lib';
// Define mock configurations
const mockConfig: MockConfig[] = [
{
path: '/users',
method: 'GET',
response: [
{ id: 1, name: 'John Doe', email: '[email protected]' },
{ id: 2, name: 'Jane Smith', email: '[email protected]' }
]
},
{
path: '/users',
method: 'POST',
params: { name: 'Alice', email: '[email protected]' },
response: { id: 3, name: 'Alice', email: '[email protected]' }
}
];
// Enable mocking in the provider
function TestApp() {
return (
<ApiProvider
apiClient = { apiClient }
mocked = { true }
mockConfig = { mockConfig } >
<YourApplication / >
</ApiProvider>
)
;
}Authentication Integration
The API client integrates with the token manager for authentication.
import { createApiClient, createTokenManager } from 'pagamio-frontend-commons-lib';
// Create a token manager
const tokenManager = createTokenManager<MyAuthConfig>({
baseUrl: 'https://api.example.com',
refreshEndpoint: '/auth/refresh',
cookieOptions: {
secure: true,
sameSite: 'strict'
}
});
// Create API client with authentication
const apiClient = createApiClient<MyAuthConfig>({
baseURL: 'https://api.example.com',
tokenManager: tokenManager,
onUnauthorized: () => {
// Handle unauthorized access (e.g., redirect to login)
window.location.href = '/login';
}
});Advanced Configuration
Custom Request/Response Handling
const apiClient = createApiClient<MyAuthConfig>({
baseURL: 'https://api.example.com',
tokenManager: tokenManager,
onRequest: async (config) => {
// Add custom headers or modify request configuration
config.headers = {
...config.headers,
'X-Custom-Header': 'CustomValue'
};
return config;
},
onResponse: async (response, data) => {
// Transform or process response data
return data.results || data;
},
onError: async (error) => {
// Log or handle errors
console.error(`API Error (${error.status}):`, error.message);
}
});Pagination and Filtering
// Custom pagination params
const { data } = useApiSWR<UserListResponse>('/users', {
params: {
page: 0,
size: 25,
sortBy: 'createdAt',
sortDir: 'desc',
name: 'John'
}
});TypeScript Integration
The API module is fully typed with TypeScript, providing type safety and better developer experience.
// Define your auth configuration
interface MyAuthConfig extends CustomAuthConfig {
UserInfo: {
id: string;
username: string;
email: string;
roles: string[];
};
TokenInfo: {
token: string;
expiresIn: number;
};
Credentials: {
username: string;
password: string;
};
}
// Use your custom types with the API client
const apiClient = createApiClient<MyAuthConfig>({
baseURL: 'https://api.example.com',
tokenManager: tokenManager
});
// Type-safe API calls
interface Product {
id: string;
name: string;
price: number;
}
const { data: products } = useApiSWR<Product[]>('/products');Best Practices
Centralize API Configuration: Create a central API configuration file that sets up the API client and exports hooks for use throughout your application.
Use TypeScript: Leverage TypeScript definitions for type-safe API calls and better developer experience.
Handle Loading and Error States: Always handle loading and error states in your components when using API hooks.
Implement Proper Error Handling: Configure error handling with the
onErrorcallback and handle errors appropriately in your UI.Use Mocking for Development: Enable mocking during development to work without a backend or to test specific scenarios.
Optimize Cache Invalidation: Use SWR's
mutatefunction to keep your data fresh and update the UI after mutations.Set Appropriate Timeouts: Configure request timeouts based on the expected response time of your API endpoints.
:globe_with_meridians: Translations
The library provides a complete translation system that supports internationalization for your applications.
Languages Currently Supported
The library comes with built-in support for the following languages:
- English (en)
- Spanish (es)
- French (fr)
- Portuguese (pt)
Implementation Guide
Follow these steps to implement translations in your project:
1. Setup Translation Provider
Wrap your application with the TranslationProvider:
import { TranslationProvider } from 'pagamio-frontend-commons-lib';
function App() {
return (
<TranslationProvider
defaultLocale="en"
loadPath="/translations" // Path to your translation files
>
<YourApplicationComponents />
</TranslationProvider>
);
}Alternatively, if you're using the AppLayout component:
import { AppLayout } from 'pagamio-frontend-commons-lib';
function App() {
return (
<AppLayout
// other props...
enableTranslations={true}
translationConfig={{
defaultLocale: 'en',
loadPath: '/translations',
}}
>
{/* Your content */}
</AppLayout>
);
}2. Create Translation Files
Create JSON files for each language in your project:
/public
/translations
en.json
es.json
fr.json
pt.jsonExample of a translation file (en.json):
{
"common": {
"save": "Save",
"cancel": "Cancel",
"submit": "Submit"
},
"auth": {
"login": "Login",
"register": "Register",
"forgotPassword": "Forgot Password?"
}
}3. Add i18next-scanner Config
Create an i18next-scanner.config.js in your project root:
module.exports = {
input: ['src/**/*.{js,jsx,ts,tsx}', '!src/**/*.test.{js,jsx,ts,tsx}', '!**/node_modules/**'],
output: './public/translations/',
options: {
debug: true,
func: {
list: ['t', 'tLib'],
extensions: ['.js', '.jsx', '.ts', '.tsx'],
},
lngs: ['en', 'es', 'fr', 'pt'],
defaultLng: 'en',
defaultValue: function(lng, ns, key) {
return key;
},
resource: {
loadPath: 'public/translations/{{lng}}.json',
savePath: '{{lng}}.json',
jsonIndent: 2,
lineEnding: '\n',
},
removeUnusedKeys: false,
nsSeparator: false,
keySeparator: '.',
},
};4. Add Extraction Script to package.json
"scripts": {
"extract-translations": "i18next-scanner --config i18next-scanner.config.js 'src/**/*.{js,jsx,ts,tsx}'"
}5. Install Required Dependencies
Install the necessary dev dependencies:
yarn add -D i18next-scannerOr if you're using npm:
npm install --save-dev i18next-scanner6. Use Translations in Components
import { useTranslation } from 'pagamio-frontend-commons-lib';
function YourComponent() {
const { t } = useTranslation();
return (
<div>
<h1>{t('common.title', 'Default Title')}</h1>
<p>{t('common.description', 'This is a default description')}</p>
<button>{t('common.save', 'Save')}</button>
</div>
);
}7. Use Library Translations
The library provides common translations for frequently used UI elements:
import { useLibTranslations } from 'pagamio-frontend-commons-lib';
function YourComponent() {
const { tLib } = useLibTranslations();
return (
<div>
<button>{tLib('save')}</button>
<button>{tLib('cancel')}</button>
<button>{tLib('submit')}</button>
</div>
);
}8. Add Locale Switcher
Add a language switcher to allow users to change the application language:
import { LocaleSwitcher } from 'pagamio-frontend-commons-lib';
function Header() {
return (
<header>
<nav>
{/* Your other navigation elements */}
<LocaleSwitcher />
</nav>
</header>
);
}You can customize language display names:
<LocaleSwitcher
localeNames={{
en: 'English',
es: 'Español',
fr: 'Français',
pt: 'Português'
}}
/>9. Run the Extraction Script
Extract all translation keys from your application:
yarn extract-translationsThis will scan your code for translation keys and update your translation files.
Advanced Configuration
Custom Locale Detector
You can configure the translation system to detect the browser's locale:
import { TranslationProvider, detectBrowserLocale } from 'pagamio-frontend-commons-lib';
function App() {
const browserLocale = detectBrowserLocale(); // Returns 'en', 'es', etc.
return (
<TranslationProvider
defaultLocale={browserLocale}
loadPath="/translations"
>
<YourApplicationComponents />
</TranslationProvider>
);
}Direct Loading of Translation Data
Instead of loading translations from files, you can provide them directly:
import { TranslationProvider } from 'pagamio-frontend-commons-lib';
const translations = [
{
locale: 'en',
messages: {
common: {
save: 'Save',
cancel: 'Cancel'
}
}
},
{
locale: 'es',
messages: {
common: {
save: 'Guardar',
cancel: 'Cancelar'
}
}
}
];
function App() {
return (
<TranslationProvider
defaultLocale="en"
localeData={translations}
>
<YourApplicationComponents />
</TranslationProvider>
);
}