Private Contractor Leads & CRM Vault

Authorized Joshua / ToolsVault Admin Only

Secure Edge & Client-Side Storage

+ (leads.length * 75).toLocaleString() + ' Est. Dispatch Value'; document.getElementById('stat-briefings-count').textContent = briefings.length; document.getElementById('stat-subs-count').textContent = subs.length; document.getElementById('tab-leads-badge').textContent = leads.length; document.getElementById('tab-briefings-badge').textContent = briefings.length; document.getElementById('tab-subs-badge').textContent = subs.length; renderActiveTab(); } function renderActiveTab() { const q = (document.getElementById('vault-search-box')?.value || '').toLowerCase(); const thead = document.getElementById('table-head'); const tbody = document.getElementById('table-body'); tbody.innerHTML = ''; if (currentTab === 'leads') { document.getElementById('table-title').innerHTML = ' Contractor Bids & Direct Quote Inquiries'; document.getElementById('table-subtitle').textContent = 'Captured from localized quote widgets across calculators'; thead.innerHTML = ` Lead ID & Date Company / Name Direct Contact ZIP & Trade Budget / Scope Status Actions `; let leads = getStoredLeads(); if (q) { leads = leads.filter(l => ( (l.id && l.id.toLowerCase().includes(q)) || (l.name && l.name.toLowerCase().includes(q)) || (l.email && l.email.toLowerCase().includes(q)) || (l.phone && l.phone.toLowerCase().includes(q)) || (l.zip && l.zip.includes(q)) || (l.trade && l.trade.toLowerCase().includes(q)) || (l.notes && l.notes.toLowerCase().includes(q)) )); } if (leads.length === 0) { tbody.innerHTML = `No contractor bids found.`; return; } leads.forEach((l, idx) => { const tr = document.createElement('tr'); tr.className = 'hover:bg-slate-900/50 transition'; const dateStr = l.timestamp ? new Date(l.timestamp).toLocaleDateString() + ' ' + new Date(l.timestamp).toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}) : 'N/A'; const emailLink = l.email ? `${l.email}` : 'No email'; const phoneLink = l.phone ? `${l.phone}` : ''; tr.innerHTML = ` ${l.id || 'LEAD-' + idx} ${dateStr} ${l.name || 'Anonymous Client'} ${emailLink}${phoneLink} ${l.zip || 'N/A'} ${l.trade || 'General'} ${l.budget || 'Not Specified'} ${l.notes ? `` : ''} `; tbody.appendChild(tr); }); } else if (currentTab === 'briefings') { document.getElementById('table-title').innerHTML = ' Territory Consultation & Briefing Bookings'; document.getElementById('table-subtitle').textContent = 'Direct appointments booked with John Granbridge (toolsvault78@gmail.com)'; thead.innerHTML = ` Appointment Date & Time Company & Contact Format Trade & Territory ZIP Target Size & Labor Notes Actions `; let briefings = getStoredBriefings(); if (q) { briefings = briefings.filter(b => ( (b.company_name && b.company_name.toLowerCase().includes(q)) || (b.contact_person && b.contact_person.toLowerCase().includes(q)) || (b.email && b.email.toLowerCase().includes(q)) || (b.phone && b.phone.toLowerCase().includes(q)) || (b.territory_zip && b.territory_zip.includes(q)) || (b.trade_division && b.trade_division.toLowerCase().includes(q)) )); } if (briefings.length === 0) { tbody.innerHTML = `No territory briefings booked yet.`; return; } briefings.forEach((b, idx) => { const tr = document.createElement('tr'); tr.className = 'hover:bg-slate-900/50 transition'; const emailLink = b.email ? `${b.email}` : ''; const phoneLink = b.phone ? `${b.phone}` : ''; tr.innerHTML = ` ${b.consultation_date || 'Date TBD'} ${b.time_slot || 'Time TBD'} ${b.company_name || 'N/A'} ${b.contact_person || 'Estimating'}
${emailLink}${phoneLink}
${b.meeting_format || 'Phone Call'} ${b.territory_zip || 'N/A'} ${b.trade_division || 'Commercial'} ${b.project_size_target || 'N/A'} ${b.labor_structure || ''} ${b.bonding_capacity ? `Bond: ${b.bonding_capacity}` : ''} ${b.notes ? `` : '—'} `; tbody.appendChild(tr); }); } else if (currentTab === 'subs') { document.getElementById('table-title').innerHTML = ' Deliverable & Cheat Sheet Subscribers'; document.getElementById('table-subtitle').textContent = 'Captured from weekly brief bar across all 1,027 calculation tools'; thead.innerHTML = ` Subscriber ID Date & Time Email Address Requested Lead Magnet Source Calculator Actions `; let subs = getStoredSubs(); if (q) { subs = subs.filter(s => ( (s.id && s.id.toLowerCase().includes(q)) || (s.email && s.email.toLowerCase().includes(q)) || (s.leadMagnet && s.leadMagnet.toLowerCase().includes(q)) || (s.source && s.source.toLowerCase().includes(q)) )); } if (subs.length === 0) { tbody.innerHTML = `No subscribers captured yet.`; return; } subs.forEach((s, idx) => { const tr = document.createElement('tr'); tr.className = 'hover:bg-slate-900/50 transition'; const dateStr = s.timestamp ? new Date(s.timestamp).toLocaleDateString() + ' ' + new Date(s.timestamp).toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}) : 'N/A'; tr.innerHTML = ` ${s.id || 'SUB-' + idx} ${dateStr} ${s.email} ${s.leadMagnet || 'Institutional Cheat Sheet'} ${s.source || '/'} `; tbody.appendChild(tr); }); } } function viewNotes(category, title, content) { document.getElementById('modal-category').textContent = category; document.getElementById('modal-title').textContent = title || 'Details'; document.getElementById('modal-content').innerHTML = `
${content}
`; document.getElementById('detail-modal').classList.remove('hidden'); } function closeDetailModal() { document.getElementById('detail-modal').classList.add('hidden'); } function updateLeadStatus(idx, newStatus) { const leads = getStoredLeads(); if (leads[idx]) { leads[idx].status = newStatus; localStorage.setItem('tv_contractor_leads_log', JSON.stringify(leads)); } } function deleteLead(idx) { if (confirm('Delete this contractor lead?')) { const leads = getStoredLeads(); leads.splice(idx, 1); localStorage.setItem('tv_contractor_leads_log', JSON.stringify(leads)); refreshAllData(); } } function deleteBriefing(idx) { if (confirm('Delete this territory consultation booking?')) { const briefings = getStoredBriefings(); briefings.splice(idx, 1); localStorage.setItem('tv_territory_bookings', JSON.stringify(briefings)); refreshAllData(); } } function deleteSub(idx) { if (confirm('Delete this subscriber?')) { const subs = getStoredSubs(); subs.splice(idx, 1); localStorage.setItem('tv_subscribers_log', JSON.stringify(subs)); refreshAllData(); } } function clearActiveTab() { const tabName = currentTab === 'leads' ? 'Contractor Bids' : (currentTab === 'briefings' ? 'Territory Consultations' : 'Subscribers'); if (confirm(`Clear all stored records in ${tabName}?`)) { if (currentTab === 'leads') localStorage.removeItem('tv_contractor_leads_log'); if (currentTab === 'briefings') localStorage.removeItem('tv_territory_bookings'); if (currentTab === 'subs') localStorage.removeItem('tv_subscribers_log'); refreshAllData(); } } async function fetchEdgeLeads() { try { const res = await fetch('/api/lead-capture?pin=' + encodeURIComponent(DEFAULT_PIN)); if (res.ok) { const data = await res.json(); if (data && data.leads && data.leads.length > 0) { const local = getStoredLeads(); const existingIds = new Set(local.map(l => l.id)); let added = 0; for (const el of data.leads) { if (el.id && !existingIds.has(el.id)) { local.unshift(el); added++; } } if (added > 0) { localStorage.setItem('tv_contractor_leads_log', JSON.stringify(local.slice(0, 500))); refreshAllData(); alert(`Synced ${added} new leads from Cloudflare Pages Edge!`); return; } } alert('Local leads are already synchronized with Edge.'); } else { alert('Edge sync response: ' + res.status); } } catch(err) { alert('Edge leads fetch offline or unavailable.'); } } function exportActiveTabCsv() { if (currentTab === 'leads') { const leads = getStoredLeads(); if (leads.length === 0) return alert('No contractor leads to export.'); let csv = 'Lead ID,Timestamp,Company/Name,Email,Phone,ZIP Code,Trade,Budget,Notes,Originating Page,Status,Est Value\n'; leads.forEach(l => { csv += `"${l.id||''}","${l.timestamp||''}","${(l.name||'').replace(/"/g,'""')}","${l.email||''}","${l.phone||''}","${l.zip||''}","${l.trade||''}","${l.budget||''}","${(l.notes||'').replace(/"/g,'""')}","${l.page||''}","${l.status||'New'}","$75"\n`; }); downloadCsvBlob(csv, 'toolsvault_contractor_bids_' + getTodayStr() + '.csv'); } else if (currentTab === 'briefings') { const briefings = getStoredBriefings(); if (briefings.length === 0) return alert('No territory briefings to export.'); let csv = 'Event,Date,Time Slot,Format,Company,Contact Person,Phone,Email,Territory ZIP,Trade Division,Target Size,Labor,Bonding,Notes,Timestamp\n'; briefings.forEach(b => { csv += `"${b.event||''}","${b.consultation_date||''}","${b.time_slot||''}","${b.meeting_format||''}","${(b.company_name||'').replace(/"/g,'""')}","${(b.contact_person||'').replace(/"/g,'""')}","${b.phone||''}","${b.email||''}","${b.territory_zip||''}","${b.trade_division||''}","${b.project_size_target||''}","${b.labor_structure||''}","${b.bonding_capacity||''}","${(b.notes||'').replace(/"/g,'""')}","${b.timestamp||''}"\n`; }); downloadCsvBlob(csv, 'toolsvault_territory_briefings_' + getTodayStr() + '.csv'); } else if (currentTab === 'subs') { const subs = getStoredSubs(); if (subs.length === 0) return alert('No subscribers to export.'); let csv = 'Subscriber ID,Timestamp,Email,Lead Magnet,Source URL\n'; subs.forEach(s => { csv += `"${s.id||''}","${s.timestamp||''}","${s.email||''}","${(s.leadMagnet||'').replace(/"/g,'""')}","${s.source||''}"\n`; }); downloadCsvBlob(csv, 'toolsvault_subscribers_' + getTodayStr() + '.csv'); } } function downloadCsvBlob(csv, filename) { const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); } function getTodayStr() { return new Date().toISOString().split('T')[0]; } function escapeHtml(str) { return String(str || '').replace(/'/g, "\\'").replace(/"/g, '"'); } function seedSampleLeads() { const sampleLeads = [ { id: 'LEAD-9B7C12', name: 'Apex Commercial Solar LLC', email: 'bids@apexsolar.com', phone: '(512) 555-0144', timestamp: new Date(Date.now() - 3600000).toISOString(), zip: '78701', trade: 'Solar & Battery Storage', budget: '$100,000 - $500,000', notes: 'Looking for 300kW rooftop solar + 500kWh BESS commercial proposal in Austin metro.', page: '/solar_energy_storage_calculators', status: 'New / Unclaimed' }, { id: 'LEAD-3K8F45', name: 'Metro Mechanical Systems', email: 'estimating@metromechanical.com', phone: '(404) 555-0199', timestamp: new Date(Date.now() - 14400000).toISOString(), zip: '30301', trade: 'Commercial Mechanical & HVAC', budget: '$500,000+ (Commercial)', notes: 'Bidding 4-story medical office chiller replacement and VAV retrofit.', page: '/contractor_fabrication_calculators', status: 'Contacted' }, { id: 'LEAD-7M2A89', name: 'Gulf Coast Roofing Specialists', email: 'sales@gulfcoastroof.com', phone: '(305) 555-0182', timestamp: new Date(Date.now() - 86400000).toISOString(), zip: '33101', trade: 'Commercial Roofing', budget: '$100,000 - $500,000', notes: 'Need 60,000 sq ft TPO 60-mil single-ply reroof specification.', page: '/contractor_fabrication_calculators', status: 'Dispatched' } ]; const sampleBriefings = [ { event: 'COMMERCIAL_TERRITORY_BRIEFING_BOOKED', company_name: 'Vanguard Electrical Prime', contact_person: 'Mark Henderson (VP Precon)', phone: '(512) 555-0188', email: 'mhenderson@vanguardelec.com', territory_zip: '78701', trade_division: 'Commercial Electrical', consultation_date: '2026-10-07', time_slot: '10:30 AM EST', meeting_format: 'Phone Call', project_size_target: '$500,000 - $2,000,000', labor_structure: 'Open Shop (Merit)', bonding_capacity: '$5M Single / $15M Aggregate', notes: 'Interested in locking exclusive Division 26 territory placement for Travis County.', timestamp: new Date().toISOString() } ]; const sampleSubs = [ { id: 'SUB-A1B2C3', email: 'precon@turner-demo.com', timestamp: new Date(Date.now() - 7200000).toISOString(), source: '/commercial_subcontractor_bid_estimator', leadMagnet: 'Get the 2026 CSI-16 Contractor Estimating & Labor Rate Guide' } ]; localStorage.setItem('tv_contractor_leads_log', JSON.stringify(sampleLeads)); localStorage.setItem('tv_territory_bookings', JSON.stringify(sampleBriefings)); localStorage.setItem('tv_subscribers_log', JSON.stringify(sampleSubs)); refreshAllData(); alert('Sample test data seeded across all 3 tabs!'); }