fix(leads): portaled dropdowns, flex-wrapper icons, responsive layout, and UI polish
- Replace all native <select> with LeadCustomSelect (ReactDOM.createPortal into body, getBoundingClientRect positioning, e.composedPath() scroll detection) - Add LeadCombobox: fuzzy-search state picker (searches abbr + full name, portal, onMouseDown) - Convert Phone/MapPin icons from absolute-positioned to flex-wrapper siblings of bg-transparent input - Fix dark mode invisible text: all inputs converted from isDark JS conditionals to dark: variants - Fix urgency Standard pill visibility: container bg-zinc-900, selected bg-zinc-700 ring-1 shadow-lg - Fix City/State/ZIP mobile overlap: flex -> grid-cols-2 (mobile) / grid-cols-[1fr_5.5rem_6rem] (sm+) - Fix urgency section hidden behind mobile sticky footer: pb-28 -> pb-44 md:pb-10 - Replace all compact type pickers (phone/email) with LeadCustomSelect compact mode - Update README.md with full lead creation architecture docs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,25 +8,24 @@
|
||||
|
||||
---
|
||||
|
||||
## 🏛️ PRODUCT OVERVIEW
|
||||
## PRODUCT OVERVIEW
|
||||
|
||||
### Value Proposition
|
||||
- **Precision Targeting**: Identify "Golden Leads" (older, high-value homes) instantly on a map.
|
||||
- **Precision Targeting**: Identify high-value homes instantly on a map.
|
||||
- **AI-Powered Dispatch**: LynkDispatch AI scores and recommends rep assignments in real-time.
|
||||
- **Gamified Field Performance**: ProCanvas turns door-knocking into a game — XP, streaks, leaderboards, daily missions.
|
||||
- **Gamified Field Performance**: ProCanvas turns door-knocking into a performance game — XP, streaks, leaderboards, daily missions.
|
||||
- **Intelligent Lead Capture**: Mobile-optimized lead creation with Quick Capture for the door, Full Form for the office.
|
||||
|
||||
---
|
||||
|
||||
## 🎨 KEY FEATURES
|
||||
## KEY FEATURES
|
||||
|
||||
### ProCanvas — Gamified Agent Dashboard
|
||||
- FIFA-style player card with XP bar, streak tracker, and rank badge
|
||||
- Log Action hub (Door Knocked, Lead Gained, Appointment, Client Meet)
|
||||
- Daily Missions with Energy Bars, Weekly Challenge with progress tracking
|
||||
- Live event cards: Showdown, Hot Streak, Weekly Objective
|
||||
- Rewards & Checkpoints milestone track
|
||||
- Badges & Achievements trophy room
|
||||
- Rewards & Checkpoints milestone track, Badges & Achievements trophy room
|
||||
- **Dual design identity**: Light mode (energetic/clean — solid colored header banners on white cards) and Dark mode (neon/glass arcade aesthetic) — distinct, never washed-out
|
||||
|
||||
### Estimate Builder
|
||||
@@ -36,18 +35,21 @@
|
||||
- Financial Summary sidebar with adjustable margin slider
|
||||
- Full light/dark theme support
|
||||
|
||||
### Lead Creation Page _(Phases 1–4 complete, Phases 5–8 remaining)_
|
||||
- Quick Capture (essential fields only) for agents at the door; Full Form for the office
|
||||
- 5 color-coded accordion sections: Contact (blue), Property (emerald), Job Details (amber), Insurance (purple), Assignment (cyan)
|
||||
- **Custom portaled dropdowns** (`LeadCustomSelect`) — dark zinc-900 panel, fully scrollable, escapes all `overflow:hidden` containers via `ReactDOM.createPortal`; scroll detection uses `e.composedPath()` for reliability across browsers and touch
|
||||
- **Fuzzy-search state combobox** (`LeadCombobox`) — type "tex" to find Texas, searches both abbreviation and full state name simultaneously
|
||||
- **Flex-wrapper icon pattern** for Phone/MapPin icons — eliminates z-index conflicts, icons are true flex siblings of the input
|
||||
- Animated progress bar (GSAP), section completion check marks, spring height animations (Framer Motion)
|
||||
- Mobile-first: sticky Save footer, responsive City/State/ZIP grid layout, ample bottom padding for footer clearance
|
||||
|
||||
### LynkDispatch AI _(investor demo — in development)_
|
||||
- 3-panel command center: Lead Queue + Map + AI Recommendation Drawer
|
||||
- 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)
|
||||
|
||||
### Lead Creation Page _(in development)_
|
||||
- Quick Capture (7 fields) for agents at the door, Full Form for office
|
||||
- 5 color-coded sections: Contact (blue), Property (emerald), Job Details (amber), Insurance (purple), Assignment (cyan)
|
||||
- Role-aware: agents get simplified assignment, admins/owners get Smart Assign with rep scoring
|
||||
- Mobile-first, works beautifully on tablet and desktop too
|
||||
|
||||
### Maps & Territory
|
||||
- Interactive Leaflet map with color-coded property polygons
|
||||
- Reverse geocoding to create properties from map clicks
|
||||
@@ -65,7 +67,7 @@
|
||||
|
||||
---
|
||||
|
||||
## 👥 USER ROLES & DEMO ACCOUNTS
|
||||
## USER ROLES & DEMO ACCOUNTS
|
||||
|
||||
**Password for ALL accounts: `password`**
|
||||
|
||||
@@ -81,19 +83,18 @@
|
||||
|
||||
---
|
||||
|
||||
## 💻 DEVELOPER GUIDE
|
||||
## DEVELOPER GUIDE
|
||||
|
||||
### Tech Stack
|
||||
- **Frontend**: React 19 (Vite), Tailwind CSS (`darkMode: 'class'`)
|
||||
- **State**: MockStore (simulates backend), AuthContext (RBAC), ThemeContext (light/dark), GamificationContext (XP/streaks)
|
||||
- **State**: MockStore (simulates backend), AuthContext (RBAC), ThemeContext (light/dark), GamificationContext
|
||||
- **Routing**: React Router v7 with ProtectedRoute (role-based)
|
||||
- **Animations**: Framer Motion (page transitions, stagger entrances, height animations)
|
||||
- **Maps**: react-leaflet (Leaflet.js)
|
||||
- **Charts**: Recharts (bar, area, pie, scatter)
|
||||
- **Animations**: Framer Motion (page transitions, stagger, height animations, layoutId), GSAP (progress bars, counters)
|
||||
- **Maps**: react-leaflet
|
||||
- **Charts**: Recharts
|
||||
- **Icons**: lucide-react
|
||||
- **AI**: Groq SDK (qwen-32b) with dynamic role-aware system prompts
|
||||
- **Notifications**: sonner (toasts)
|
||||
- **Smooth Scroll**: Lenis
|
||||
|
||||
### Setup
|
||||
1. **Clone**: `git clone <repo>`
|
||||
@@ -102,30 +103,51 @@
|
||||
4. **Run**: `pnpm run dev`
|
||||
|
||||
### Design System
|
||||
- Dark mode: Glass panels (`bg-zinc-900/70 backdrop-blur-xl`), neon accents, Barlow Condensed uppercase
|
||||
- Light mode: White cards (`bg-white shadow-md`), solid colored header banners, `bg-zinc-100/80` page background
|
||||
- **Dark mode**: Glass panels (`bg-zinc-900/70 backdrop-blur-xl`), neon accents, Barlow Condensed uppercase
|
||||
- **Light mode**: White cards (`bg-white shadow-md`), solid colored header banners, `bg-zinc-100/80` page background
|
||||
- Theme controlled via `useTheme()` from `src/context/ThemeContext.jsx`
|
||||
- All components use `dark:` Tailwind variants — no JS theme switching per-element needed
|
||||
- **Critical rule**: always use `dark:` Tailwind variants on inputs and text — never `isDark ? 'classA' : 'classB'` — JS conditionals caused invisible text bugs in dark mode that dark: variants solve
|
||||
|
||||
### Custom Dropdown Architecture (LeadCustomSelect / LeadCombobox)
|
||||
All select fields in the Lead Creation form use custom components rather than native `<select>`:
|
||||
- Trigger button styled identically to the other input fields
|
||||
- Panel rendered via `ReactDOM.createPortal` into `document.body` — escapes all `overflow:hidden` ancestors (critical because Framer Motion collapse animations use overflow:hidden)
|
||||
- Position: `getBoundingClientRect()` + `window.scrollY/scrollX` → `position: absolute` on body
|
||||
- Scroll detection: `e.composedPath()` — reliable across Chrome, Safari, Firefox, and mobile touch
|
||||
- `accent` prop: `'blue'` (Job Details) or `'emerald'` (Property section)
|
||||
- `compact` prop: for inline type pickers (phone/email type selectors, `w-24` container)
|
||||
- `LeadCombobox`: input-based variant with live fuzzy filtering — `Enter` selects top result, `Escape` cancels
|
||||
|
||||
---
|
||||
|
||||
## 📁 Project Structure (Abbreviated)
|
||||
## Project Structure (Abbreviated)
|
||||
|
||||
```
|
||||
src/
|
||||
├── pages/ # Route-level pages by role
|
||||
├── pages/
|
||||
│ ├── CreateLeadPage.jsx # Lead creation orchestrator (form state, sections, progress)
|
||||
│ └── ... # Other role pages
|
||||
├── components/
|
||||
│ ├── estimates/ # EstimateBuilder modals (MaterialDetails, Measurements, etc.)
|
||||
│ ├── leads/ # Lead creation form components (in development)
|
||||
│ ├── dispatch/ # LynkDispatch AI panels (in development)
|
||||
│ ├── dashboard/ # Admin dashboard widgets
|
||||
│ ├── ProCanvas/ # Gamification subcomponents
|
||||
│ └── ... # Shared components (Layout, AnimatedCounter, etc.)
|
||||
├── context/ # AuthContext, ThemeContext, GamificationContext
|
||||
├── data/ # mockStore.jsx — central data layer
|
||||
└── hooks/ # useGamification, custom hooks
|
||||
│ ├── leads/
|
||||
│ │ ├── LeadSectionWrapper.jsx # Collapsible accordion with spring animation
|
||||
│ │ ├── LeadContactSection.jsx # Name, dynamic phone rows, dynamic email rows
|
||||
│ │ ├── LeadPropertySection.jsx # Address, city/state/zip, property type, site photos
|
||||
│ │ ├── LeadJobSection.jsx # Lead source, type, work/trade type, urgency, notes
|
||||
│ │ ├── LeadCustomSelect.jsx # Portaled custom dropdown (accent + compact modes)
|
||||
│ │ ├── LeadCombobox.jsx # Fuzzy-search combobox for state field
|
||||
│ │ ├── UrgencyPillSelector.jsx # Sliding pill with Framer Motion layoutId
|
||||
│ │ ├── PhoneEntryRow.jsx # Phone input with mask, type picker, primary star
|
||||
│ │ └── EmailEntryRow.jsx # Email input with type picker, primary star
|
||||
│ ├── estimates/ # EstimateBuilder modals
|
||||
│ ├── dispatch/ # LynkDispatch AI panels (in development)
|
||||
│ ├── dashboard/ # Admin dashboard widgets
|
||||
│ └── ... # Layout, AnimatedCounter, shared components
|
||||
├── context/ # AuthContext, ThemeContext, GamificationContext
|
||||
├── data/
|
||||
│ └── mockStore.jsx # Central data layer + LEAD_FORM_OPTIONS
|
||||
└── hooks/ # useGamification, custom hooks
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Maintained by Satyam Rastogi | Branch: revamp | Last updated: March 12, 2026**
|
||||
**Maintained by Satyam Rastogi | Branch: revamp | Last updated: March 13, 2026**
|
||||
|
||||
Reference in New Issue
Block a user