Skip to Content
FrontendBundlesCRUDUtility Functions

Utility Functions

The CRUD bundle provides a comprehensive set of utility functions and custom hooks that power the CRUD operations, validation, API calls, and more.


Core Functions

formatEntityName

Formats entity names for display and API endpoints.

const formatEntityName = ( name: string, options?: { plural?: boolean; capitalize?: boolean; separator?: string; } ) => { // Returns formatted entity name }; // Usage formatEntityName("user_profile", { plural: true, capitalize: true }); // "User Profiles"

getTenant / getTenantBackend

Retrieves tenant information for multi-tenant applications.

const getTenant = () => { // Client-side tenant retrieval }; const getTenantBackend = (request: Request) => { // Server-side tenant retrieval };

validationSchema

Generates Zod validation schemas from field configurations.

const validationSchema = (fields: FilterField[]) => { return z.object({ // Dynamic schema generation based on field types and validation rules }); }; // Usage const schema = validationSchema(userFormFields); const form = useForm({ resolver: zodResolver(schema), });

verifyUser

Verifies user authentication and permissions.

const verifyUser = async (options: { token: string; // JWT token requiredRoles?: string[]; // Required roles for access requiredPermissions?: string[]; // Required permissions }) => { return { valid: boolean; // Token is valid user: User | null; // User data if valid roles: string[]; // User roles permissions: string[]; // User permissions }; }; // Usage (Server-side) export async function getServerSideProps(context) { const token = context.req.cookies.token; const verification = await verifyUser({ token, requiredRoles: ['admin', 'manager'] }); if (!verification.valid) { return { redirect: { destination: '/login', permanent: false } }; } return { props: { user: verification.user } }; }

CallAPI

Centralized API calling utility with error handling and caching.

const CallAPI = async (options: { method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'; url: string; data?: any; tenant: string; csrfJwt?: string; cache?: boolean; // Enable caching (GET only) timeout?: number; // Request timeout in ms }) => { return { data: any; // Response data status: number; // HTTP status code headers: Headers; // Response headers }; };

Core Functions Summary

FunctionPurposeKey Features
formatEntityNameFormat entity namesPluralization, capitalization
getTenantGet tenant info (client)Multi-tenant support
getTenantBackendGet tenant info (server)Request-based tenant
validationSchemaGenerate Zod schemasDynamic from field config
verifyUserVerify authenticationRoles, permissions check
CallAPIAPI callsCaching, error handling
createLoggerCreate scoped loggersinfo, warn, error, debug
importEntitySchemaValidate importsBulk data validation
getUpdatedFormFieldsUpdate field configsConditional fields

Custom Hooks

useActionButtons

Manages action button states and handlers.

const useActionButtons = (options: { resource: string; entityId?: number; defaultActions?: string[]; customActions?: ActionButtonConfig[]; }) => { return { actions: ActionButtonConfig[]; handleAction: (actionType: string, id?: number) => void; loading: boolean; deleting: boolean; duplicating: boolean; }; }; // Usage function EntityActions({ entity }: { entity: any }) { const { actions, handleAction, deleting } = useActionButtons({ resource: 'users', entityId: entity.id, defaultActions: ['edit', 'delete', 'duplicate'] }); return ( <div className="flex gap-2"> {actions.map(action => ( <Button key={action.type} onClick={() => handleAction(action.type, entity.id)} disabled={deleting} > {action.label} </Button> ))} </div> ); }

useFormValues

Handles form value management with persistence.

const useFormValues = (options: { formKey: string; defaultValues?: any; persistToKVS?: boolean; }) => { return { values: any; setValue: (key: string, value: any) => void; resetValues: () => void; isDirty: boolean; }; };

useKVS

Key-Value Store integration for user preferences and form state.

const useKVS = (options?: { key?: string; defaultValue?: any; }) => { return { kvs: KVS[]; createKVS: (data: any) => Promise<KVS>; updateKVS: (id: string, data: any) => Promise<KVS>; deleteKVS: (id: string) => Promise<void>; loading: boolean; creatingKVS: boolean; }; }; // Usage function UserPreferences() { const { kvs, createKVS, updateKVS, loading } = useKVS({ key: 'user_preferences' }); const savePreference = async (key: string, value: any) => { const existing = kvs.find(item => item.key === key); if (existing) { await updateKVS(existing.id, { value }); } else { await createKVS({ key, value }); } }; return ( <div> {/* Preferences UI */} </div> ); }

useTreeView

Tree view navigation and state management.

const useTreeView = (options: { data: TreeNode[]; defaultExpanded?: string[]; }) => { return { expandedNodes: string[]; toggleNode: (nodeId: string) => void; expandAll: () => void; collapseAll: () => void; selectedNode: string | null; selectNode: (nodeId: string) => void; }; };

useScrollToError

Automatically scrolls to the first form validation error.

const useScrollToError = (options?: { offset?: number; // Scroll offset from top behavior?: 'smooth' | 'auto'; // Scroll behavior }) => { return { scrollToError: (errors: FieldErrors) => void; scrollToField: (fieldName: string) => void; }; }; // Usage function FormWithScrollToError() { const form = useForm(); const { scrollToError } = useScrollToError({ offset: 100 }); const onError = (errors: FieldErrors) => { scrollToError(errors); }; return ( <form onSubmit={form.handleSubmit(onSubmit, onError)}> {/* Form fields */} </form> ); }

useDefaultFormValues

Initializes and manages default form values from various sources.

const useDefaultFormValues = (options: { resource: string; // API resource name entityId?: string | number; // Entity ID for edit mode defaultValues?: any; // Fallback default values kvsKey?: string; // KVS key for persisted values }) => { return { defaultValues: any; // Resolved default values loading: boolean; // Loading state error: Error | null; // Error if fetching failed refetch: () => Promise<void>; // Refetch values }; }; // Usage function EditUserForm({ userId }: { userId: string }) { const { defaultValues, loading } = useDefaultFormValues({ resource: 'users', entityId: userId, defaultValues: { status: 'active' } }); const form = useForm({ defaultValues, }); if (loading) return <Skeleton />; return ( <form onSubmit={form.handleSubmit(onSubmit)}> {/* Form fields */} </form> ); }

Custom Hooks Summary

HookPurposeKey Returns
useActionButtonsAction button managementactions, handleAction, loading
useFormValuesForm value persistencevalues, setValue, isDirty
useKVSKey-Value Store integrationkvs, createKVS, updateKVS
useTreeViewTree navigationexpandedNodes, toggleNode
useScrollToErrorForm error scrollingscrollToError, scrollToField
useDefaultFormValuesDefault value initializationdefaultValues, loading

Higher-Order Components

getPageConfig

HOC for page configuration and metadata.

const getPageConfig = (config: PageConfig) => { return <P extends object>(Component: React.ComponentType<P>) => { return (props: P) => { // Apply page configuration return <Component {...props} />; }; }; }; // Usage const UserListPage = getPageConfig({ title: "Users", breadcrumbs: ["Dashboard", "Users"], permissions: ["users.read"], })(UsersList);

Validation Utilities

importEntitySchema

Schema validation for data imports.

const importEntitySchema = (entityType: string, data: any[]) => { // Validates import data against entity schema return { valid: any[]; invalid: any[]; errors: ValidationError[]; }; };

getUpdatedFormFields

Updates form field configurations based on conditions.

const getUpdatedFormFields = ( fields: FilterField[], formValues: any, conditions: FieldCondition[] ) => { // Returns updated field configurations return FilterField[]; };

Logger Utilities

createLogger

Creates scoped loggers for debugging.

const createLogger = (scope: string) => { return { info: (message: string, data?: any) => void; warn: (message: string, data?: any) => void; error: (message: string, error?: Error) => void; debug: (message: string, data?: any) => void; }; }; // Usage const logger = createLogger('UserService'); logger.info('Fetching users', { page: 1, limit: 25 }); logger.error('Failed to create user', error);

Complete Usage Example

import { CallAPI, validationSchema, createLogger, useFormValues, useKVS } from "@phpcreation/frontend-crud-react-nextjs-bundle/utils"; const logger = createLogger('UserForm'); function UserForm({ userId }: { userId?: string }) { const { kvs, createKVS, updateKVS } = useKVS({ key: 'user_form_preferences' }); const { values, setValue, resetValues, isDirty } = useFormValues({ formKey: 'user_form', persistToKVS: true, defaultValues: { name: '', email: '', status: 'active' } }); const form = useForm({ resolver: zodResolver(validationSchema(userFormFields)), defaultValues: values }); const onSubmit = async (data: any) => { try { logger.info('Submitting user form', { userId, data }); const response = await CallAPI({ method: userId ? 'PATCH' : 'POST', url: userId ? `/api/users/${userId}` : '/api/users', data, tenant: getTenant(), csrfJwt: getCsrfToken() }); logger.info('User saved successfully', response.data); toast.success('User saved successfully!'); if (!userId) { resetValues(); } } catch (error) { logger.error('Failed to save user', error); toast.error('Failed to save user'); } }; return ( <form onSubmit={form.handleSubmit(onSubmit)}> {/* Form fields */} <Button type="submit" disabled={!isDirty}> {userId ? "Update" : "Create"} User </Button> </form> ); }

Best Practices

Utility Usage - Always use the provided utilities instead of direct API

calls - Implement proper error handling with loggers - Use validation schemas for all form submissions - Leverage KVS for user preferences and form persistence

Performance - Memoize expensive utility calls - Use proper dependency

arrays in custom hooks - Implement proper cleanup in useEffect hooks - Avoid creating utilities inside render functions

Last updated on