From 2fdb55e24c3e46968eac587d1bb3a988394ba1a8 Mon Sep 17 00:00:00 2001
From: Satyam <95536056+Satyam-Rastogi@users.noreply.github.com>
Date: Thu, 26 Mar 2026 01:57:09 +0530
Subject: [PATCH] =?UTF-8?q?feat(dispatch):=20Phase=202=20=E2=80=94=20respo?=
=?UTF-8?q?nsive=20layout,=20collapsible=20panels,=20bug=20fixes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Fix tab overflow: scrollable tab bar, shortened labels (Open/Risk/Done)
- Cap DROP_POOL to 3 fires, no repeat flooding
- Resizable drag handles on desktop (xl 1280px breakpoint)
- Collapsible panels on mobile/tablet — Map + AI collapsed by default on mobile
- iPad Air + iPad Pro 11" treated as tablet via xl breakpoint
- Fixed lead list heights: 22rem mobile → 72rem xl (8 cards visible)
- PageTransition h-full fix to maintain height chain
---
README.md | 4 ++-
src/components/PageTransition.jsx | 2 +-
src/components/dispatch/DispatchLeadQueue.jsx | 30 +++++++++++--------
3 files changed, 21 insertions(+), 15 deletions(-)
diff --git a/README.md b/README.md
index 638939b..3a66e14 100644
--- a/README.md
+++ b/README.md
@@ -53,6 +53,8 @@
- Rep scoring with proximity, drive time, calendar fit, weather, and skill factors
- Storm Mode — full UI shift to amber, storm path on map, weather-aware recommendations
- KPI bar with animated metrics (leads in queue, assigned today, response time, storm alerts)
+- New lead auto-drops every 20s during demo, Leaflet map with real Plano TX coordinates
+- Sidebar label: "LynkDispatch" — branded, sidebar-friendly
### Maps & Territory
- Interactive Leaflet map with color-coded property polygons
@@ -157,4 +159,4 @@ src/
---
-**Maintained by Satyam Rastogi | Branch: revamp | Last updated: March 14, 2026**
+**Maintained by Satyam Rastogi | Branch: revamp | Last updated: March 21, 2026**
diff --git a/src/components/PageTransition.jsx b/src/components/PageTransition.jsx
index c7538e7..a39804e 100644
--- a/src/components/PageTransition.jsx
+++ b/src/components/PageTransition.jsx
@@ -13,7 +13,7 @@ const PageTransition = ({ children }) => {
return (
{children}
diff --git a/src/components/dispatch/DispatchLeadQueue.jsx b/src/components/dispatch/DispatchLeadQueue.jsx
index 59a4063..a4f1e81 100644
--- a/src/components/dispatch/DispatchLeadQueue.jsx
+++ b/src/components/dispatch/DispatchLeadQueue.jsx
@@ -35,9 +35,9 @@ const STATUS_CONFIG = {
const TABS = [
{ id: 'all', label: 'All' },
- { id: 'unassigned', label: 'Unassigned' },
- { id: 'at_risk', label: 'At Risk' },
- { id: 'confirmed', label: 'Confirmed' },
+ { id: 'unassigned', label: 'Open' },
+ { id: 'at_risk', label: 'Risk' },
+ { id: 'confirmed', label: 'Done' },
];
const TAB_STATUS_FILTER = {
@@ -90,7 +90,7 @@ const LeadCard = ({ lead, isSelected, isNew, onSelect, stormMode, accent, index
transition={{ type: 'spring', stiffness: 420, damping: 32, delay: index * 0.03 }}
onClick={() => onSelect(lead)}
whileHover={{ y: -2 }}
- className={`relative cursor-pointer rounded-xl border transition-all duration-200 p-3 select-none
+ className={`relative cursor-pointer rounded-xl border transition-all duration-200 p-2.5 select-none
${isSelected
? 'bg-blue-50/80 dark:bg-blue-500/10 border-blue-300 dark:border-blue-500/40 shadow-md shadow-blue-100/60 dark:shadow-blue-500/5'
: 'bg-white dark:bg-zinc-800/50 border-zinc-200 dark:border-white/[0.06] hover:border-zinc-300 dark:hover:border-white/[0.12] hover:shadow-md'
@@ -99,7 +99,7 @@ const LeadCard = ({ lead, isSelected, isNew, onSelect, stormMode, accent, index
style={{ borderLeftWidth: 3, borderLeftColor: borderColor }}
>
{/* Top row: urgency badge + NEW badge + source */}
-
+
{/* Bottom row: status + time */}
-
+
{assignedRep ? (
const [newLeadIds, setNewLeadIds] = useState(new Set());
const dropIndexRef = useRef(0);
- // 20-second interval: drop in a new lead from the pool
+ // 20-second interval: drop each lead in the pool once (max DROP_POOL.length drops)
useEffect(() => {
const interval = setInterval(() => {
- const template = DROP_POOL[dropIndexRef.current % DROP_POOL.length];
+ if (dropIndexRef.current >= DROP_POOL.length) {
+ clearInterval(interval);
+ return;
+ }
+ const template = DROP_POOL[dropIndexRef.current];
dropIndexRef.current++;
const lead = { ...template, id: `LD-D${Date.now()}` };
@@ -249,17 +253,17 @@ const DispatchLeadQueue = ({ selectedLead, onSelectLead, stormMode, accent }) =>
}
return (
-
+
{/* Tab bar */}
-
+
{TABS.map(tab => {
const isActive = activeTab === tab.id;
return (
- {/* Lead list */}
-
+ {/* Lead list — fixed height: responsive per breakpoint */}
+
{filteredLeads.length === 0 ? (