Add standalone Leads module for prospect outreach before customers.
Import large Excel lists with duplicate checks, assign and kanban follow-up, convert to Person when ready; also fix OTP mobile mask order and SMS brand name to منتکت. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -124,7 +124,8 @@ export type OrgModuleKey =
|
||||
| "teams"
|
||||
| "woocommerce"
|
||||
| "voip"
|
||||
| "reservations";
|
||||
| "reservations"
|
||||
| "leads";
|
||||
|
||||
export const ORG_MODULE_KEYS: OrgModuleKey[] = [
|
||||
"customers",
|
||||
@@ -139,6 +140,7 @@ export const ORG_MODULE_KEYS: OrgModuleKey[] = [
|
||||
"workflow_automations",
|
||||
"message_automations",
|
||||
"lead_forms",
|
||||
"leads",
|
||||
"project_boards",
|
||||
"inventory",
|
||||
"cheques",
|
||||
@@ -174,6 +176,7 @@ export const ORG_MODULE_LABELS: Record<OrgModuleKey, string> = {
|
||||
workflow_automations: "اتوماسیون گردش کار",
|
||||
message_automations: "اتوماسیون پیامک",
|
||||
lead_forms: "�رم‌ساز سرنخ",
|
||||
leads: "مدیریت لیدها",
|
||||
project_boards: "کاریز پروژه",
|
||||
inventory: "انبار",
|
||||
cheques: "چک‌ها",
|
||||
@@ -205,6 +208,7 @@ export const ORG_MODULE_GROUPS: Array<{
|
||||
title: "�روش",
|
||||
keys: [
|
||||
"pipeline",
|
||||
"leads",
|
||||
"products",
|
||||
"invoices",
|
||||
"quotes",
|
||||
@@ -3657,3 +3661,209 @@ export interface ReservationListResponse {
|
||||
items: ReservationAppointmentDto[];
|
||||
total: number;
|
||||
}
|
||||
|
||||
/* ——— ãÏíÑíÊ áíÏåÇ ——— */
|
||||
|
||||
export type LeadAssignRule = "round_robin" | "equal_split";
|
||||
|
||||
export interface LeadStageDto {
|
||||
id: string;
|
||||
name: string;
|
||||
position: number;
|
||||
color: string;
|
||||
showOnBoard: boolean;
|
||||
isConverted: boolean;
|
||||
isLost: boolean;
|
||||
isUnqualified: boolean;
|
||||
leadCount?: number;
|
||||
}
|
||||
|
||||
export interface CreateLeadStageRequest {
|
||||
name: string;
|
||||
color?: string;
|
||||
showOnBoard?: boolean;
|
||||
isConverted?: boolean;
|
||||
isLost?: boolean;
|
||||
isUnqualified?: boolean;
|
||||
}
|
||||
|
||||
export interface UpdateLeadStageRequest {
|
||||
name?: string;
|
||||
color?: string;
|
||||
showOnBoard?: boolean;
|
||||
isConverted?: boolean;
|
||||
isLost?: boolean;
|
||||
isUnqualified?: boolean;
|
||||
position?: number;
|
||||
}
|
||||
|
||||
export interface LeadDto {
|
||||
id: string;
|
||||
title: string;
|
||||
contactName: string | null;
|
||||
mobile: string;
|
||||
phone: string | null;
|
||||
city: string | null;
|
||||
region: string | null;
|
||||
trade: string | null;
|
||||
source: string | null;
|
||||
notes: string | null;
|
||||
estimatedValue: number | null;
|
||||
stageId: string;
|
||||
stageName: string;
|
||||
position: number;
|
||||
assigneeId: string | null;
|
||||
assigneeName: string | null;
|
||||
lastContactAt: string | null;
|
||||
nextFollowUpAt: string | null;
|
||||
convertedPersonId: string | null;
|
||||
convertedAt: string | null;
|
||||
archivedAt: string | null;
|
||||
daysInStage: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface LeadEventDto {
|
||||
id: string;
|
||||
type: string;
|
||||
title: string;
|
||||
body: string | null;
|
||||
actorId: string | null;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface CreateLeadRequest {
|
||||
title: string;
|
||||
mobile: string;
|
||||
contactName?: string | null;
|
||||
phone?: string | null;
|
||||
city?: string | null;
|
||||
region?: string | null;
|
||||
trade?: string | null;
|
||||
source?: string | null;
|
||||
notes?: string | null;
|
||||
estimatedValue?: number | null;
|
||||
stageId?: string;
|
||||
assigneeId?: string | null;
|
||||
nextFollowUpAt?: string | null;
|
||||
}
|
||||
|
||||
export interface UpdateLeadRequest {
|
||||
title?: string;
|
||||
mobile?: string;
|
||||
contactName?: string | null;
|
||||
phone?: string | null;
|
||||
city?: string | null;
|
||||
region?: string | null;
|
||||
trade?: string | null;
|
||||
source?: string | null;
|
||||
notes?: string | null;
|
||||
estimatedValue?: number | null;
|
||||
stageId?: string;
|
||||
assigneeId?: string | null;
|
||||
nextFollowUpAt?: string | null;
|
||||
lastContactAt?: string | null;
|
||||
}
|
||||
|
||||
export interface MoveLeadRequest {
|
||||
stageId: string;
|
||||
position?: number;
|
||||
}
|
||||
|
||||
export interface AssignLeadsRequest {
|
||||
leadIds: string[];
|
||||
assigneeId: string;
|
||||
}
|
||||
|
||||
export interface BulkLeadStageRequest {
|
||||
leadIds: string[];
|
||||
stageId: string;
|
||||
}
|
||||
|
||||
export interface AutoAssignLeadsRequest {
|
||||
rule?: LeadAssignRule;
|
||||
leadIds?: string[];
|
||||
assigneeIds?: string[];
|
||||
onlyUnassigned?: boolean;
|
||||
}
|
||||
|
||||
export interface LeadCallLogRequest {
|
||||
outcome?: string;
|
||||
body?: string;
|
||||
nextFollowUpAt?: string | null;
|
||||
stageId?: string;
|
||||
}
|
||||
|
||||
export interface LeadNoteRequest {
|
||||
body: string;
|
||||
}
|
||||
|
||||
export interface LeadFollowUpRequest {
|
||||
nextFollowUpAt: string;
|
||||
body?: string;
|
||||
}
|
||||
|
||||
export interface ConvertLeadRequest {
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
createIfMissing?: boolean;
|
||||
}
|
||||
|
||||
export interface ConvertLeadResult {
|
||||
lead: LeadDto;
|
||||
personId: string;
|
||||
createdPerson: boolean;
|
||||
}
|
||||
|
||||
export interface LeadDuplicateCheckResult {
|
||||
exists: boolean;
|
||||
kind: "lead" | "person" | null;
|
||||
id: string | null;
|
||||
title: string | null;
|
||||
}
|
||||
|
||||
export interface LeadImportJobDto {
|
||||
id: string;
|
||||
fileName: string | null;
|
||||
status: string;
|
||||
totalCount: number;
|
||||
processedCount: number;
|
||||
successCount: number;
|
||||
duplicateCount: number;
|
||||
errorCount: number;
|
||||
errorSamples: string[];
|
||||
startedAt: string | null;
|
||||
finishedAt: string | null;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface LeadImportRow {
|
||||
title?: string;
|
||||
contactName?: string;
|
||||
mobile?: string;
|
||||
phone?: string;
|
||||
city?: string;
|
||||
region?: string;
|
||||
trade?: string;
|
||||
source?: string;
|
||||
notes?: string;
|
||||
}
|
||||
|
||||
export interface LeadStatsDto {
|
||||
total: number;
|
||||
newCount: number;
|
||||
unassigned: number;
|
||||
byAssignee: Array<{ userId: string; fullName: string; count: number }>;
|
||||
callsLogged: number;
|
||||
withFollowUp: number;
|
||||
interested: number;
|
||||
converted: number;
|
||||
lost: number;
|
||||
conversionRate: number;
|
||||
}
|
||||
|
||||
export interface LeadBoardColumnDto {
|
||||
stage: LeadStageDto;
|
||||
leads: LeadDto[];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user