// Entreprise panel v2 — dramatic header, kinetic info cells const { useState, useEffect, useRef } = React; const GEO_CACHE2 = new Map(); let LAST_GEO_REQ2 = 0; async function geocode2(addr) { if (!addr) return null; if (GEO_CACHE2.has(addr)) return GEO_CACHE2.get(addr); const wait = Math.max(0, 1100 - (Date.now() - LAST_GEO_REQ2)); if (wait) await new Promise(r => setTimeout(r, wait)); LAST_GEO_REQ2 = Date.now(); try { const q = encodeURIComponent(addr + ', Québec, Canada'); const r = await fetch(`https://nominatim.openstreetmap.org/search?format=json&limit=1&q=${q}`, { headers: { 'Accept': 'application/json' } }); if (!r.ok) throw new Error('geo fail'); const j = await r.json(); const hit = j[0]; if (!hit) { GEO_CACHE2.set(addr, null); return null; } const point = { lat: parseFloat(hit.lat), lng: parseFloat(hit.lon) }; GEO_CACHE2.set(addr, point); return point; } catch (e) { GEO_CACHE2.set(addr, null); return null; } } function MapView2({ entreprise, onFail }) { const ref = useRef(null); const mapRef = useRef(null); const [state, setState] = useState('loading'); useEffect(() => { let cancelled = false; setState('loading'); if (!entreprise.adresse) { setState('fail'); return; } (async () => { const point = await geocode2(entreprise.adresse); if (cancelled) return; if (!point) { setState('fail'); onFail?.(); return; } if (!ref.current) return; if (mapRef.current) { mapRef.current.remove(); mapRef.current = null; } const map = L.map(ref.current, { zoomControl: true, attributionControl: false, scrollWheelZoom: false }); mapRef.current = map; const regionBounds = L.latLngBounds([45.0, -75.0], [49.0, -68.0]); map.fitBounds(regionBounds, { padding: [10, 10] }); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 16, attribution: '© OpenStreetMap', }).addTo(map); const icon = L.divIcon({ className: '', html: '
', iconSize: [24, 24], iconAnchor: [12, 12], }); L.marker([point.lat, point.lng], { icon }).addTo(map); setTimeout(() => { if (cancelled) return; map.flyTo([point.lat, point.lng], 8, { duration: 1.2 }); }, 350); setState('ready'); })(); return () => { cancelled = true; if (mapRef.current) { mapRef.current.remove(); mapRef.current = null; } }; }, [entreprise.adresse]); return ({entreprise.description}
)}