Some checks failed
Migrates scanning pipeline from marketing-.lu-domains app into Orion module. Supports digital (domain scan) and offline (manual capture) lead channels with enrichment, scoring, campaign management, and interaction tracking. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
138 lines
4.4 KiB
JavaScript
138 lines
4.4 KiB
JavaScript
// static/admin/js/campaigns.js
|
|
|
|
const campLog = window.LogConfig.createLogger('prospecting-campaigns');
|
|
|
|
function campaignManager() {
|
|
return {
|
|
...data(),
|
|
|
|
currentPage: 'campaigns',
|
|
|
|
templates: [],
|
|
loading: true,
|
|
error: null,
|
|
filterLeadType: '',
|
|
|
|
showCreateModal: false,
|
|
showEditModal: false,
|
|
editingTemplateId: null,
|
|
|
|
templateForm: {
|
|
name: '',
|
|
lead_type: 'no_website',
|
|
channel: 'email',
|
|
language: 'fr',
|
|
subject_template: '',
|
|
body_template: '',
|
|
is_active: true,
|
|
},
|
|
|
|
leadTypes: [
|
|
{ value: 'no_website', label: 'No Website' },
|
|
{ value: 'bad_website', label: 'Bad Website' },
|
|
{ value: 'gmail_only', label: 'Gmail Only' },
|
|
{ value: 'security_issues', label: 'Security Issues' },
|
|
{ value: 'performance_issues', label: 'Performance Issues' },
|
|
{ value: 'outdated_cms', label: 'Outdated CMS' },
|
|
{ value: 'general', label: 'General' },
|
|
],
|
|
|
|
placeholders: [
|
|
'{business_name}', '{domain}', '{score}', '{issues}',
|
|
'{primary_email}', '{primary_phone}', '{city}',
|
|
],
|
|
|
|
async init() {
|
|
await I18n.loadModule('prospecting');
|
|
|
|
if (window._campaignsInit) return;
|
|
window._campaignsInit = true;
|
|
|
|
campLog.info('Campaign manager initializing');
|
|
await this.loadTemplates();
|
|
},
|
|
|
|
async loadTemplates() {
|
|
this.loading = true;
|
|
this.error = null;
|
|
try {
|
|
const response = await apiClient.get('/admin/prospecting/campaigns/templates');
|
|
this.templates = response.items || response || [];
|
|
} catch (err) {
|
|
this.error = err.message;
|
|
campLog.error('Failed to load templates', err);
|
|
} finally {
|
|
this.loading = false;
|
|
}
|
|
},
|
|
|
|
filteredTemplates() {
|
|
if (!this.filterLeadType) return this.templates;
|
|
return this.templates.filter(t => t.lead_type === this.filterLeadType);
|
|
},
|
|
|
|
editTemplate(tpl) {
|
|
this.editingTemplateId = tpl.id;
|
|
this.templateForm = {
|
|
name: tpl.name,
|
|
lead_type: tpl.lead_type,
|
|
channel: tpl.channel,
|
|
language: tpl.language,
|
|
subject_template: tpl.subject_template || '',
|
|
body_template: tpl.body_template,
|
|
is_active: tpl.is_active,
|
|
};
|
|
this.showEditModal = true;
|
|
},
|
|
|
|
async saveTemplate() {
|
|
try {
|
|
if (this.showEditModal && this.editingTemplateId) {
|
|
await apiClient.put(
|
|
'/admin/prospecting/campaigns/templates/' + this.editingTemplateId,
|
|
this.templateForm,
|
|
);
|
|
Utils.showToast('Template updated', 'success');
|
|
} else {
|
|
await apiClient.post('/admin/prospecting/campaigns/templates', this.templateForm);
|
|
Utils.showToast('Template created', 'success');
|
|
}
|
|
this.showCreateModal = false;
|
|
this.showEditModal = false;
|
|
this.resetForm();
|
|
await this.loadTemplates();
|
|
} catch (err) {
|
|
Utils.showToast('Failed: ' + err.message, 'error');
|
|
}
|
|
},
|
|
|
|
async deleteTemplate(id) {
|
|
if (!confirm('Delete this template?')) return;
|
|
try {
|
|
await apiClient.delete('/admin/prospecting/campaigns/templates/' + id);
|
|
Utils.showToast('Template deleted', 'success');
|
|
await this.loadTemplates();
|
|
} catch (err) {
|
|
Utils.showToast('Failed: ' + err.message, 'error');
|
|
}
|
|
},
|
|
|
|
insertPlaceholder(ph) {
|
|
this.templateForm.body_template += ph;
|
|
},
|
|
|
|
resetForm() {
|
|
this.editingTemplateId = null;
|
|
this.templateForm = {
|
|
name: '',
|
|
lead_type: 'no_website',
|
|
channel: 'email',
|
|
language: 'fr',
|
|
subject_template: '',
|
|
body_template: '',
|
|
is_active: true,
|
|
};
|
|
},
|
|
};
|
|
}
|