About Frontend
The partner-facing SPA powering all internal staff operations
🏦 Who Uses This?
Internal staff — not customers. This is used by Loan Executives, Collection Agents, Sanction Managers, Credit Executives, and Administrators of lending brands to manage the full loan workflow.
🏷️ Multi-Brand Support
The platform supports multiple lending brands simultaneously (Qualoan, PaisaPop, Salary4Sure, etc.). Every route is scoped under /:brandId/ so the same codebase serves many separate lenders.
🔐 Role-Based Interface
The entire UI changes based on the logged-in user's role. A Collection Executive sees collection queues; a Sanction Head sees approval queues. Navigation, buttons, and data all reflect permissions.
📊 Ops Dashboard
Real-time dashboards show disbursement stats, collection metrics, user performance, and geographic breakdowns. Two dashboard versions (v1, v2) serve different operational needs.
Tech Stack
Libraries, frameworks and build tools used in the frontend
🏗️ Core Framework
React 19 brings the latest features. Vite provides lightning-fast HMR and build times. TypeScript enforces strict typing across all components and API calls.
🗄️ State Management
Redux Toolkit is the single source of truth for auth state, brand config, partner user data, and user data. Slices are organized by domain.
🛣️ Routing
React Router v7 with nested routes. Brand-scoped routes pattern: /:brandId/[feature]. Protected routes wrap all authenticated pages with token validation guards.
🎨 Styling
TailwindCSS utility classes for rapid styling. Framer Motion for smooth animations and transitions. Each brand has its own color theme loaded dynamically.
📡 HTTP & API
A single Axios instance with request/response interceptors handles auth headers, token refresh on 401, error normalization, and base URL switching per brand.
📊 Data Visualization
Chart.js for bar/line/pie charts on dashboards. Recharts for React-idiomatic composable charts in collection analytics and performance views.
📄 PDF & File Handling
pdf-lib for in-browser PDF editing. PDFjs-dist for rendering PDFs. React Dropzone for drag-and-drop file uploads (documents, bank statements, payslips).
🛠️ Other Libraries
FingerprintJS for device registration. Toastify for notifications. TipTap rich-text editor for notes/comments. lodash.debounce for search inputs. dayjs for all date formatting (not date-fns — confirmed in lib/utils.ts).
🎛️ UI Utilities
@headlessui/react for accessible unstyled UI primitives (dropdowns, dialogs, switches). clsx + tailwind-merge combined into the cn() utility in lib/utils.ts for safe conditional Tailwind class merging. react-markdown for rendering markdown content in help center and notification bodies.
🔐 Google OAuth
Google OAuth is configured via the VITE_GOOGLE_CLIENT_ID environment variable. Allows partner staff to log in using their Google workspace accounts in addition to email/password.
Routing System
React Router v7 — all routes and how they're protected
brandId is extracted from the URL, used to fetch brand-specific configs, and sent with every API request.
🔓 Public Routes
| Path | Component | Purpose |
|---|---|---|
| /login | LoginPage | Email + password login for partner staff |
| /reset-password | ResetPasswordPage | Password reset via email token |
| / | Redirect | Redirects to /login if unauthenticated |
🔒 Protected Routes (require JWT + brandId)
| Path | Page | Role Required |
|---|---|---|
| /:brandId/dashboard | Dashboard V1/V2 | VIEW_DASHBOARD permission |
| /:brandId/loans | Loans List | LOANS permission |
| /:brandId/loans/:loanId | Loan Detail | LOANS permission |
| /:brandId/loans/unallocated | Unallocated Loans | ADMIN / LOAN_OPS |
| /:brandId/customers | Customer List | ONBOARDING_IN_PROGRESS |
| /:brandId/customers/:userId | Customer Detail | ONBOARDING_IN_PROGRESS |
| /:brandId/customers/unallocated | Unallocated Customers | ADMIN |
| /:brandId/collection | Collections | COLLECTIONS |
| /:brandId/pre-collection | Pre-Collection | PRE_COLLECTIONS |
| /:brandId/post-collection | Post-Collection | POST_COLLECTIONS |
| /:brandId/collection/v2 | Collection V2 | COLLECTIONS |
| /:brandId/completed | Completed Loans | COMPLETED_LOANS |
| /:brandId/loans-ops | Loan Operations | LOAN_OPS |
| /:brandId/payment-approval | Payment Approval | LOAN_OPS |
| /:brandId/payment-rejected | Rejected Payments | LOAN_OPS |
| /:brandId/payment-approved | Approved Payments | LOAN_OPS |
| /:brandId/sanction-manager | Sanction Manager | SANCTION_MANAGER |
| /:brandId/sanction-head | Sanction Head | SANCTION_HEAD |
| /:brandId/credit-executive | Credit Executive | CREDIT_EXECUTIVE |
| /:brandId/global-search | Global Search | GLOBAL_SEARCH |
| /:brandId/user | Partner Users | PARTNER_USER_MANAGEMENT |
| /:brandId/settings | Brand Settings | BRAND_SETTINGS |
| /:brandId/reports | Reports | MASTER_REPORTS |
| /:brandId/reminders | Reminders | ADMIN |
| /:brandId/help-center | Help Center | Any authenticated |
| /admin | Admin Panel | SUPER_ADMIN |
| /admin/settings | Admin Settings | SUPER_ADMIN |
Redux State Management
Global state structure and how it flows through the app
auth slice
brand slice
partnerUser slice
user slice (customer)
common slice
Shared UI state across all pages.
Actions: setFiltersVisible(bool), toggleFiltersVisible(). Used to show/hide the filter sidebar on list pages from anywhere in the component tree.
API Services Layer
How the frontend communicates with the backend
🔧 Axios Configuration (shared/services/axios.ts)
A single Axios instance is created with:
Every outgoing request automatically receives the JWT access token in Authorization: Bearer <token>. On a 401 response, the interceptor calls the refresh-token endpoint, updates the Redux store, and retries the original request.
🔑 auth.api
Login, logout, reset password, refresh token. Called at startup to validate stored tokens.
👥 customer.api
List customers, fetch customer details, allocate, reloan, update status.
📋 loan.api
List loans, loan details, status updates, CSV export, force-bypass, rule changes.
💰 collection.api
Pre/post collection queues, repayment timelines, settlement, write-off actions.
💳 payment.api
Payment processing, autopay setup, payment approval/rejection.
📊 dashboard.api
Stats, summary, geographic breakdown, collection analysis, disbursement metrics.
🏦 disbursement.api
Disbursement requests, status checks, IDFC/ICICI integrations.
👔 partner-user.api
Staff CRUD, role assignment, loan allocation, secure code generation.
🔐 partner-permissions.api
Permission fetching, role-permission matrix management.
📈 evaluation.api
Evaluation criteria, evaluation results, manual overrides.
🔎 bre.api
Business Rules Engine triggers and result fetching.
⚙️ brand.api
Brand config, theme, evaluation items, loan rules, targets.
shared/services/api/ but were not previously documented:🏦 Account Aggregation (aa.api.ts)
Full AA consent lifecycle: createConsentRequest, createManualConsentRequest, getUserConsentRequests, updateConsentStatus, sendConsentRequestEmail, generateConsentUrl, fetchPeriodicData. Integrates with FINDUIT/CART providers (RBI-regulated framework).
📞 Acefone Dialer (acefone.dialer.service.ts)
initiateCall (click-to-dial with userId, partnerUserId, brandId, loanId), getUserCalls, getPartnerUserCalls, getCustomerUserCalls, getCallDetails, endCall, getUserCallStats, getPartnerUserCallStats. Full VoIP call management.
📊 Activity Tracking (activityTracking.service.ts)
Sends user activity pings to the backend. Tracks mouse, keyboard, scroll events. Linked to the ActivityTrackerContext for idle detection and session logging.
🔑 API Key Management (apiKey.api.ts)
CRUD for brand API keys used by external systems to call the LOS backend. Create, list, revoke, and rotate API keys from the settings panel.
📋 Agreement (agreament.api.ts)
Loan agreement generation, e-sign initiation, e-sign status polling, final agreement PDF download. Works with the e-sign docket system configured per brand.
🚗 Autopay (autopay.api.ts)
Razorpay subscription management: create autopay mandate, get mandate status, cancel mandate, create autopay transaction, skip autopay consent. Linked to loan repayment scheduling.
⭐ Brand Rating Matrix (brand-rating-matrix.api.ts)
Fetch and update the brand-level rating matrix used to score customers. GET/POST/PUT endpoints for matrix configurations per brand.
🧮 CAM Calculator (cam-calculator.api.ts)
saveCAMCalculator (POST with salary dates, amounts, FOIR, ROI, repayment data), getCAMCalculator by loanId, getCAMCalculatorByUser by userId+brandId, deleteCAMCalculator. Used by credit executives to fill Credit Appraisal Memo.
🌐 Common (common.api.ts)
Miscellaneous shared API calls: IFSC lookup, state/city lists, pincode details, generic dropdown data used across forms.
💸 Disbursement (disbursement.api.ts)
Initiate bank disbursement, check NEFT/IMPS status, IDFC/ICICI bank integration, pending disbursement queue management, NDC (No Due Certificate) generation.
📈 Evaluation V2 (evaluationV2.api.ts)
Enhanced evaluation engine endpoints. Supports a newer evaluation flow with more criteria, weighted scoring, and automated rule checks. Used alongside evaluationV1 based on brand config evaluationVersion flag.
💱 Penny Drop (external/pennyDrop.api.ts)
Trigger penny drop bank verification for a customer's bank account. Polls verification status. Used in customer onboarding to confirm bank account ownership.
📬 Lead Management (leads/leads.api.ts)
uploadLeadFormsCsv (multipart), getLeadForms (paginated+filtered), getLeadFormsStats, syncLeadForms, deleteLeadForms (bulk), updateLeadFormStatus, exportLeadFormsCsv. Manages CSV lead imports from Facebook ads and other marketing channels.
📜 Loan Comments (loanComments.api.ts)
Add, list, and delete comments/remarks on a specific loan. Comments are timestamped and attributed to the partner user who made them. Used in the remarks modal on loan detail pages.
📏 Loan Rules (loan-rule.api.ts)
Fetch active loan rules for a brand, update rule parameters (min/max amount, tenure, rate), and create new rules per product type. Used in the settings panel.
🔔 Notification (notification.api.ts)
Fetch unread notifications for the logged-in partner user, mark as read (single or bulk), delete notifications. Feeds the notification bell in the header.
🔐 Partner Permissions (partner-permissions.api.ts)
Get all available permissions for a brand, get permissions assigned to a specific partner user, update permissions for a partner user. Core of the RBAC system UI.
📞 Partner User Dialer Config (partner-user-dialer-config.api.ts)
Get/set Acefone and Stringee dialer configurations for individual partner users. Maps the staff member's SIP extension to their account.
⭐ Partner User Rating Matrix (partner-user-rating-matrix.api.ts)
Individual staff performance rating matrix. Different from brand-level matrix. Tracks each partner user's collection/sales performance scores over time.
💳 Payment Approval (payment-approval.api.ts)
List pending payment approvals, approve a payment (with UTR confirmation), reject a payment (with reason). Used by Loan Ops staff in the payment approval queue.
💰 Payment (payment.api.ts)
Record manual payments, fetch payment history for a loan, payment gateway status lookups, trigger payment confirmations. Core payment processing API.
⏰ Reminder (reminder.api.ts)
getUserReminders (paginated, filters: channel/status/dateRange), getReminderAuditLogs, createUserReminder (with channel, templateCode, scheduledAt), getReminderDashboardMetrics, refreshReminderDashboardMetrics. Manages automated payment reminder scheduling.
📊 Report (report.api.ts)
getReport (by reportType + dateRange), exportReportToCSV, downloadReport. Supports 29 backend report types. Frontend type-asserts responses as MasterReportUser[], MarketingReportItem[], CompletedNoRepaymentReportItem[], or BaseReportItem[].
🧠 ScoreMe BDA (scoreMeBDA.ts)
ScoreMe Bureau Data Analysis integration. Fetches credit bureau data augmented with ScoreMe's scoring model. Used in the customer detail Credit Report tab for enhanced bureau analysis.
📤 Upload (upload.api.ts)
Generic S3 file upload service. Generates pre-signed URLs for direct browser-to-S3 uploads. Used for KYC docs, bank statements, payslips, profile photos, and agreement PDFs.
📱 User Devices (user-devices.api.ts)
Register and list devices for a partner user. Each device has a fingerprint ID. Admins can revoke device access. Used for the device-based login policy.
📝 User Logs (user-logs.api.ts)
Fetch activity logs for a customer user — what they did in the app, when, from which device. Shown in the Activity tab of the customer detail page.
🔎 User Search (user-search.api.ts)
Global search across customers by name, phone, PAN, email, loan ID. Powers the global search page with real-time debounced results.
shared/services/api/settings/):🎨 Appearance (appearance.setting.api.ts)
Update brand colors, fonts, logo URL, favicon. Theme changes reflect immediately via ThemeProviderContext.
📝 Blogs (blogs.setting.api.ts)
CRUD for brand blog posts shown in the customer-facing app. Title, content, published flag, featured image.
📞 Brand Acefone (brandAcefone.setting.api.ts)
Configure the brand's Acefone VoIP account credentials, SIP settings, and agent extension assignments.
🏦 Brand Bank Account (brandBankAccount.setting.api.ts)
Manage the brand's own bank accounts used for disbursements and repayment collection. IFSC, account number, beneficiary name.
🚫 Brand Block List (brandBlockList.setting.api.ts)
Manage list of blocked PAN/Aadhaar/phone numbers. Applications from blocked identities are auto-rejected.
🃏 Brand Cards (brandCards.setting.api.ts)
Configure brand card products shown to customers. Card types, limits, eligibility criteria, and interest rates.
📋 Evaluation Items (brandEvaluationItems.setting.api.ts)
Add/update/delete evaluation criteria and their weights. Supports V1 and V2 evaluation engines.
🛤️ Brand Paths (brandPaths.api.ts)
Configure URL paths/subdomains for the brand's customer-facing app. Each brand can have custom app routes.
📜 Brand Policy (brandPolicy.setting.api.ts)
Update T&C URL, privacy policy URL, FAQ URL shown to customers during onboarding and in the app.
🔌 Brand Provider (brandProvider.setting.api.ts)
Manage third-party provider configurations per brand: credit bureau, bank statement analysis, e-sign, SMS, email providers. isPrimary, isActive, isDisabled flags.
🌐 Brand Sub-Domains (brandSubDomains.api.ts)
Configure custom subdomains for the brand's partner dashboard and customer portal. Domain verification status.
🎯 Brand Targets (brandTargets.setting.api.ts)
Set monthly/quarterly disbursement and collection targets at brand, team, and individual executive levels.
⚙️ General Settings (general.setting.api.ts)
Core brand config: salary threshold, rejection duration, bank statement months, e-sign settings, section manager details, CAM requirement flag, auto-allocation type, field visit flag, dashboard/loan-ops/collection version flags.
📏 Loan Rules Settings (loanRules.setting.api.ts)
CRUD for loan rules (min/max amount, tenure, interest, processing fee) per product/risk category. BRE rules configuration.
📅 Non-Repayment Dates (nonRepaymentDates.api.ts)
Configure public holidays and non-working days when repayments cannot be processed. Affects due date calculations.
🏖️ Partner Unavailability Dates (partnerUnavailabilityDates.api.ts)
Mark dates when partner operations are suspended (holidays, maintenance). Affects auto-allocation and reminder scheduling.
Authentication Flow
How partner staff log in and stay authenticated
+ Password
/:brandId/dashboard
🔄 Token Refresh
When any API call returns 401, the Axios interceptor automatically calls POST /auth/refresh-token with the stored refresh token. On success, both tokens are updated in Redux and localStorage, and the failed request is retried. On failure, the user is redirected to /login.
📱 Device Fingerprinting
On login, FingerprintJS generates a unique device ID. This is sent to the backend which registers the device under the partner user's account. Future logins from unrecognized devices can be flagged or blocked per brand policy.
🏷️ Brand Access Check
After login, the frontend checks if the partner user has access to the requested brandId in the URL. If not, they're redirected to their first accessible brand. This prevents staff from accessing brands they weren't given access to.
⏱️ Activity Tracking
The activityTrackerContext monitors mouse movement, keyboard input, and scroll events. After a configurable period of inactivity, it sends an alert to the backend. A warning modal can appear asking the user to confirm they're still active.
Login Page
Entry point for all partner staff
The login page is brand-agnostic — it shows a generic 8byte/LOS login form. Staff enter their registered email and password. On success, the API returns the user's accessible brand IDs, roles, and JWT tokens. The frontend redirects to the first accessible brand's dashboard. For forgotten passwords, a "Reset Password" link sends an email with a one-time reset token link.
Dashboard Pages
Real-time operational metrics (V1 and V2)
📈 Dashboard V1
Overview stats: total applications, disbursements today, active loans, pending collections. Bar charts for loan volume by month. Pie charts for loan status distribution. Table of recent applications and their current status. Filters for date range and loan type.
📊 Dashboard V2
Enhanced analytics: per-user performance tables, geographic breakdown (users by city/state/company), collection analysis with recovery rates, disbursement analysis with amount trends. Partner user lead stats showing each agent's conversion rates.
dashboard.api calls. Charts are rendered with Chart.js (V1) and Recharts (V2). Both dashboards support date range filters that re-fetch data on change.
Customers Pages
Customer listing and full detail view
📋 Customer List
Paginated table of all customers for the current brand. Each row shows: name, phone, PAN, onboarding step, allotted executive, current status, and last activity date. Filters: by status, onboarding step, assigned executive, date range. Supports CSV export.
👁️ Customer Detail Page (Tabs)
The most information-dense page in the app. When you open a customer, you see multiple tabs:
Personal Details
Name, DOB, address, PAN, Aadhaar status, alternate addresses and phone numbers
Employment
Employer name, salary, UAN, EPFO verification status, payslips
Bank Account
Account details, penny drop status, bank statements uploaded
KYC Documents
PAN card, Aadhaar, selfie, salary slip — status + preview
Loans History
All loans for this customer, their statuses and amounts
Credit Report
CIBIL / Equifax scores, report download, credit history
Bank Statement
CART / Finbox / ScoreMe analysis results, BSA report
Evaluation
Evaluation results, criteria scores, manual override options
Activity / Calls
Call history, recordings, Acefone dialer, activity timeline
Loans Pages
Full loan lifecycle management
📋 Loan List
Paginated list of all loans for the brand. Shows loan ID, customer name, amount, status, disbursal date, due date, assigned executive. Filterable by status, amount range, date, executive. Supports bulk status changes and CSV export.
📑 Loan Detail
Complete loan view: loan amount, tenure, interest rate, disbursement details, repayment timeline, all status changes, payment history, signed agreement PDF viewer, evaluation results, and action buttons based on role.
🔄 Status Update Modal
A role-gated modal allowing authorized staff to change loan status. Each transition requires a reason selection from a predefined list. Some transitions (e.g., DISBURSED → COMPLETED) require additional confirmation.
⚙️ Loan Operations
Dedicated section for: pending disbursements awaiting bank transfer confirmation, payment approval/rejection queue, and no-due certificate (NDC) generation for fully repaid loans.
Collections Pages
Pre-collection, active collection, post-collection
⏰ Pre-Collection
Loans approaching due date. Staff send reminders via SMS/WhatsApp/Email directly from the UI. Bulk reminder sends supported. Repayment timeline displayed.
🔴 Active Collection
Overdue loans. Collection executives see their assigned loans. Can initiate calls via Acefone VoIP dialer, log outcomes, set follow-up dates, create repayment timelines.
📞 Post-Collection
Severely overdue or post-settlement loans. Can initiate settlement discussions, propose write-off amounts, and escalate to collection managers.
📊 Collection V2
Enhanced collection view with more granular filters, allocation management (assign/reassign collection executives), bulk actions, and detailed recovery metrics per executive.
Payment Pages
Payment approval, autopay, and disbursement
✅ Payment Approval
Loan Ops staff review incoming payment requests that need manual approval before processing. Can approve or reject with reason. Shows payment amount, UTR, gateway, and customer details.
🔁 Autopay Management
Setup recurring Razorpay subscriptions for customers. Shows active autopay mandates, their status, next collection dates, and allows cancellation or amount modification.
Partner Users Page
Internal staff management
Administrators can create, update, and deactivate internal staff accounts. Each staff member can have:
Role Assignment
Select from 9 pre-defined roles. Each role pre-loads a default permission set.
Custom Permissions
Override individual permissions beyond what the role provides.
Brand Access
Assign staff to one or more brands. They'll only see data for their brands.
Loan Allocation
Manually or auto-allocate loans and customers to specific executives.
Also includes: secure code generation (temporary access codes for field agents), audit logs showing every action taken by each user, and activity tracking for monitoring inactivity.
Settings Pages
Brand configuration and operational parameters
🎨 Brand Appearance
Primary/secondary colors, fonts, logo upload, favicon. Changes apply instantly via ThemeProviderContext CSS variable injection.
📏 Loan Rules
Min/max loan amounts, tenures, interest rates, processing fees. Rule types per product/risk category. Linked to BRE engine.
📋 Evaluation Items
Configure which criteria are checked during loan evaluation and assign weights/scores for V1 and V2 evaluation engines.
🎯 Targets
Monthly disbursement and collection targets at brand, team, and individual executive levels.
📧 Policy Links
T&C URL, privacy policy URL, FAQ URL shown to customers during onboarding and in the app.
⚙️ General Config
Salary threshold, rejection duration, bank statement months, auto-allocation type, dashboard version (V1/V2), loan-ops version, collection version, CAM requirement flag, field visit flag, e-sign settings.
🚫 Block List
Manage list of blocked PAN/Aadhaar/phone numbers. Applications from blocked identities are auto-rejected at the BRE stage.
🃏 Brand Cards
Configure card products shown to customers. Card types, limits, eligibility criteria, and interest rates.
🌐 Sub-Domains
Configure custom subdomains for the brand's partner dashboard and customer portal. Domain verification status.
📅 Non-Repayment Dates
Public holidays and non-working days when repayments cannot be processed. Affects due date calculations and reminder scheduling.
🏖️ Partner Unavailability
Mark dates when partner operations are suspended. Affects auto-allocation and reminder scheduling.
🔑 API Key Management
Create, list, revoke, and rotate API keys used by external systems to call the LOS backend. Per-brand key scoping.
🛤️ Brand Paths
Configure URL paths for the brand's customer-facing app and partner dashboard. Each brand can have custom routing.
📝 Blog Management
CRUD for brand blog posts shown in the customer-facing app. Title, content, published flag, featured image.
🔌 Brand Providers
Third-party provider configurations: credit bureau, bank statement analysis, e-sign, SMS, email providers. isPrimary/isActive/isDisabled flags per provider.
❌ Rejection Reasons
Configurable list of rejection reasons shown during evaluation and status updates. Brand-specific reasons beyond the system defaults.
📞 Acefone / Dialer Settings
Configure brand's Acefone VoIP account credentials, SIP settings, and Stringee fallback configuration.
🏦 Brand Bank Accounts
Manage the brand's own bank accounts for disbursements and repayment collection. IFSC, account number, beneficiary name.
🔄 Reloan Config
Configure reloan rules: eligibility criteria for customers to take a new loan, reloan product settings, minimum time between loans.
🎫 Coupons
Configure discount/waiver coupons that can be applied to loan processing fees or interest amounts.
Admin Panel
Super admin — cross-brand management
The Super Admin panel at /admin is only accessible to users with the SUPER_ADMIN global role. From here they can:
Brand Management
Create, update, and configure all lending brands on the platform.
Cross-Brand User Mgmt
Create and manage partner users across all brands simultaneously.
Admin Settings
System-level configuration, API key management, and global policies.
Platform-wide Reports
Aggregate reports across all brands and all staff.
Shared Components
Reusable UI building blocks used across all features
Sidebar Navigation
Dynamic sidebar that renders navigation links based on the user's permissions. Items not permitted are hidden entirely.
Data Tables
Sortable, paginated, filterable tables with row selection, bulk actions, and column visibility toggles.
Filter Components
Date range pickers, status dropdowns, user selects, and amount range inputs. All filters sync to URL query params.
Dialog / Modals
Confirmation dialogs, form modals, image preview modals, and PDF viewer modals with Framer Motion animations.
File Uploader
React Dropzone based uploader with preview, type validation, size limits, and progress indicators. Used for documents, statements, payslips.
Notification Bell
Header bell icon showing unread count. Dropdown lists recent notifications with type icons and timestamps.
Breadcrumbs (common/ui/breadcrumbs.tsx)
Navigation trail showing current location in the app hierarchy. Clickable segments to navigate back. Used on detail pages and nested settings.
LoanStatusBadge (common/ui/LoanStatusBadge.tsx)
Color-coded pill badge displaying loan status (ACTIVE, DISBURSED, COMPLETED, REJECTED, etc.). Consistent status colors used across all list and detail pages.
AddRemarksButton (common/ui/AddRemarksButton.tsx)
Button that opens the RemarksCommentModal. Appears on loan detail and customer detail pages. Allows partner staff to add timestamped remarks to a loan/customer record.
RemarksCommentModal (common/ui/RemarksCommentModal.tsx)
Modal dialog for adding and viewing remarks/comments on loans and customers. Lists existing remarks with author and timestamp. Submits new remarks to loanComments.api.
ColumnVisibilityDropdown (common/ui/columnVisibilityDropdown.tsx)
Dropdown control that lets users show/hide individual table columns. State persisted per page. Used on all major list pages (customers, loans, collections, etc.).
Dynamic Filters (common/filter/dynamicFilters.tsx)
Configurable filter panel that renders different filter inputs based on configuration. Syncs all filters to URL query params. Used by most list pages.
Dialogs (common/dialog/)
Specific pre-built dialog components: createAutopayTransactionDialog, loanAgreementDetailsDialog, resendConfirmationDialog, sendBackToCEDialog, skipAutopayConsentDialog.
React Context Providers
Cross-cutting concerns shared via Context API
🎨 ThemeProviderContext
Loads the current brand's theme (colors, fonts) from the Redux brand slice and injects CSS custom properties into the document root. Every component automatically uses the brand's color scheme.
🍞 ToastContext
Wraps React Toastify configuration. Provides a showToast(message, type) helper usable anywhere. Success/error/info/warning variants with auto-dismiss.
⏱️ ActivityTrackerContext
Listens to DOM events (mousemove, keypress, scroll, click). Tracks the last-active timestamp and sends pings to the backend's activity tracking endpoint. Shows an inactivity warning modal after threshold.
📞 AcefoneDialerContext (features/acefone/context/)
Manages the Acefone VoIP dialer widget state: current call session, call controls (mute, hold, end), call log, and the floating dialer UI shown when a call is active. Available globally via AcefoneDialerProvider in App.tsx for any page to initiate calls.
👤 RoleContext (context/roleContext.tsx)
Provides { role, setRole } to the component tree. Initialised from auth.data.role[0] in Redux. Re-syncs via useEffect when auth data changes. Uses getCurrentRoleAndPermissions() lib to validate the current role. Consumed via the useRole() hook.
🔒 PermissionContext
Companion to RoleContext. Exposes the resolved permission set for the logged-in partner user. Components can check specific permissions without reading Redux directly. Gates sidebar items, action buttons, table columns, and route access.
Custom Hooks
Reusable logic extracted into hooks
📱 useDevice (hooks/useDevice.ts)
Uses FingerprintJS to generate a stable device fingerprint on first load. Calls the backend device-registration API. Returns the device ID for use in login requests and session tracking.
🔄 useVersionGuard (hooks/useVersionGuard.ts)
Polls a version endpoint periodically. If the deployed frontend version is newer than what the user has, shows a "New version available" banner with a force-reload button. Prevents users from running stale code.
⏱️ useActivityMonitor (hooks/useActivityMonitor.ts)
Exports three hooks: useActivityMonitor(thresholdSeconds) returns isActive, isIdle, inactiveSeconds, inactiveMinutes, lastActivityTime, activityLogs, sessionDuration. usePageVisibility() tracks tab active/hidden state. useRecentActivity(thresholdSeconds) returns boolean if user interacted in last N seconds.
🔗 useAwsSignedUrl (hooks/useAwsSignedUrl.ts)
Takes an S3 object key and fetches a time-limited pre-signed URL for secure document viewing. Used throughout the app wherever KYC docs, agreements, or statements need to be displayed without exposing the raw S3 path.
🏢 useBrandMeta (hooks/useBrandMeta.ts)
Reads brand metadata from the Redux brand slice. Returns brand name, logo URL, theme colors, and config flags (isAA, isCamRequired, dashboardVersion, etc.) as a convenient destructured object.
💾 usePersistedSearch (hooks/usePersistedSearch.ts)
Persists the user's last search term and filters for a given page key in sessionStorage. When the user navigates away and returns, the previous search state is restored — preventing loss of context when opening a detail record.
🔍 useQueryParams (hooks/useQueryParams.ts)
Read and write URL query parameters as typed values. Used by list pages to sync filters, page number, and sort order to the URL so they survive a browser refresh and can be shared as links.
📤 useResendConfirmation (hooks/useResendConfirmation.ts)
Manages resend cooldown timer for confirmation emails (e.g., password reset, email verification). Prevents spam by enforcing a cooldown period with a countdown displayed in the UI.
🚪 handelLogout (hooks/handelLogout.ts)
Centralized logout handler. Calls POST /auth/partner/logout, clears Redux state (auth, brand, partnerUser), removes tokens from localStorage, and redirects to /login. Used in the sidebar profile menu and session expiry handler.
📞 useAcefoneDialer (hooks/useAcefoneDialer.ts)
Convenience hook that wraps the AcefoneDialerContext. Returns call state (isCallActive, currentCall) and action methods (initiateCall, endCall, muteCall). Used by collection pages to embed click-to-dial in customer rows.
🏷️ useLoanStatus (hooks/useloanStatus.ts)
Returns valid next status transitions for a given loan's current status and the logged-in user's role+permissions. Ensures the status update dropdown only shows transitions the current user is authorized to perform.
📊 useDashboardStats (features/dashboard/hooks/)
Fetches and memoizes dashboard summary statistics for the selected date range. Returns loading state, error, and the stats object (total applications, disbursements, active loans, collections due).
📈 useCollectionAnalysis (features/dashboard/hooks/)
Fetches collection analysis data for Dashboard V2. Returns recovery rates, overdue buckets, and executive-level collection performance for the selected period.
💸 useDisbursementAnalysis (features/dashboard/hooks/)
Fetches disbursement trend data for Dashboard V2 charts. Returns daily/weekly/monthly disbursement amounts and counts for the selected date range.
📋 useLoanAllocationDetails (features/dashboard/hooks/)
Fetches loan allocation breakdown by executive for Dashboard V2. Returns per-agent loan counts, amounts, and allocation rates for the team performance table.
🔔 useNotifications (features/notification/useNotifications.ts)
Polls the notification API at regular intervals. Returns unread count, notification list, and markAsRead(id) / markAllRead() actions. Feeds the notification bell component.
📞 useDialerConfig (features/partnerUsers/hooks/useDialerConfig.ts)
Fetches the dialer configuration for the current partner user (Acefone SIP extension, Stringee settings). Returns config and a updateConfig mutation method. Used in the partner user settings dialog.
Roles & Permissions (RBAC)
How the frontend enforces access control
SUPER_ADMIN
Cross-brand access, brand creation, system settings, all permissions unlocked.
ADMIN
Full access within their brand: users, settings, reports, loans, collections.
LOAN_EXECUTIVE
Customer onboarding, loan management, evaluation. Cannot access collections or settings.
COLLECTION_EXECUTIVE
Active collections, pre/post collection queues. Can initiate calls and log outcomes.
COLLECTION_MANAGER
All collection executive access plus team management, allocation, escalations.
COLLECTION_HEAD
Supervisory view over all collections, settlement authority, write-off approvals.
SANCTION_MANAGER
Reviews applications for sanctioning. Can approve/reject with conditions.
SANCTION_HEAD
Final sanctioning authority. Overrides sanction manager decisions.
CREDIT_EXECUTIVE
Credit analysis, BRE results review, evaluation overrides, credit decisions.
🔒 How Permissions Work in the UI
The lib/role.ts utility provides helper functions like hasPermission(user, 'COLLECTIONS') and hasRole(user, 'ADMIN'). These are used in:
Frontend Third-Party Integrations
External SDKs embedded in the frontend
📞 Acefone VoIP
VoIP dialer widget embedded in the frontend. Allows collection staff to make calls directly from the browser. Call sessions tracked, recordings linked to customer profiles.
📱 Stringee
Alternative call center platform integration. Provides call queuing, IVR, and agent management for larger collection teams.
🤝 Lendbox
Partner lender UI components. Loan creation requests sent to Lendbox, their disbursement status synced back and shown in the frontend.
🔏 FingerprintJS
Browser fingerprinting for device registration. Runs invisibly on login, generates stable device ID.
📝 TipTap Editor
Rich-text editor for notes, comments, and rejection reason descriptions. Supports bold, lists, links.
📊 Chart.js + Recharts
Two charting libraries for different dashboard needs. Chart.js for standard charts, Recharts for more complex React-integrated charts.
🔐 Google OAuth
Google Sign-In integrated via VITE_GOOGLE_CLIENT_ID env variable. Allows partner staff to authenticate using Google Workspace accounts. Token validation delegated to the backend auth service.
🧠 ScoreMe BDA
ScoreMe Bureau Data Analysis SDK. Fetches enriched credit bureau data with ScoreMe's proprietary scoring model. Embedded in the customer detail Credit Report tab. Results include bureau score, repayment history, and risk flags. API handled via scoreMeBDA.ts.
Completed Loans Page
4 sub-tabs for fully closed loan lifecycle management
/:brandId/completed. Split into 4 sub-tabs, each with its own page file in pages/loanCompleted/. Accessible to LOAN_OPS role and above.📋 All Completed (all.tsx)
Unified view of all loans that have reached a terminal status. Paginated table with filters for status, date, executive, amount. Supports CSV export. Shows loan ID, customer name, amount, closure date, and closure type.
🔒 Closed (closed.tsx)
Loans fully repaid by the customer with no outstanding balance. NDC (No Due Certificate) generation available. Shows repayment date, total paid, any waiver given. NDC can be emailed to the customer directly from this view.
🤝 Settlement (settlement.tsx)
Loans settled at a negotiated amount less than the full outstanding balance. Shows original outstanding, settlement amount agreed, settlement date, and the partner user who authorized it. Settlement requires COLLECTION_HEAD permission.
📉 Write-Off (write-off.tsx)
Loans written off as uncollectable. Shows write-off date, outstanding at write-off, reason, and authorizing manager. Write-off requires both COLLECTION_HEAD and ADMIN approval. Once written off, the loan is archived but remains visible for audit.
Loan Operations Pages
All sub-pages under /:brandId/loans-ops
/:brandId/loans-ops. Dedicated workspace for the LOAN_OPS role. 5 sub-pages handle the full disbursement and repayment verification workflow. Files in pages/loanOps/.⏳ Pending Disbursement (pendingDisbursement.tsx)
Loans sanctioned and waiting for bank transfer. Shows loan ID, customer name, bank account details, amount, and NEFT/IMPS transfer reference. Loan Ops confirms disbursement once bank transfer is done, triggering status change to DISBURSED.
📄 No Due Pending (noDuePending.tsx)
Fully repaid loans waiting for NDC (No Due Certificate) generation. Loan Ops verifies all payments are received, then generates and emails the NDC. Moves loan to CLOSED status on completion.
🔍 Payment Approval (paymentApproval.tsx)
Incoming payment records that need manual Loan Ops review before being confirmed. Shows customer, loan, payment amount, UTR/reference number, payment gateway, and submission date. Can approve or reject.
✅ Payment Approved (paymentApproved.tsx)
Historical view of all payments that have been approved by Loan Ops. Audit trail with who approved, when, and the UTR confirmed. Used for reconciliation and reporting.
❌ Payment Rejected (paymentRejected.tsx)
Historical view of payments rejected by Loan Ops with rejection reasons. Shows rejected amount, reason given, and the partner user who rejected. Customer support can use this to explain payment issues to customers.
Reports Page
Data export and analytics for management and compliance
/:brandId/reports. File: pages/report/index.tsx. Requires MASTER_REPORTS permission. All reports support date range filters and CSV/download export via report.api.ts.📋 Master Report
Complete customer-level data export. Includes: Customer ID, Name, Mobile, DOB, Gender, PAN verified, Aadhaar verified, employment type, monthly income, company name, bank account, address, references, all loan IDs, loan statuses, loan amounts, status history, and brand rejection reasons. Used for regulatory filings and portfolio analysis.
📢 Marketing Report
Lead and acquisition funnel data. Fields: Lead ID, Domain/source, Lead Stage, Rejection Remarks, Created At. Tracks which marketing channels are converting to applications. Used by the marketing team to measure campaign ROI.
📉 Completed No-Repayment Report
Loans that reached a terminal status (closed/written-off/settled) without any payment being made. Shows loan ID, formatted loan ID, status, creation date, customer ID, and due date. Used for NPA (Non-Performing Asset) analysis.
📊 Other Reports (29 Total)
The backend exposes 29 report types across three categories: User/Loan reports (e.g. disbursed-loan-report, reject-report, outstanding-data-report), Collection reports (e.g. master-collection-report, collection-due-report, field-visit-report), and Marketing/Credit reports (e.g. marketing-report, cic-report, daily-marketing-mis-report). All are date-range filtered and support CSV export.
Reminders Page
Automated communication scheduling and monitoring
/:brandId/reminders. File: pages/reminders/RemindersPage.tsx. Feature component: features/Reminders/index.tsx. API: reminder.api.ts.📊 Reminder Dashboard Metrics
Summary card showing total reminders sent today, this week, this month. Delivery rate per channel (SMS/WhatsApp/Email). Fetched via getReminderDashboardMetrics. A refresh button manually triggers a data refresh via refreshReminderDashboardMetrics. Includes a matrix graph (features/Reminders/components/matrixGraph.tsx) visualizing reminder performance over time.
📋 Reminder List
Paginated table of all reminders. Columns: customer name, channel (SMS/WhatsApp/Email), template code, scheduled time, status (PENDING/SENT/FAILED/CANCELLED). Filters: channel, status, created date range, scheduled date range, search by customer. Each row shows audit logs link.
📝 Create Reminder
Modal form to schedule a new reminder. Fields: select customer (userId), channel (SMS/WhatsApp/Email), template code, scheduled date/time, optional providerMessageId, and custom payload variables. Submits to createUserReminder.
🔍 Reminder Audit Logs
Per-reminder audit trail showing every status change: when it was created, when it was dispatched to the provider, provider acknowledgement, delivery confirmation, and any failure reasons with error codes.
Global Search Page
Cross-entity search across customers, loans, and users
/:brandId/global-search. File: pages/gloabalSearch/index.tsx. API: user-search.api.ts.A dedicated search page that allows partner staff to search across the entire brand's data in one place. The search input is debounced and queries the user-search.api which searches across:
Results are displayed in grouped sections (Customers, Loans). Clicking a result navigates to the respective customer detail or loan detail page. Results load in real time as the user types.
Sanctions Pages
Sanction Manager and Sanction Head queues
📋 Sanction Manager (pages/sanctionsManager/index.tsx)
Route: /:brandId/sanction-manager. Shows applications that have passed credit evaluation and are awaiting manager-level sanction approval. Lists customer name, loan amount, evaluation score, credit executive who evaluated, and days waiting. Manager can: Sanction (approve with conditions), Send Back to Credit Executive, or Reject with reason. Requires SANCTION_MANAGER role.
🏅 Sanction Head (pages/sanctionsHead/index.tsx)
Route: /:brandId/sanction-head. Higher-level sanction queue for applications that Sanction Managers have escalated or that meet criteria requiring Head-level approval (e.g., high loan amounts beyond manager threshold). Final sanction authority. Can override Sanction Manager decisions. Requires SANCTION_HEAD role.
Credit Executive Page
Credit analysis and loan evaluation queue
/:brandId/credit-executive. File: pages/creditExecutive/index.tsx. Requires CREDIT_EXECUTIVE role.Dedicated queue for Credit Executives showing loans that have completed onboarding and are awaiting credit analysis. The Credit Executive reviews:
BRE Results
Business Rules Engine output, score breakdown, and rule pass/fail details.
CAM Calculator
Fill/review Credit Appraisal Memo with salary data, FOIR, and loan recommendation.
Evaluation V2
Enhanced evaluation criteria scoring with manual override capability.
Credit Report
CIBIL/Equifax score, ScoreMe BDA analysis, and repayment history.
After analysis, the Credit Executive submits an evaluation decision (Approve/Conditional/Reject) which moves the loan to the Sanction Manager queue.
Help Center Page
Internal knowledge base and support resources
/:brandId/help-center. File: pages/helpCenter/index.tsx. Accessible to any authenticated partner user.Internal help and documentation page for partner staff. Content rendered using react-markdown. Provides:
CAM Calculator Feature
Credit Appraisal Memo — used by Credit Executives to assess loan eligibility
brandConfig.is_cam_calculation_required = true. Component: features/customerDetails/components/ (CAM tab on customer detail). API: cam-calculator.api.ts.📋 What it does
The CAM Calculator is a structured form that credit executives fill when analysing a loan application. It captures 3 months of salary data, calculates average salary, determines eligible FOIR (Fixed Obligation to Income Ratio), computes eligible loan amount, and generates a recommendation.
📐 Data Fields
⚙️ API Operations
saveCAMCalculator(brandId, data) — POST to save/update. getCAMCalculator(loanId) — GET existing CAM for a loan. getCAMCalculatorByUser(userId, brandId) — GET all CAMs for a user. deleteCAMCalculator(loanId) — DELETE. The saved CAM data is visible to Sanction Managers when reviewing the loan.
👥 Roles
CREDIT_EXECUTIVE fills the CAM. SANCTION_MANAGER and SANCTION_HEAD can view it (read-only) during their review. The CAM tab is only visible on the customer detail page when is_cam_calculation_required is true for the brand.
Account Aggregation (AA) Feature
RBI-regulated financial data sharing via consent framework
brandConfig.isAA = true. Component: features/customerDetails/components/aa/ (AA tab on customer detail). API: aa.api.ts. Providers: FINDUIT, CART.📜 What is AA
Account Aggregation is an RBI-regulated framework that allows customers to securely share their bank statement data with lenders via a consent-based mechanism. The customer approves a consent request through their bank's AA-enabled app. The lender then receives structured financial data without manually uploading bank statements.
🔄 Consent Flow
1. Partner creates consent request (createConsentRequest). 2. Consent link sent to customer via email (sendConsentRequestEmail) or shared manually (generateConsentUrl). 3. Customer approves via their bank's AA app. 4. System polls consent status (updateConsentStatus). 5. On approval, periodic data fetch (fetchPeriodicData) pulls bank statements.
📊 AA Components (features/customerDetails/components/aa/)
These components render income analysis, transaction categorisation, balance trends, and month-over-month comparison from the AA-fetched data.
📋 API Operations
createConsentRequest(userId, brandId), createManualConsentRequest(userId, mobile, brandId), getConsentRequest(id), getUserConsentRequests(userId), getDataSessions(consentRequestId), updateConsentStatus(id, {status, clientTransactionId, consentHandle}), sendConsentRequestEmail(userId), generateConsentUrl(userId, brandId), fetchPeriodicData({userId, consentRequestId}).
Lead Management Feature
Import and manage marketing leads from Facebook Ads and other channels
leads/leads.api.ts. Accessible from the Settings area or a dedicated leads section. Used by marketing/admin staff to import leads generated by ad campaigns.📤 CSV Upload
uploadLeadFormsCsv(brandId, file) — accepts a CSV file (multipart/form-data). The CSV contains lead data from Facebook Lead Ads: full name, phone, email, city, platform, monthly salary, PAN, employment status, campaign metadata (adId, adName, adsetId, campaignId, formId). Backend processes and deduplicates against existing users.
📋 Lead List & Filtering
Paginated table of all uploaded leads. Each lead shows: name, phone, status (PENDING/PROCESSED/FAILED/DUPLICATE), platform, campaign, and uploaded timestamp. Filters by status and platform. Supports bulk delete and CSV export of filtered leads.
🔄 Sync & Processing
syncLeadForms(brandId) — triggers backend processing to match unprocessed leads against existing users or create new user records. Returns counts of processed, failed, and duplicate leads.
📊 Lead Stats
getLeadFormsStats(brandId) — returns totals: total leads, pending, processed, failed, duplicates. Displayed as summary cards at the top of the leads view for quick overview.
Rating Matrix Feature
Performance scoring for brands and partner users
🏢 Brand Rating Matrix (brand-rating-matrix.api.ts)
Brand-level scoring matrix used to evaluate loan applications. Configurable criteria with weightings. Fetched as part of brand setup. Admins can update matrix criteria and weights from the settings panel. Affects how the BRE engine scores applications for the brand.
👤 Partner User Rating Matrix (partner-user-rating-matrix.api.ts)
Individual staff performance rating system. Tracks each partner user's metrics (conversion rates, collection efficiency, TAT). Managers can view and update staff performance scores. Used for performance reviews and allocation priority decisions.
Utilities (lib/ folder)
Shared helper functions used across the frontend
🔗 cn() — clsx + tailwind-merge (lib/utils.ts)
The cn(...inputs) function combines clsx and tailwind-merge for safe conditional class merging. Also exports: formatDate(date), formatDateWithTime(date) (using dayjs), formatDocumentType(type), maskAadhaar(aadhaar) (shows only last 4 digits as XXXX-XXXX-NNNN), maskPan(pan) (shows first 2 + last 1 chars).
✅ canUpdateLoanStatus (lib/canUpdateLoanStatus.ts)
Given the current loan status, user role, and permissions, returns a boolean whether the user can trigger a status transition. Also returns the list of valid target statuses. Used by the status update modal to filter the dropdown options.
🏦 fetchIFSCDetails (lib/fetchIFSCDetails.ts)
Fetches bank branch details (bank name, branch, address, city, state) for a given IFSC code from the Razorpay IFSC API or the backend IFSC lookup. Used in bank account forms to auto-fill branch details when the user enters an IFSC code.
👤 getCurrentRoleAndPermissions (lib/getCurrentRoleAndPermissions.ts)
Reads the current user's role and permissions from Redux or localStorage and returns them in a normalised format { roleId, permissions }. Used by RoleContext and throughout the app for permission checks without hitting Redux directly.
📄 pdfMetadataExtractor (lib/pdfMetadataExtractor.ts)
Uses PDFjs-dist to extract metadata from uploaded PDF files (title, author, page count, creation date). Also validates PDF integrity. Used when partner staff upload loan agreements and bank statements to verify the file is a valid PDF.
📄 getPdfVersionFromUrl (lib/getPdfVersionFromUrl.ts)
Extracts the PDF version identifier from an S3 URL. Used to determine whether to render a PDF with the old viewer or the new enhanced viewer based on version number.
🎨 theme.ts (lib/theme.ts)
Theme configuration helper. Maps brand theme fields (primaryColor, secondaryColor, fontFamily, etc.) to CSS custom property names. Used by ThemeProviderContext to inject brand colors into the document root.
🔒 role.ts (lib/role.ts)
Role utility functions: hasPermission(permissions, permKey), hasRole(roles, roleKey), role hierarchy checks. Used throughout the app for conditional rendering and route guarding.