Skip to content

Customer Dashboard — Landing Screen ​

The landing screen at /dashboard is a read-only KPI summary: four overview cards (Leads, Campaigns, Commerce, Payments) plus a CRM Activity row (Upcoming Meetings, Follow-ups, Lead stages). It aggregates data the other sections own so a customer sees the state of their business at a glance.

Screenshots ​

Dashboard landing — overview cardsDashboard — CRM activity rowDashboard — date-range view

Architecture Overview ​

How It Works (Step-by-Step) ​

  1. Page load. Opening /dashboard renders the greeting ("Hi, {name}") and a date-range switcher (Day / Week / Month / Custom). The range is passed to each card's query so all KPIs share one window.
  2. Overview cards fetch in parallel. Each card calls the stats endpoint owned by its section:
    • Leads → GET /api/leads/stats (totals by status: Total, Contacted, Converted, Lost). Served by crmLead.controller.getLeadStats → crmLead.service → crmLead.repository → CrmLead collection.
    • Campaigns → GET /dashboard-stats (Total / Active / Drafts / Completed). Served by campaign.controller.getDashboardStats → campaign.service → Campaign / CampaignReport.
    • Commerce → GET /api/orders/stats and inventory counts (Orders, Revenue, Items, Low stock). Served by crmOrder.controller.getOrderStats and crmInventory → CrmOrder / CrmInventory.
    • Payments → GET /api/transactions/stats (Collected, Transactions, Paid, Pending). Served by crmTransaction.controller.getTransactionStats → CrmTransaction.
  3. CRM Activity row.
    • Upcoming Meetings → GET /meetings filtered to future meetings → Meeting records (only shown when the meeting_room feature is on).
    • Follow-ups → GET /api/reminders/due → CrmReminder records due for the current user.
    • Lead stages → stage counts from GET /api/leads/stats rendered as a mini bar list (New, Contacted, Qualified, Negotiation, Won, Lost, …).
  4. Compliance banner. A TRAI 7-day calling-window banner (TraiComplianceBanner) appears above the cards when the customer holds crm_leads, reminding them to call new leads within the compliant window.

⚠️ Unverified: the exact card→endpoint wiring (which card uses which stats call, and the Customize 6/6 card toggle) is inferred from the screenshot and each section's stats route. The dashboard page component was not read line-by-line; treat the per-card endpoint mapping as indicative.

File Reference ​

FileRoleKey Functions
app/src/layouts/CustomerLayout.tsxRenders the Dashboard nav item (/dashboard) and the TRAI bannermainNavItems[0], TraiComplianceBanner
controllers/campaign.controller.tsCampaign KPIs for the Campaigns cardgetDashboardStats()
controllers/crmLead.controller.tsLead totals + stage countsgetLeadStats()
controllers/crmOrder.controller.tsOrder KPIsgetOrderStats()
controllers/crmTransaction.controller.tsPayment KPIsgetTransactionStats()
controllers/crmReminder.controller.tsDue follow-upslistDueReminders()
routes/meeting.routes.tsUpcoming meetingsPOST/GET /meetings

Data Model ​

The dashboard reads (never writes) these collections:

Card / widgetCollection(s)Fields read
LeadsCrmLeadstatus, createdAt, customerUID
CampaignsCampaign, CampaignReportstatus, createdAt
CommerceCrmOrder, CrmInventorytotal, status, stock
PaymentsCrmTransactionamount, status
Upcoming MeetingsMeetingscheduledAt, participants
Follow-upsCrmReminderdueAt, userUID

API Endpoints ​

Campaign dashboard stats ​

  • Method: GET
  • Path: /dashboard-stats
  • Auth: verifyJwt (user-scoped)
  • Response: 200 with campaign totals/active/draft/completed counts.

Lead stats (totals + stages) ​

  • Method: GET
  • Path: /api/leads/stats
  • Auth: verifyJwt → requireFeatureAccess(leads) → resolveCrmLeadScope → requireLeadPermission("view")
  • Response: 200 with status and stage counts for the resolved tenant.

Order stats ​

  • Method: GET
  • Path: /api/orders/stats
  • Auth: verifyJwt → requireFeatureAccess(commerce) → resolveCommerceScope → requirePermission("commerce","view")

Transaction stats ​

  • Method: GET
  • Path: /api/transactions/stats
  • Auth: same commerce chain as order stats

Due follow-ups ​

  • Method: GET
  • Path: /api/reminders/due
  • Auth: verifyJwt → requireFeatureAccess(leads) → resolveCrmLeadScope → requireLeadPermission("view")

External Integrations ​

None directly. The Upcoming Meetings widget links into the LiveKit-backed Meeting Room feature; the dashboard only lists the meeting records.

How to Test (End-to-End) ​

  1. Log in as a customer with leads, campaigns, and commerce data seeded.
  2. Open /dashboard; confirm the four overview cards render with non-error values.
  3. Switch Day/Week/Month and confirm each card re-queries (watch the network tab for the stats calls above).
  4. Create a reminder due today on a lead → it should appear under Follow-ups.
  5. Confirm the Lead stages bar counts match GET /api/leads/stats.

Troubleshooting ​

SymptomCauseFix
A card shows 0/emptyNo data in that section, or the feature is offSeed data or enable the section's feature
Payments/Commerce cards missingcommerce entitlement offEnable Commerce for the customer
Follow-ups empty though reminders existReminders not due in the selected range, or set by another userReminders are per-user and date-scoped
TRAI banner won't dismissIt re-appears while never-called leads are within/over the 7-day windowCall or reassign the at-risk leads

Last updated: