fix(dispatch): fix Leaflet map blank/partial render on mobile and tablet

- DispatchMapPanel: replace h-full/height:100% with explicit inline px height
  on both wrapper div and MapContainer — CollapsePanel uses height:auto which
  makes percentage heights resolve to 0 giving Leaflet a zero-size canvas
- DispatchMapPanel: accept mapHeight prop from parent for responsive sizing
- LynkDispatchPage: compute responsive mapHeight state (300px mobile →
  380px sm → 460px md → 520px lg tablet) updated on window resize; passed
  as prop to DispatchMapPanel on all non-desktop renders
- LynkDispatchPage: add missing reps={effectiveReps} prop on mobile map render
  so live rep status cycling is reflected on all breakpoints
- LynkDispatchPage: add missing onQuickAssign={handleAssign} on desktop lead
  queue render so Quick Assign button works on desktop
- LynkDispatchPage: add whitespace-nowrap to efficiency badge to prevent
  '89% AI-Dispatched' wrapping to two lines in header
- LynkDispatchPage: dispatch synthetic resize event 260ms after map panel
  expands on mobile/tablet so Leaflet invalidateSize fires post-animation
- DispatchMapPanel: add second invalidateSize call at 320ms (belt-and-suspenders
  alongside 50ms) to cover 220ms CollapsePanel animation on slower devices
- DispatchLeadQueue: enrich DROP_POOL leads with phone, email, source
  sub-details and notes so Lead Quick View shows complete data on drop-in leads
This commit is contained in:
Satyam
2026-03-26 14:31:36 +05:30
parent b804f7cff1
commit 9be8ec911f
3 changed files with 60 additions and 16 deletions
+31 -2
View File
@@ -162,8 +162,23 @@ const LynkDispatchPage = () => {
const [isDesktop, setIsDesktop] = useState(() => window.innerWidth >= 1280);
const aiPanelRef = useRef(null);
// Responsive map height for non-desktop — explicit px needed so Leaflet
// gets a reliable offsetHeight regardless of CollapsePanel's height:auto chain
const calcMapHeight = () => {
const w = window.innerWidth;
if (w >= 1280) return null; // desktop: DispatchMapPanel handles its own height
if (w >= 1024) return '520px'; // iPad Pro 11" landscape / large tablet
if (w >= 768) return '460px'; // iPad Air / md tablet
if (w >= 640) return '380px'; // small tablet / large phone landscape
return '300px'; // mobile portrait
};
const [mapHeight, setMapHeight] = useState(calcMapHeight);
useEffect(() => {
const handler = () => setIsDesktop(window.innerWidth >= 1280);
const handler = () => {
setIsDesktop(window.innerWidth >= 1280);
setMapHeight(calcMapHeight());
};
window.addEventListener('resize', handler);
return () => window.removeEventListener('resize', handler);
}, []);
@@ -179,6 +194,16 @@ const LynkDispatchPage = () => {
const dragLeft = useCallback((delta) => setLeftWidth(w => Math.min(440, Math.max(220, w + delta))), []);
const dragRight = useCallback((delta) => setRightWidth(w => Math.min(440, Math.max(260, w - delta))), []);
// When the map panel expands on mobile/tablet, fire a synthetic resize
// after the CollapsePanel animation (220ms) completes so Leaflet
// invalidateSize() in MapController gets a correct container height.
useEffect(() => {
if (!collapsed.map && !isDesktop) {
const t = setTimeout(() => window.dispatchEvent(new Event('resize')), 260);
return () => clearTimeout(t);
}
}, [collapsed.map, isDesktop]);
const handleSelectLead = (lead) => {
if (selectedLead?.id === lead.id) return;
setSelectedLead(lead);
@@ -328,7 +353,7 @@ const LynkDispatchPage = () => {
exit={{ opacity: 0 }}
transition={{ duration: 0.2 }}
title={`${efficiencyPct}% of dispatches used AI recommendation — ${100 - efficiencyPct}% were manual overrides`}
className="flex items-center gap-1 text-[10px] font-black cursor-default"
className="flex items-center gap-1 text-[10px] font-black cursor-default whitespace-nowrap"
style={{ color: stormMode ? '#F59E0B' : '#10B981' }}
>
<span className="w-1 h-1 rounded-full" style={{ backgroundColor: stormMode ? '#F59E0B' : '#10B981' }} />
@@ -465,6 +490,7 @@ const LynkDispatchPage = () => {
selectedLead={selectedLead}
onSelectLead={handleSelectLead}
onViewDetails={setViewDetailLead}
onQuickAssign={handleAssign}
stormMode={stormMode}
accent={accent}
/>
@@ -513,15 +539,18 @@ const LynkDispatchPage = () => {
stormMode={stormMode}
accent={accent}
isDesktop={isDesktop}
mapHeight={null}
/>
) : (
<CollapsePanel open={!collapsed.map}>
<DispatchMapPanel
selectedLead={selectedLead}
dispatchLeads={dispatchLeads}
reps={effectiveReps}
stormMode={stormMode}
accent={accent}
isDesktop={isDesktop}
mapHeight={mapHeight}
/>
</CollapsePanel>
)}