Leads
Inbound inquiries that haven't become customers yet — website form submissions, WhatsApp pings, referrals. Tracked in one list, convertible to a quotation or a booking.
Scope
Only one page in this module: src/pages/leads/Leads.tsx (route /sales/leads). No detail route — the full edit experience is a dialog opened from the list.
Page — Leads.tsx
Route /sales/leads, gated by leads.view (src/App.tsx:159).
List
DataTable filtered by search + status. Columns: lead name + phone, travel type + group size, linked group name, status badge, received date, view action (Leads.tsx:263-319).
Status enum (Leads.tsx:39-45): new, contacted, qualified, converted, closed.
Travel type enum (Leads.tsx:47-52): umrah, hajj, umrah_plus, custom.
Create lead
Header "Add Lead" button — gated by leads.edit (Leads.tsx:255-260). Fields:
fullName,phone,email,city.travelType(one of the four above).groupSize— integer.preferredMonth— free text.message— long text.
The form has no file uploader — inbound leads with attachments (from the website widget) are created by the public API and show their files on the detail dialog (Leads.tsx:361-380).
Detail dialog
Opens when "View" is clicked. Shows all captured fields plus any attachments[] that came in with the website submission. Two conversion buttons plus an in-dialog status updater.
Lead → customer / quotation / booking conversion
Two conversion paths, both live on the detail dialog (Leads.tsx:381-389):
Convert to quotation (convertLeadToQuotation, Leads.tsx:201-209)
Service: src/services/leadService.ts. Fields collected on the convert dialog:
totalAmount,currency.validUntil(date).notes.discount.
Creates a Quotation row linked to the (newly-created or matched) customer. Permission: quotations.create.
Convert to booking (convertLeadToBooking, Leads.tsx:215-223)
Requires a group selection — groupId is required (Leads.tsx:211-214). Fields:
totalAmount,currency.groupId— the travel group this booking belongs to.paymentPolicy—partialor full.paidAmount.notes.
Creates a Booking inside the selected TravelGroup, with an associated customer record. Permission: bookings.create.
Customer creation is implicit during conversion
Converting a lead to a quotation or booking creates (or matches) a Customer row from the lead's contact fields — the lead itself is not a customer until it converts.
Status updates (updateLeadStatus)
The detail dialog has a Select that updates status independently of conversion. Gated by leads.edit (Leads.tsx:391).
Permissions
Canonical reference: docs/PERMISSIONS.md §4.1 and §6.2.
| Action | Permission |
|---|---|
View /sales/leads |
leads.view |
| Create lead | leads.edit |
| Update status | leads.edit |
| Convert to quotation | quotations.create |
| Convert to booking | bookings.create |
No leads.create — creation is gated by leads.edit
The catalog only defines leads.view and leads.edit (PERMISSIONS.md §4.1). Creating a lead and updating its status share the same permission.
Roles holding leads.edit by default: SALES_MANAGER, SALES_EXEC, plus super-admin/admin tier (PERMISSIONS.md §5.2).
Related
- Customers — created implicitly by
convertLeadToBooking/convertLeadToQuotation. - Quotations — destination of
convertLeadToQuotation. - Bookings — destination of
convertLeadToBooking. - PERMISSIONS.md §6.2 — authoritative action matrix.