import CrmRoute from "../routes/CrmRoute"; import Requests from "../util/Requests"; import Response from "../util/Response"; import { AxiosPromise, AxiosProgressEvent } from "axios"; class Crm { /** * List and search CRM leads. */ public static listLeads(params?: Record): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.listLeads, undefined, undefined, params); } /** * Manually create a new lead. */ public static createLead(data: object): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.createLead, data); } /** * View a single lead with contacts and activity timeline. */ public static viewLead(lead_id: string): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.viewLead, {}, { lead_id }); } /** * Update lead information. */ public static updateLead(lead_id: string, data: object): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.updateLead, data, { lead_id }); } /** * Delete a lead (Soft Delete). */ public static deleteLead(lead_id: string): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.deleteLead, {}, { lead_id }); } /** * Assign a Super Admin as the owner of a lead. */ public static assignOwner(lead_id: string, user_id: string): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.assignOwner, { user_id }, { lead_id }); } /** * Manually trigger Apollo enrichment and website scraping for a lead. */ public static enrichLead(lead_id: string): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.enrichLead, {}, { lead_id }); } /** * Approve a specific contact to start the Apollo email sequence. */ public static approveContact(contact_id: string): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.approveContact, {}, { contact_id }); } /** * Manually update the pipeline status of a lead. */ public static updateStatus(lead_id: string, status: string, note?: string): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.updateStatus, { status, note }, { lead_id }); } /** * Add a manual note to the lead's activity timeline. */ public static addNote(lead_id: string, content: string): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.addNote, { content }, { lead_id }); } /** * Manually add a contact person to a lead. */ public static addContact(lead_id: string, data: object): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.addContact, data, { lead_id }); } /** * Mark a lead as lost and record the reason. */ public static markAsLost(lead_id: string, reason: string): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.markAsLost, { reason }, { lead_id }); } /** * Record that a staff member has manually replied to a prospect. */ public static recordStaffReply(lead_id: string): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.recordStaffReply, {}, { lead_id }); } /** * Approve a batch of contacts for outreach. */ public static bulkApprove(contact_ids: string[]): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.bulkApprove, { contact_ids }); } /** * Manually trigger the bi-weekly sourcing automation. */ public static triggerSourcing(): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.triggerSourcing, {}); } /** * Manually trigger the Apollo status and conversion sync. */ public static triggerSync(): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.triggerSync, {}); } /** * Get funnel conversion percentages. */ public static getFunnelStats(): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.funnelStats); } /** * Get win rates and response time analytics. */ public static getPerformanceStats(): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.performanceStats); } /** * Get the analytics on what users indcated they were interested in. */ public static getInterestStats(): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.getInterestStats); } /** * Update an existing contact's information. */ public static updateContact(contact_id: string, data: object): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.updateContact, data, { contact_id }); } /** * Remove a contact from a lead. */ public static deleteContact(contact_id: string): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.deleteContact, {}, { contact_id }); } /** * List CRM newsletter and mass-email campaigns. */ public static listCampaigns(params?: Record): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.listCampaigns, undefined, undefined, params); } /** * Create a CRM campaign draft with filters, exclusions, and optional variants. */ public static createCampaign(data: object): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.createCampaign, data); } /** * View a CRM campaign. Pass include_recipients in params for a small recipient sample. */ public static viewCampaign(campaign_id: string, params?: Record): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.viewCampaign, {}, { campaign_id }, params); } /** * Update an editable CRM campaign draft or paused campaign. */ public static updateCampaign(campaign_id: string, data: object): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.updateCampaign, data, { campaign_id }); } /** * Delete an unsent CRM campaign draft. */ public static deleteCampaign(campaign_id: string): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.deleteCampaign, {}, { campaign_id }); } /** * Preview campaign audience filters and exclusions without creating recipients. */ public static previewCampaignAudience(data: object): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.previewCampaignAudience, data); } /** * List human-readable filter options for the CRM campaign composer. */ public static getCampaignFilterOptions(): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.getCampaignFilterOptions); } /** * List the backend-supported CRM campaign merge fields for the composer. */ public static getCampaignMergeFields(): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.getCampaignMergeFields); } /** * Render CRM campaign content with the same merge-field engine used at send time. */ public static renderCampaignTemplatePreview(data: object): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.renderCampaignTemplatePreview, data); } /** * Send a non-tracked CRM campaign test email with rendered merge fields. */ public static sendCampaignTestEmail(data: object): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.sendCampaignTestEmail, data); } /** * Read CRM campaign queue depth and Azure/system email rate-limit windows. */ public static getCampaignDeliveryStatus(): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.getCampaignDeliveryStatus); } /** * Materialize and queue a CRM campaign, optionally with a limit or dispatch=false. */ public static sendCampaign(campaign_id: string, data: object = {}): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.sendCampaign, data, { campaign_id }); } /** * Refresh and read CRM campaign engagement, reply, and conversion stats. */ public static getCampaignStats(campaign_id: string): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.getCampaignStats, {}, { campaign_id }); } /** * List campaign recipient audit rows with optional status or variant filters. */ public static listCampaignRecipients(campaign_id: string, params?: Record): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.listCampaignRecipients, {}, { campaign_id }, params); } /** * Validate external prospect rows and preview field mapping/dedupe outcomes. */ public static previewCampaignProspectImport(prospects: object[], options: Record = {}): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.previewCampaignProspectImport, { prospects, ...options }); } /** * Import external prospects into CRM leads and contacts for future campaigns. */ public static importCampaignProspects(prospects: object[], options: Record = {}): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.importCampaignProspects, { prospects, ...options }); } /** * Preview uploaded festival submission sheets without writing External Game or CRM records. */ public static previewFestivalSubmissionImport( files: Array, options: Record = {}, onUploadProgress?: (progressEvent: AxiosProgressEvent) => void ): AxiosPromise> { return Requests.postFormData( CrmRoute.routes.previewFestivalSubmissionImport.url, Crm.festivalSubmissionFormData(files, options), undefined, onUploadProgress ); } /** * Import uploaded festival submission sheets into External Games and CRM leads/contacts. */ public static importFestivalSubmissions( files: Array, options: Record = {}, onUploadProgress?: (progressEvent: AxiosProgressEvent) => void ): AxiosPromise> { return Requests.postFormData( CrmRoute.routes.importFestivalSubmissions.url, Crm.festivalSubmissionFormData(files, options), undefined, onUploadProgress ); } /** * List saved recurring Google Sheet sources for festival submission imports. */ public static listFestivalSubmissionSources(): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.listFestivalSubmissionSources); } /** * Save a recurring Google Sheet source for festival submission imports. */ public static createFestivalSubmissionSource(data: object): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.createFestivalSubmissionSource, data); } /** * Update a recurring Google Sheet source for festival submission imports. */ public static updateFestivalSubmissionSource(source_id: string, data: object): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.updateFestivalSubmissionSource, data, { source_id }); } /** * Delete a recurring Google Sheet source for festival submission imports. */ public static deleteFestivalSubmissionSource(source_id: string): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.deleteFestivalSubmissionSource, {}, { source_id }); } /** * List provider-managed sender and reply-to addresses for CRM campaigns. */ public static listEmailProviderAddresses(params?: Record): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.listEmailProviderAddresses, undefined, undefined, params); } /** * List sender/reply-to dropdown options and defaults for the campaign composer. */ public static getEmailProviderAddressOptions(): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.getEmailProviderAddressOptions); } /** * Add a provider-managed sender or reply-to address. */ public static createEmailProviderAddress(data: object): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.createEmailProviderAddress, data); } /** * Update provider verification, sendability, capabilities, defaults, or notes. */ public static updateEmailProviderAddress(address_id: string, data: object): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.updateEmailProviderAddress, data, { address_id }); } /** * Deactivate a provider address while keeping the audit record. */ public static deactivateEmailProviderAddress(address_id: string): AxiosPromise> { return Requests.processRoute(CrmRoute.routes.deactivateEmailProviderAddress, {}, { address_id }); } private static festivalSubmissionFormData(files: Array, options: Record): FormData { const formData = new FormData(); files.forEach((file, index) => { const candidate = file as any; formData.append('files[]', file as any, candidate?.name || `festival-submission-${index + 1}`); }); Object.entries(options || {}).forEach(([key, value]) => { if (value === undefined || value === null) { return; } if (Array.isArray(value)) { value.forEach((item) => formData.append(`${key}[]`, String(item))); return; } formData.append(key, typeof value === 'boolean' ? (value ? '1' : '0') : String(value)); }); return formData; } } export default Crm;