Pagamio library for Frontend reusable components like the form engine and table container
npm install @pagamio/frontend-commons-libA reusable React component library styled with Tailwind CSS, designed to streamline your frontend development process.
- 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.
Install the library via Yarn:
``bash`
yarn add pagamio-frontend-commons-lib
- 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';
Some utilities (for example the useImageUpload hook and ImageUploader component) require an API endpoint that issues presigned upload URLs. Make sure your host application exposes the following public environment variable before using those helpers:
| Variable | Description |
| --- | --- |
| NEXT_PUBLIC_UPLOAD_URL_ENDPOINT | HTTP endpoint that returns presigned URLs for file uploads. |
`bash`.env (per app)
NEXT_PUBLIC_UPLOAD_URL_ENDPOINT=https://
This value is resolved at runtime;
The Role-Based Access Control (RBAC) module provides a flexible system for implementing permission-based access control in your applications.
- 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
#### Initialization
Initialize the RBAC system with your application-specific configuration:
`typescript
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:
`typescript
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:
`typescript
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 (
: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.
$3
- 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
$3
#### ApiClient
The
ApiClient class provides a flexible HTTP client with authentication support, retry logic, and error handling.`typescript
import { ApiClient, createApiClient } from 'pagamio-frontend-commons-lib';// Create a client with your custom auth configuration
const apiClient = createApiClient({
baseURL: 'https://api.example.com',
tokenManager: tokenManager,
defaultHeaders: {
'Content-Type': 'application/json',
},
timeout: 5000,
retries: 2,
});
// Making API calls
const data = await apiClient.get('/users');
const newUser = await apiClient.post('/users', { name: 'John', email: 'john@example.com' });
`#### SWR Integration
The API module includes SWR hooks for efficient data fetching with caching, revalidation, and focus refetching.
`typescript
import { useApiSWR, usePaginatedApiSWR } from 'pagamio-frontend-commons-lib';// Basic data fetching with SWR
function UserProfile({ userId }) {
const { data, error, isLoading } = useApiSWR(
/users/${userId}); if (isLoading) return
Loading
...
;
if (error) return Error
loading
user
data < /div>; return
Hello, { data.name }! < /div>;
}// Paginated data fetching
function UserList() {
const { data, error, isLoading } = usePaginatedApiSWR('/users', {
params: { page: 0, size: 10 }
});
if (isLoading) return
Loading
users
...
; return (
Users({ data.totalElements }) < /h2>
< ul >
{
data.content.map(user =>
{ user.name } < /li>)}
< /ul>
< /div>
);
}
`#### API Context Provider
The
ApiProvider component makes the API client available throughout your application.`typescript
import { ApiProvider, createApiClient } from 'pagamio-frontend-commons-lib';// Create API client
const apiClient = createApiClient({
baseURL: 'https://api.example.com',
tokenManager: tokenManager,
});
// Wrap your application with the provider
function App() {
return (
);
}
`#### API Mutations
The API module provides hooks for performing mutations (create, update, delete operations).
`typescript
import { useApiMutation, useApiSWRWithMutation } from 'pagamio-frontend-commons-lib';// Using the mutation hook
function CreateUserForm() {
const mutation = useApiMutation();
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
/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
Loading
...
; return onSubmit = { handleUpdate }
/>;
}
`$3
The API module supports mocking API requests for testing and development.
`typescript
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: 'john@example.com' },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' }
]
},
{
path: '/users',
method: 'POST',
params: { name: 'Alice', email: 'alice@example.com' },
response: { id: 3, name: 'Alice', email: 'alice@example.com' }
}
];
// Enable mocking in the provider
function TestApp() {
return (
apiClient = { apiClient }
mocked = { true }
mockConfig = { mockConfig } >
)
;
}
`$3
The API client integrates with the token manager for authentication.
`typescript
import { createApiClient, createTokenManager } from 'pagamio-frontend-commons-lib';// Create a token manager
const tokenManager = createTokenManager({
baseUrl: 'https://api.example.com',
refreshEndpoint: '/auth/refresh',
cookieOptions: {
secure: true,
sameSite: 'strict'
}
});
// Create API client with authentication
const apiClient = createApiClient({
baseURL: 'https://api.example.com',
tokenManager: tokenManager,
onUnauthorized: () => {
// Handle unauthorized access (e.g., redirect to login)
window.location.href = '/login';
}
});
`$3
#### Custom Request/Response Handling
`typescript
const apiClient = createApiClient({
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
`typescript
// Custom pagination params
const { data } = useApiSWR('/users', {
params: {
page: 0,
size: 25,
sortBy: 'createdAt',
sortDir: 'desc',
name: 'John'
}
});
`$3
The API module is fully typed with TypeScript, providing type safety and better developer experience.
`typescript
// 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({
baseURL: 'https://api.example.com',
tokenManager: tokenManager
});
// Type-safe API calls
interface Product {
id: string;
name: string;
price: number;
}
const { data: products } = useApiSWR('/products');
`$3
1. Centralize API Configuration: Create a central API configuration file that sets up the API client and exports
hooks for use throughout your application.
2. Use TypeScript: Leverage TypeScript definitions for type-safe API calls and better developer experience.
3. Handle Loading and Error States: Always handle loading and error states in your components when using API hooks.
4. Implement Proper Error Handling: Configure error handling with the
onError callback and handle errors
appropriately in your UI.5. Use Mocking for Development: Enable mocking during development to work without a backend or to test specific
scenarios.
6. Optimize Cache Invalidation: Use SWR's
mutate function to keep your data fresh and update the UI after
mutations.7. 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.
$3
The library comes with built-in support for the following languages:
- English (en)
- Spanish (es)
- French (fr)
- Portuguese (pt)
$3
Follow these steps to implement translations in your project:
#### 1. Setup Translation Provider
Wrap your application with the
TranslationProvider:`tsx
import { TranslationProvider } from 'pagamio-frontend-commons-lib';function App() {
return (
defaultLocale="en"
loadPath="/translations" // Path to your translation files
>
);
}
`Alternatively, if you're using the
AppLayout component:`tsx
import { AppLayout } from 'pagamio-frontend-commons-lib';function App() {
return (
// other props...
enableTranslations={true}
translationConfig={{
defaultLocale: 'en',
loadPath: '/translations',
}}
>
{/ Your content /}
);
}
`#### 2. Create Translation Files
Create JSON files for each language in your project:
`
/public
/translations
en.json
es.json
fr.json
pt.json
`Example of a translation file (
en.json):`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:`js
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
`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:
`bash
yarn add -D i18next-scanner
`Or if you're using npm:
`bash
npm install --save-dev i18next-scanner
`#### 6. Use Translations in Components
`tsx
import { useTranslation } from 'pagamio-frontend-commons-lib';function YourComponent() {
const { t } = useTranslation();
return (
{t('common.title', 'Default Title')}
{t('common.description', 'This is a default description')}
);
}
`#### 7. Use Library Translations
The library provides common translations for frequently used UI elements:
`tsx
import { useLibTranslations } from 'pagamio-frontend-commons-lib';function YourComponent() {
const { tLib } = useLibTranslations();
return (
);
}
`#### 8. Add Locale Switcher
Add a language switcher to allow users to change the application language:
`tsx
import { LocaleSwitcher } from 'pagamio-frontend-commons-lib';function Header() {
return (
);
}
`You can customize language display names:
`tsx
localeNames={{
en: 'English',
es: 'Español',
fr: 'Français',
pt: 'Português'
}}
/>
`#### 9. Run the Extraction Script
Extract all translation keys from your application:
`bash
yarn extract-translations
`This will scan your code for translation keys and update your translation files.
$3
#### Custom Locale Detector
You can configure the translation system to detect the browser's locale:
`tsx
import { TranslationProvider, detectBrowserLocale } from 'pagamio-frontend-commons-lib';function App() {
const browserLocale = detectBrowserLocale(); // Returns 'en', 'es', etc.
return (
defaultLocale={browserLocale}
loadPath="/translations"
>
);
}
`#### Direct Loading of Translation Data
Instead of loading translations from files, you can provide them directly:
`tsx
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 (
defaultLocale="en"
localeData={translations}
>
);
}
``