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>
154 lines
5.0 KiB
JavaScript
154 lines
5.0 KiB
JavaScript
// noqa: js-006 - async init pattern is safe, no data loading
|
|
// static/admin/js/capture.js
|
|
|
|
const captureLog = window.LogConfig.createLogger('prospecting-capture');
|
|
|
|
function quickCapture() {
|
|
return {
|
|
...data(),
|
|
|
|
currentPage: 'capture',
|
|
|
|
form: {
|
|
business_name: '',
|
|
phone: '',
|
|
email: '',
|
|
address: '',
|
|
city: '',
|
|
postal_code: '',
|
|
source: 'street',
|
|
notes: '',
|
|
tags: [],
|
|
location_lat: null,
|
|
location_lng: null,
|
|
},
|
|
|
|
sources: [
|
|
{ value: 'street', label: 'Street' },
|
|
{ value: 'networking_event', label: 'Networking' },
|
|
{ value: 'referral', label: 'Referral' },
|
|
{ value: 'other', label: 'Other' },
|
|
],
|
|
|
|
availableTags: [
|
|
'no-website', 'gmail', 'restaurant', 'retail', 'services',
|
|
'professional', 'construction', 'beauty', 'food',
|
|
],
|
|
|
|
submitting: false,
|
|
saved: false,
|
|
lastSaved: '',
|
|
gettingLocation: false,
|
|
recentCaptures: [],
|
|
|
|
async init() {
|
|
await I18n.loadModule('prospecting');
|
|
|
|
if (window._captureInit) return;
|
|
window._captureInit = true;
|
|
|
|
captureLog.info('Quick capture initializing');
|
|
},
|
|
|
|
toggleTag(tag) {
|
|
const idx = this.form.tags.indexOf(tag);
|
|
if (idx >= 0) {
|
|
this.form.tags.splice(idx, 1);
|
|
} else {
|
|
this.form.tags.push(tag);
|
|
}
|
|
},
|
|
|
|
getLocation() {
|
|
if (!navigator.geolocation) {
|
|
Utils.showToast('Geolocation not supported', 'error');
|
|
return;
|
|
}
|
|
this.gettingLocation = true;
|
|
navigator.geolocation.getCurrentPosition(
|
|
(pos) => {
|
|
this.form.location_lat = pos.coords.latitude;
|
|
this.form.location_lng = pos.coords.longitude;
|
|
this.gettingLocation = false;
|
|
captureLog.info('Location acquired', pos.coords);
|
|
},
|
|
(err) => {
|
|
this.gettingLocation = false;
|
|
Utils.showToast('Location error: ' + err.message, 'error');
|
|
captureLog.error('Geolocation error', err);
|
|
},
|
|
{ enableHighAccuracy: true, timeout: 10000 },
|
|
);
|
|
},
|
|
|
|
async submitCapture() {
|
|
if (!this.form.business_name) {
|
|
Utils.showToast('Business name is required', 'error');
|
|
return;
|
|
}
|
|
|
|
this.submitting = true;
|
|
try {
|
|
const payload = {
|
|
channel: 'offline',
|
|
business_name: this.form.business_name,
|
|
source: this.form.source,
|
|
notes: this.form.notes,
|
|
tags: this.form.tags.length > 0 ? this.form.tags : null,
|
|
address: this.form.address || null,
|
|
city: this.form.city || null,
|
|
postal_code: this.form.postal_code || null,
|
|
location_lat: this.form.location_lat,
|
|
location_lng: this.form.location_lng,
|
|
contacts: [],
|
|
};
|
|
|
|
if (this.form.phone) {
|
|
payload.contacts.push({ contact_type: 'phone', value: this.form.phone });
|
|
}
|
|
if (this.form.email) {
|
|
payload.contacts.push({ contact_type: 'email', value: this.form.email });
|
|
}
|
|
|
|
const result = await apiClient.post('/admin/prospecting/prospects', payload);
|
|
|
|
this.lastSaved = this.form.business_name;
|
|
this.recentCaptures.unshift({
|
|
id: result.id,
|
|
business_name: this.form.business_name,
|
|
city: this.form.city,
|
|
source: this.form.source,
|
|
});
|
|
|
|
this.saved = true;
|
|
setTimeout(() => { this.saved = false; }, 3000);
|
|
|
|
this.resetForm();
|
|
Utils.showToast('Prospect saved!', 'success');
|
|
captureLog.info('Capture saved', result.id);
|
|
} catch (err) {
|
|
Utils.showToast('Failed: ' + err.message, 'error');
|
|
captureLog.error('Capture failed', err);
|
|
} finally {
|
|
this.submitting = false;
|
|
}
|
|
},
|
|
|
|
resetForm() {
|
|
this.form = {
|
|
business_name: '',
|
|
phone: '',
|
|
email: '',
|
|
address: '',
|
|
city: this.form.city, // Keep city for rapid captures in same area
|
|
postal_code: this.form.postal_code,
|
|
source: this.form.source,
|
|
notes: '',
|
|
tags: [],
|
|
location_lat: this.form.location_lat, // Keep GPS
|
|
location_lng: this.form.location_lng,
|
|
};
|
|
},
|
|
};
|
|
}
|