a85b90d28377b02570bb9965b100d26eda5541de
LynkedUpPro CRM — Field Sales & Territory Management Platform
The Next Generation of Roofing Sales & Dispatch Management
LynkedUpPro CRM is an advanced, data-driven platform for roofing and real estate canvassing teams. Field agents knock doors and log leads on mobile, admins dispatch reps from the office, and owners get a real-time command center — all in one app.
Current branch: revamp — complete UI/UX overhaul in progress.
PRODUCT OVERVIEW
Value Proposition
- 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 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
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
- 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
- Section → Group → Item hierarchy
- Material Details Modal (measurement → waste → qty → cost → price formula)
- Measurements Modal for detailed takeoffs
- Financial Summary sidebar with adjustable margin slider
- Full light/dark theme support
Lead Creation Page (All 8 phases complete)
- 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 alloverflow:hiddencontainers viaReactDOM.createPortal; scroll detection usese.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
- Insurance section — carrier, claim number, claim status, adjuster name/phone, policy number (purple accent)
- Assignment section — role-aware rep selector (agents: self-assign toggle; admins/owners: full scrollable agent list), priority pill (Low/Medium/High), follow-up date picker (cyan accent)
- Save action — validates required fields, Sonner toast on success/failure, redirects to Leads list
- Leads list page (
/emp/fa/leads) — card list with urgency/status badges, search bar, animated empty state - Animated progress bar (GSAP), section completion checkmarks, 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)
- 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
- Reverse geocoding to create properties from map clicks
- Rep location overlays and lead clustering (in development)
Admin Action Center
- Unassigned lead queue — zero leakage
- Smart agent assignment modal
- Urgency counters and pending signatures tracking
Owner's Box
- Financial KPIs (revenue, spend, health score)
- Project command center with change orders and budget vs. actuals
- People, vendor, and document management
USER ROLES & DEMO ACCOUNTS
Password for ALL accounts: password
| Role | Account ID | Description |
|---|---|---|
| Field Agent | FA001 – FA005 |
Door knocking, lead logging, ProCanvas |
| Admin | ADM01 – ADM03 |
Action center, dispatch, leaderboard |
| Owner | OWN01, OWN02 |
Full platform access, owner snapshot |
| Contractor | CON01 |
Project and task management |
| Vendor | VEN01 |
Orders and invoices |
| Subcontractor | SUB01 |
Work scope and tasks |
| Customer | alice, bob, charlie |
Customer portal |
DEVELOPER GUIDE
Tech Stack
- Frontend: React 19 (Vite), Tailwind CSS (
darkMode: 'class') - State: MockStore (simulates backend), AuthContext (RBAC), ThemeContext (light/dark), GamificationContext
- Routing: React Router v7 with ProtectedRoute (role-based)
- 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)
Setup
- Clone:
git clone <repo> - Install:
pnpm install - Env: Create
.envwithVITE_GROQ_API_KEYandVITE_OPENWEATHER_API_KEY - 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/80page background - Theme controlled via
useTheme()fromsrc/context/ThemeContext.jsx - Critical rule: always use
dark:Tailwind variants on inputs and text — neverisDark ? '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.createPortalintodocument.body— escapes alloverflow:hiddenancestors (critical because Framer Motion collapse animations use overflow:hidden) - Position:
getBoundingClientRect()+window.scrollY/scrollX→position: absoluteon body - Scroll detection:
e.composedPath()— reliable across Chrome, Safari, Firefox, and mobile touch accentprop:'blue'(Job Details) or'emerald'(Property section)compactprop: for inline type pickers (phone/email type selectors,w-24container)LeadCombobox: input-based variant with live fuzzy filtering —Enterselects top result,Escapecancels
Project Structure (Abbreviated)
src/
├── pages/
│ ├── CreateLeadPage.jsx # Lead creation orchestrator (form state, sections, progress, save)
│ ├── LeadsListPage.jsx # Leads list with search, cards, empty state
│ └── ... # Other role pages
├── components/
│ ├── 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
│ │ ├── LeadInsuranceSection.jsx # Carrier, claim #/status, adjuster name/phone, policy #
│ │ ├── LeadAssignmentSection.jsx # Role-aware rep selector, priority pill, follow-up date
│ │ ├── 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 + leads[] + addLead()
└── hooks/ # useGamification, custom hooks
Maintained by Satyam Rastogi | Branch: revamp | Last updated: March 21, 2026
Description
Languages
JavaScript
98.8%
TypeScript
1%
CSS
0.2%