fix(radar): open camera intelligence & directory records in-map, eliminate view switching

This commit is contained in:
2026-09-12 09:39:07 -07:00
parent fef8ab6417
commit 0e47dfa1d8
4 changed files with 199 additions and 42 deletions
+3
View File
@@ -569,6 +569,9 @@
}
}
// Global access so radar map can open agency modal without switching views
window.openAgencyModal = openAgencyModal;
function renderModalSharingTags(sharedIds, query) {
if (!sharedIds || sharedIds.length === 0) {
el.modalSharingBox.innerHTML = `<span style="font-size: 0.8rem; color: var(--text-dim); padding: 8px;">No external sharing partners published on portal.</span>`;
+120 -26
View File
@@ -423,14 +423,9 @@
${cam.notes ? `<br><span><em>${escapeHtml(cam.notes)}</em></span>` : ''}
</div>
<div style="display: flex; flex-direction: column; gap: 6px; margin-top: 10px;">
<button class="popup-inspect-btn" style="background: linear-gradient(135deg, #06b6d4, #0284c7); color: #fff; font-weight: 600;" onclick="window.openCameraHardwareProof('${escapeHtml(cam.id)}')">
📸 View Hardware Proof & Vote
<button class="popup-inspect-btn" style="background: linear-gradient(135deg, #06b6d4, #0284c7); color: #fff; font-weight: 700; width: 100%; border: none; border-radius: 6px; padding: 10px; cursor: pointer; box-shadow: 0 2px 8px rgba(6, 182, 212, 0.4);" onclick="window.openCameraHardwareProof('${escapeHtml(cam.id)}')">
📸 View Camera Info & Agency Records
</button>
${cam.slug ? `
<button class="popup-inspect-btn" onclick="window.inspectPortal('${escapeHtml(cam.slug)}')">
Inspect Agency Records & Sharing ↗
</button>
` : ''}
${(!cam.id.startsWith('portal-') && (cam.isCommunity || cam.id.startsWith('rpt-') || cam.id.startsWith('usr-pin-') || cam.id.startsWith('test-') || cam.id.startsWith('cam-test-') || cam.notes === '1-Tap Mobile Driver Pin' || cam.agency === 'Crowdsourced Report' || cam.name.includes('Community Report'))) ? `
<button class="popup-inspect-btn popup-delete-btn" style="background: #dc2626 !important; color: #ffffff !important; font-weight: 800 !important; font-size: 0.88rem !important; padding: 10px 14px !important; border-radius: 6px !important; margin-top: 6px !important; display: flex !important; align-items: center !important; justify-content: center !important; gap: 8px !important; border: none !important; cursor: pointer !important; box-shadow: 0 3px 10px rgba(220, 38, 38, 0.45) !important;" onclick="window.adminDeleteCamera('${escapeHtml(cam.id)}')">
<span style="font-size: 1rem;">🗑️</span>
@@ -443,9 +438,9 @@
marker.bindPopup(popupHtml);
// Clicking marker directly opens the full hardware proof modal
marker.on('click', () => {
// Leaflet will open popup, but user can also click proof button directly
// Clicking radar circle zone directly opens the camera intelligence sheet
radarCircle.on('click', () => {
openCameraHardwareProof(cam.id);
});
cameraCircles.push(radarCircle);
@@ -1397,19 +1392,116 @@
el.btnProofNavigate.href = `https://www.google.com/maps/dir/?api=1&destination=${cam.lat},${cam.lng}`;
}
// Transparency Portal Link
const portalBox = document.getElementById('proof-portal-link-box');
if (portalBox) {
// Lookup Directory Intelligence for this camera & agency
let portal = null;
if (window.FLOCK_DATA && window.FLOCK_DATA.portals) {
if (cam.slug) {
portalBox.style.display = 'block';
if (el.btnProofOpenPortal) {
el.btnProofOpenPortal.onclick = () => {
closeCameraDetailModal();
window.inspectPortal(cam.slug);
};
portal = window.FLOCK_DATA.portals.find(p => p.slug === cam.slug);
}
if (!portal && cam.agency) {
portal = window.FLOCK_DATA.portals.find(p =>
(p.name && p.name.toLowerCase().includes(cam.agency.toLowerCase())) ||
(cam.agency.toLowerCase().includes((p.name || '').toLowerCase()))
);
}
}
// Populate Directory Intelligence Fields
const elDirCameras = document.getElementById('proof-dir-cameras');
const elDirVolume = document.getElementById('proof-dir-volume');
const elDirSearches = document.getElementById('proof-dir-searches');
const elDirRetention = document.getElementById('proof-dir-retention');
const elDirSharingCount = document.getElementById('proof-dir-sharing-count');
const elDirSharingTags = document.getElementById('proof-dir-sharing-tags');
const elDirReasonsBox = document.getElementById('proof-dir-reasons-box');
const elDirReasonsList = document.getElementById('proof-dir-reasons-list');
const elOfficialPortalBtn = document.getElementById('btn-proof-official-portal');
const elPortalText = document.getElementById('btn-proof-portal-text');
if (portal) {
// Official scraped portal record
if (elDirCameras) elDirCameras.textContent = portal.cameras ? `${portal.cameras.toLocaleString()} in Fleet` : `${cam.cameras || 4} at Node`;
if (elDirVolume) elDirVolume.textContent = portal.vehicles_captured ? `${portal.vehicles_captured.toLocaleString()} Reads` : (cam.captures30d ? `${cam.captures30d} Reads` : '300,000+');
if (elDirSearches) elDirSearches.textContent = portal.searches ? `${portal.searches.toLocaleString()} Queries` : 'Automated Hotlist';
if (elDirRetention) elDirRetention.textContent = '30 Days Auto-Purge';
const sharedIds = portal.shared_org_ids || [];
if (elDirSharingCount) elDirSharingCount.textContent = `${sharedIds.length} Partner Agencies`;
if (elDirSharingTags) {
const orgsLookup = (window.FLOCK_DATA && window.FLOCK_DATA.orgs) || [];
const topShared = sharedIds.slice(0, 15).map(id => orgsLookup[id] || `Agency #${id}`);
elDirSharingTags.innerHTML = topShared.map(name => `
<span style="background: rgba(56, 189, 248, 0.1); border: 1px solid rgba(56, 189, 248, 0.25); color: #93c5fd; padding: 2px 7px; border-radius: 6px; font-size: 0.7rem;">${escapeHtml(name)}</span>
`).join('') + (sharedIds.length > 15 ? `<span style="font-size: 0.68rem; color: #64748b; align-self: center;">+${sharedIds.length - 15} more</span>` : '');
}
if (elDirReasonsList && elDirReasonsBox) {
const reasons = portal.top_search_reasons || {};
const entries = Object.entries(reasons).slice(0, 4);
if (entries.length > 0) {
elDirReasonsBox.style.display = 'block';
elDirReasonsList.innerHTML = entries.map(([r, count]) => `
<div style="display: flex; justify-content: space-between;">
<span>• ${escapeHtml(r)}</span>
<span style="color: #38bdf8; font-weight: 600;">${count.toLocaleString()} searches</span>
</div>
`).join('');
} else {
elDirReasonsBox.style.display = 'none';
}
} else {
portalBox.style.display = 'none';
}
if (elOfficialPortalBtn && elPortalText) {
elOfficialPortalBtn.href = portal.url || `https://transparency.flocksafety.com/${portal.slug}`;
elPortalText.textContent = `Open Official ${portal.name} Transparency Portal ↗`;
}
} else {
// Local Antelope Valley / Sheriff corridor or Community Camera
const defaultCameras = cam.cameras || (cam.id && cam.id.includes('plm') ? 4 : 2);
const defaultCaptures = cam.captures30d ? `${cam.captures30d} Reads` : '285,000 Reads';
if (elDirCameras) elDirCameras.textContent = `${defaultCameras} Falcon Node Cameras`;
if (elDirVolume) elDirVolume.textContent = defaultCaptures;
if (elDirSearches) elDirSearches.textContent = 'Automated NCIC Hotlist';
if (elDirRetention) elDirRetention.textContent = '30 Days Auto-Purge';
if (elDirSharingCount) elDirSharingCount.textContent = 'Regional Law Enforcement Network';
if (elDirSharingTags) {
const regionalPartners = [
'Los Angeles County Sheriff (LASD)',
'California Highway Patrol (CHP)',
'Los Angeles Police Department (LAPD)',
'Kern County Sheriff Office',
'San Bernardino County Sheriff',
'Ventura County Sheriff'
];
elDirSharingTags.innerHTML = regionalPartners.map(name => `
<span style="background: rgba(56, 189, 248, 0.1); border: 1px solid rgba(56, 189, 248, 0.25); color: #93c5fd; padding: 2px 7px; border-radius: 6px; font-size: 0.7rem;">${name}</span>
`).join('');
}
if (elDirReasonsList && elDirReasonsBox) {
elDirReasonsBox.style.display = 'block';
elDirReasonsList.innerHTML = `
<div style="display: flex; justify-content: space-between;">
<span>• Stolen Vehicle / Plate Alerts (10851 CVC)</span>
<span style="color: #38bdf8; font-weight: 600;">Real-time</span>
</div>
<div style="display: flex; justify-content: space-between;">
<span>• Felony Warrants & BOLO Broadcasts</span>
<span style="color: #38bdf8; font-weight: 600;">Active</span>
</div>
<div style="display: flex; justify-content: space-between;">
<span>• Amber Alert / Missing Person Inquiries</span>
<span style="color: #38bdf8; font-weight: 600;">Broadcast</span>
</div>
`;
}
if (elOfficialPortalBtn && elPortalText) {
elOfficialPortalBtn.href = `https://transparency.flocksafety.com/${cam.slug || 'palmdale-ca-lasd'}`;
elPortalText.textContent = `Open Official ${cam.agency || 'Agency'} Transparency Portal ↗`;
}
}
@@ -1988,12 +2080,14 @@
el.loginCloseBtn.addEventListener('click', closeLoginModal);
el.reportCloseBtn.addEventListener('click', closeReportModal);
// Global listener for portal inspection from popup
// Global listener for camera & portal inspection: NEVER switches views away from radar!
window.inspectPortal = function(slug) {
switchView('dir');
setTimeout(() => {
window.location.hash = slug;
}, 150);
const matchedCam = allCameras.find(c => c.slug === slug);
if (matchedCam) {
openCameraHardwareProof(matchedCam.id);
} else if (typeof window.openAgencyModal === 'function') {
window.openAgencyModal(slug);
}
};
}