Clientra CRM
Documentation
Comprehensive documentation for Clientra CRM — a full-featured real estate management platform built for UAE and global markets. Single-page application with 36 page modules, 386+ API endpoints, and enterprise-grade features.
Full listing management with images, documents, and advanced filtering.
Lead pipeline tracking with source attribution and agent assignment.
Kanban deal pipeline with stage tracking and commission calculation.
Unified hub for email, calls, WhatsApp, SMS, meetings, and notes.
Contract lifecycle management with UAE-specific regulatory fields.
Invoicing, payments, VAT calculation, and commission management.
Workflow rules with triggers, conditions, and automated actions.
Employee management, attendance, leave tracking, and payroll.
Tech Stack
Frontend
- Vanilla JS SPA (no framework)
- Hash-based routing (
#/page-name) - Chart.js 4.4.0 for dashboards
- SheetJS for Excel import/export
- DomPDF for PDF generation
Backend
- PHP 8.0+ with PDO
- MySQL 5.7+ / MariaDB 10.4+
- Session-based authentication
- CSRF token protection
- Role-based access control
Editions
Includes UAE-specific features: DLD fee calculation, Ejari/Tawtheeq/Oqood contract fields, Emirates ID validation, AED currency, and UAE regulatory compliance.
General-purpose real estate CRM without UAE-specific regulatory requirements. Configurable currency, date format, and timezone for any market.
Architecture Overview
Clientra CRM is a single-page application (SPA) that uses hash-based routing to navigate between 36 page modules. The frontend communicates with the PHP backend exclusively through api.php, which acts as a centralized API router dispatching to 24 service classes.
<script> tags in index.php. There is no webpack, Vite, or other bundler. Cache busting is handled manually via ?v=X.X version parameters.
Load Order
The JavaScript load order is critical. Files must be loaded in this sequence:
<!-- 1. Core utilities --> <script src="assets/js/DataAdapter.js?v=1.0"></script> <script src="assets/js/api.js?v=1.0"></script> <script src="assets/js/router.js?v=1.0"></script> <!-- 2. Components (17 files) --> <script src="assets/js/components/DataTable.js?v=1.0"></script> <!-- ... --> <!-- 3. Pages (36 files) --> <script src="assets/js/pages/Dashboard.js?v=1.0"></script> <!-- ... --> <!-- 4. App initialization --> <script src="assets/js/app.js?v=1.0"></script>
Key Conventions
showToast(message, type) function — not App.showToast(). Always use body for communication text content — not comment. All delete operations use POST method, not DELETE.
| Convention | Correct | Incorrect |
|---|---|---|
| Toast notifications | showToast('msg', 'success') |
App.showToast() |
| Communication content | body field |
comment field |
| Delete requests | POST method | DELETE method |
| Data transformation | DataAdapter.adapt(data, 'backend') |
Manual snake_case conversion |
| XSS in modals | QuickViewModal.esc(val) |
Direct innerHTML injection |
Global Functions & Variables
// Toast notifications showToast('Property saved', 'success'); // success | error | info | warning // API calls await api.call('action_name', 'GET', { param: 'value' }); await api.call('add_property', 'POST', propertyData); // Navigation window.router.navigate('/properties'); // Data transformation (camelCase ↔ snake_case) DataAdapter.adapt(data, 'backend'); // frontend → backend DataAdapter.adapt(data, 'frontend'); // backend → frontend // Global instances window.app // Main App instance window.api // ApiClient instance window.router // Router instance window.currentUser // Current logged-in user