Commit Graph

141 Commits

Author SHA1 Message Date
Satyam-Rastogi e754911e0b fix(storm-intel): graceful hail proxy error + suppress inflated homes total
Hail Recon fetch now checks Content-Type before parsing JSON — when running
under pnpm dev (Vite only), the proxy JS file is served as-is; the check
catches the non-JSON response and flags it as proxy_unavailable, surfacing
"Not available in dev mode" instead of the raw parse-error string.

Est. Homes header now shows "—" when no events are event-pinned. The
previous totalHomes sum across all 37 NWS warning polygons (each 100–500 sq mi)
produced a nonsensical 19.7M figure. The number is only meaningful per-event
or when the user explicitly pins events to compare.
2026-05-19 02:39:19 +05:30
Satyam-Rastogi 30728a0db6 feat(storm-intel): damage-probability homes estimate + pinned events total in header
useStormEvents:
- Replace flat 1800/sq mi estimate with damage probability multiplier per type:
  hail ≥2.0" = 95%, 1.75" = 80%, 1.5" = 65%, 1.25" = 45%, 1.0" = 30%, <1.0" = 15%;
  tornado = 20% (path << polygon), flood = 25%, wind = 40%, winter = 20-30%
- Expose damagePct on event object for display in drawer

StormIntelPage:
- pinnedHomes useMemo — sums estimatedHomes across event-pinned events
- Header homes stat switches to amber + "Est. Homes · N pinned" label when events are pinned;
  hover tooltip notes zones may overlap
- Drawer: "Est. Homes Affected" now shows "~X% damage probability" as sub-label
2026-05-19 02:31:57 +05:30
Satyam-Rastogi 4c32266f3d feat(storm-intel): Tier 1/2/3 data enrichment — SBW tags, LSR spotter reports, Hail Recon pin history 2026-05-19 02:27:47 +05:30
Satyam-Rastogi dc994be329 feat(storm-intel): richer event data + NWS boundary label in drawer and map tooltip
useStormEvents:
- Extract windSpeed (windtag), expireTime, warningDurationMins, phenomenaCode/Label
- Calculate polygonAreaSqMi via shoelace formula; estimate homes at 1800/sq mi

StormDetailDrawer — new sections:
- Weather Metrics: hail size with damage descriptor, wind speed with severity label
- Impact Zone: warning area sq miles + estimated homes in zone
- Warning Timeline: issued time, expired time, duration, issuing NWS office
- NWS Boundary note: explains the shape is a meteorologist-drawn warning zone

Map tooltip:
- Shows phenomenaLabel, wind speed, area sq mi
- Footer section labeled "NWS Warning Boundary" with shape explanation
2026-05-19 01:10:17 +05:30
Satyam-Rastogi b9450dc7b4 fix(storm-intel): map shows only selected/pinned events; add Show all toggle + auto-zoom to pins
- Location pins filter the sidebar only; map no longer auto-renders all
  nearby polygons (NWS warnings span entire counties, cluttering the view)
- Map shows event polygons only for explicitly selected or event-pinned items
- "Show all on map" toggle in sidebar renders the full sidebar event list
- FitToPins auto-zooms to the pin radius circle when a new pin is dropped;
  clears back to Plano center when all pins are removed
2026-05-19 00:56:37 +05:30
Satyam-Rastogi 0b8229d46f fix(storm-intel): hailIn TDZ crash, restore 36mo fetch, Go button for radius
- Fix ReferenceError: hailIn was used before declaration in featureToEvent,
  causing every SV event to throw and fall back to empty mock data
- Restore IEM fetch window to 36 months so events are available for all range chips
- Radius input now has explicit Go button (Enter key also applies); draft value
  shows hint until applied so accidental keystrokes don't retrigger search
2026-05-19 00:51:44 +05:30
Satyam-Rastogi a6d3997d07 feat(storm-intel): configurable pin radius, fix blank map, 6mo default, remove mock polygons
- Map always renders (removed blank overlay when no nearby events)
- Pin radius is now user-configurable (default 5 mi, input shown in pin strip)
- Default date range changed to 6 months for faster initial load
- IEM fetch window narrowed to 6 months to match default
- MOCK_STORM_EVENTS cleared (IEM provides real NWS polygon data)
2026-05-19 00:47:43 +05:30
Satyam-Rastogi 1b7af0699d fix(storm-intel): remove duplicate mapEvents declaration 2026-05-19 00:40:45 +05:30
Satyam-Rastogi 023c76471b feat(storm-intel): search, pin-drop radius, more event types
Search: text filter across areaName/type/severity in sidebar

Pin drop (up to 5 pins):
- Crosshair button activates drop mode; next map click places a pin
- 5-mile radius circle drawn on map for each pin
- Sidebar shows only events within 5mi of any pin, sorted by distance
- Distance label (e.g. "1.2 mi") shown on each card
- Individual pin removal + clear all; + Add pin shortcut in pin strip
- Map shows blank + drop-prompt until at least one pin is placed

More event types:
- Hook now fetches WS/BZ/WW/IS (winter storm, blizzard, ice) from IEM
- SV without hailtag maps to wind; SV with hailtag maps to hail
- New icons: CloudHail, CloudSnow, CloudRain per type
- Type filter row added to filter bar: All/Hail/Tornado/Flood/Wind/Snow/Rain
2026-05-19 00:40:17 +05:30
Satyam-Rastogi 723a0fb3a8 feat(storm-intel): auto-select latest event on map at first load 2026-05-19 00:32:46 +05:30
Satyam-Rastogi 9c0e5c2302 feat(storm-intel): select/pin system for map event visibility
Map now shows only the currently selected event + any pinned events.
If nothing is selected or pinned, all events are shown (default state).

- Pin button (MapPin icon) on each card — click to persist that event
  on the map independently of selection changes
- Card click = select (amber border, opens drawer, flies to zone)
- Pinned cards get a subtle amber tint + filled pin icon
- Pinned events on map: tighter dash + slightly elevated opacity vs unselected
- List header shows "X pinned" count + "Clear pins" button
- Selection clear button still works independently of pins
2026-05-19 00:30:37 +05:30
Satyam-Rastogi 1f0e74a7b0 fix(storm-intel): call IEM API directly from browser — no proxy needed
IEM geojson/sbw.geojson has CORS open to all origins so the browser can
fetch it directly. Moves all transformation logic into useStormEvents.js,
eliminating the need for vercel dev or any server-side proxy. Works with
plain pnpm run dev on localhost. Falls back to MOCK_STORM_EVENTS if IEM
is unreachable. api/storm-polygons.js kept as optional edge cache layer.
2026-05-19 00:22:05 +05:30
Satyam-Rastogi 5cd0d456f4 fix(storm-intel): correct IEM SBW endpoint to use sts/ets timestamps + handle MultiPolygon
Use /geojson/sbw.geojson?sts=...&ets=... instead of year param (which was
being ignored). Handle MultiPolygon geometry type from IEM response. Use
correct 'issue' date field. Filter phenomena server-side (SV/TO/FF only).
Use hailtag field for accurate severity on SVR warnings.
2026-05-18 23:58:39 +05:30
Satyam-Rastogi fd353ab732 feat(storm-intel): real storm polygon data via Iowa Environmental Mesonet IEM SBW archive
api/storm-polygons.js — Vercel proxy that fetches historical NWS storm-based
warnings (severe thunderstorm + tornado) from IEM for WFO FWD (Fort Worth),
covering Collin County / Plano TX. Filters to local bounding box, derives
severity from polygon area (area2163 km²), estimates impacted homes from
density, derives area name from centroid. Cached 12h on Vercel edge.

useStormEvents.js — switched to real IEM data (USE_MOCK=false). Fetches full
36-month dataset once on mount; all range/type/severity filtering stays
client-side in useMemo for instant UI response. Falls back to
MOCK_STORM_EVENTS when /api routes are unavailable (local vite dev).
2026-05-18 23:45:50 +05:30
Satyam-Rastogi 7799a83a4a feat(storm-intel): replace hexagonal storm polygons with realistic NWS-style swath shapes
Updated all 7 MOCK_STORM_EVENTS polygons to use irregular, amoeba-like
swath outlines matching real hail storm paths from NWS reports. Also
renamed project to LynkedUpPro-CRM in package.json.
2026-05-18 23:35:31 +05:30
Satyam-Rastogi ed19f7d202 feat(storm-intel): restore 1m/3m/6m range chips alongside new longer ranges 2026-05-18 18:39:31 +05:30
Satyam-Rastogi 0613c12b68 fix(storm-intel): forecast day contrast + range filter upgrade to 36mo + custom date range
- Alert/warn forecast cards: day label, temp, and rain% now use high-contrast red/orange text instead of muted gray — readable in both light and dark mode
- Alert card background slightly more opaque (bg-red-100/dark:bg-red-500/15) for better definition
- Range chips: 12 Mo / 18 Mo / 24 Mo / 36 Mo replacing old 1m/3m/6m/1y options
- Custom range: CalendarRange chip reveals two date inputs (from/to) with amber focus ring
- useStormEvents: DATE_RANGE_DAYS updated for new keys; custom range filters by customStart/customEnd; allEvents now uses 36m baseline
2026-05-18 18:38:36 +05:30
Satyam-Rastogi ada58fa646 fix(storm-intel): center ZoneAssignmentModal using flex wrapper instead of translate 2026-05-18 18:33:15 +05:30
Satyam-Rastogi 84b1e73fa7 fix(storm-intel): modal z-index, zone click-to-zoom, drawer close on fly-to, left padding
- ZoneAssignmentModal: portal to document.body with z-9999 so it renders above Leaflet map stacking context
- ZoneLayer: clicking any zone polygon or centroid circle fits map bounds to that zone
- handleFlyTo: closes detail drawer after zooming so the map is unobstructed
- StormDetailDrawer: pl-5 on header, body, and footer for consistent left padding
2026-05-18 18:29:29 +05:30
Satyam-Rastogi 12bd2fe0de feat(storm-intel): Phase 4+5 — Tomorrow.io forecast overlay and canvasser zone assignment
- Tomorrow.io 7-day forecast strip with weather icons, storm score bar, and per-day risk color coding
- High-risk alert banner in forecast strip when any day scores >=65
- api/storm-forecast.js: Vercel proxy that reads TOMORROW_API_KEY server-side; graceful empty response when key unset
- useStormForecast hook: USE_MOCK=false with realistic MOCK_FORECAST fallback
- ZoneDrawingLayer: click-to-place polygon vertices using react-leaflet useMapEvents; disables double-click zoom while active; shows live vertex dots + dashed preview polygon
- ZoneLayer: renders stormZones as colored semi-transparent polygons with agent initials at centroid
- ZoneAssignmentModal: name + canvasser picker + color selector + optional storm link; portaled modal
- StormIntelPage: Draw Zone button (Admin/Owner only); drawing state/cancel flow; stormZones displayed on map; zone summary strip in sidebar; StormDetailDrawer has working "Draw Canvasser Zone" action
- FieldStormZonePage: canvasser mobile view at /field/storm-zones showing assigned zones with map, linked storm details, conversion window badge, and peak window alert
- Layout: Storm Zones entry in FIELD_AGENT nav
- App: /field/storm-zones route (FIELD_AGENT + Admin + Owner)
2026-05-18 18:06:17 +05:30
Satyam-Rastogi df50f27ba6 feat(storm-intel): Phase 3 — Revenue Attribution dashboard
Adds an Attribution tab to Storm Intel showing full ROI breakdown of storm-sourced canvassing.

- MOCK_STORM_ATTRIBUTION_LEADS: 35 realistic leads across 7 storms, with addresses, statuses
  (New / Contacted / Appointed / Closed) and contractValues for closed deals — $218,900 total revenue
- useStormAttribution hook: merges historical mock leads with any session-created storm leads,
  aggregates per-storm stats (leads, closed, conversion rate, revenue, pipeline estimate, avg deal size)
- Attribution tab in StormIntelPage:
  - 6 summary stat cards: Total Leads, Closed, Conversion Rate, Revenue, Pipeline, Avg Deal
  - Grouped bar chart (Recharts) — leads generated vs closed per storm, bars colored by severity
  - Per-storm revenue cards ranked by revenue: severity badge, stats row, animated revenue
    progress bar relative to top performer
  - "Top Performing Zone" insight card at bottom
- Tab switcher (Map / Attribution) added to header; filter bar only shows on Map tab
2026-05-18 17:16:34 +05:30
Satyam-Rastogi 4cface49da feat(storm-intel): Phase 2 — storm-sourced lead generation flow
When a canvasser taps "Create Lead from Zone" in the Storm Intel detail drawer,
router state carries the storm context into CreateLeadPage:

- CreateLeadPage reads stormSource from location.state; initialises the form with
  city=Plano, state=TX, leadSource=Door Knock, urgency=high for significant/severe
  storms, and a pre-filled notes field with zone name, hail size, and date
- Amber storm banner renders below the page header showing zone name, hail size,
  and a note that urgency was auto-set; dismissible with X
- stormSource is saved on the lead object via the existing addLead spread
- LeadsListPage LeadCard shows an amber "Storm Zone" badge when lead.stormSource exists
- KanbanCard footer shows a compact amber "Storm" label for storm-sourced leads
2026-05-18 17:06:04 +05:30
Satyam-Rastogi 2e797c89f6 feat(storm-intel): Storm Intelligence Hub — Phase 1
Adds a new Storm Intel section to the sidebar and routes for ADMIN and OWNER roles.

- StormIntelPage: full-height layout with Leaflet map + storm polygon overlays,
  severity-coded color system, horizontal filter bar (date range / severity / sort),
  and a scrollable storm event list
- Storm detail drawer slides in from right with hail size, est. homes, days ago,
  conversion window indicator (Hot Zone / Warm / Cold / Too Fresh), intel text,
  and quick-action buttons (Create Lead, Open in Dispatch, Assign Canvassers stub)
- Clicking a storm card or map polygon zooms the map to that polygon and opens the drawer
- useStormEvents hook with USE_MOCK flag, date-range cutoff filter, type/severity filter,
  sort by date or severity, and conversionWindow() helper
- api/storm-events.js: NWS api.weather.gov proxy (free, no auth needed), parses
  GeoJSON polygons and hail size from alert descriptions
- MOCK_STORM_EVENTS: 7 realistic Plano TX storm events with accurate polygon coords
- Sidebar: CloudLightning "Storm Intel" entry added for OWNER and ADMIN nav
2026-05-18 16:49:37 +05:30
Satyam-Rastogi 4c1c454681 feat(hail-recon): enable live API — USE_MOCK off, KV dynamic import for graceful degradation 2026-05-18 16:13:29 +05:30
Satyam-Rastogi 9e2173fd43 feat(hail-recon): Hail Recon integration — storm intel panel, hail history, auto storm mode, address monitoring 2026-05-18 15:50:59 +05:30
Satyam-Rastogi 912967fa3a bug-fix/filter dropdowns in dark mode 2026-05-15 18:59:12 +05:30
Satyam-Rastogi d2774b4a1e adds filter in org commission distribution panel 2026-05-15 18:50:22 +05:30
Satyam-Rastogi 932e1bdbaa redesigned createItemModal with responsive and light /dark mode 2026-05-15 15:19:51 +05:30
Satyam-Rastogi a9d3d1ce48 apply commission setting model light mode 2026-05-15 15:06:16 +05:30
Satyam-Rastogi eb34ec4cb3 responsive new lead forms 2026-05-15 14:30:37 +05:30
Satyam-Rastogi b1fdda407d add leaderboard for canvassar 2026-05-15 12:05:05 +05:30
Satyam-Rastogi 00e9c2af00 adds on /off commission for team members in jobs,when comm is on then owner can edit comm 2026-05-14 19:08:31 +05:30
Satyam-Rastogi ef9fa1a401 org team managment removed promotion demotion infor section from org Settings page 2026-05-14 18:21:13 +05:30
Satyam-Rastogi d01e699250 access control by role plus by person in orgsettings 2026-05-14 18:13:42 +05:30
Satyam-Rastogi 69d81c78d0 org level commission distribution for each member 2026-05-14 13:24:16 +05:30
Satyam-Rastogi 5aff14323c door knock and referral attribution 2026-05-14 12:15:46 +05:30
Satyam-Rastogi 8157608ff0 create Teams tab in projectdetails page and display team managment section, removed from projects lists page 2026-05-13 20:24:33 +05:30
Satyam-Rastogi 138ec168b2 change org default commission from 10 to 0 2026-05-13 20:11:30 +05:30
Satyam-Rastogi b051b24fa2 Team Members section added in Projects List page 2026-05-13 19:59:37 +05:30
Satyam-Rastogi b6a7792bf7 org team management section in org Settings module 2026-05-13 18:55:09 +05:30
Satyam-Rastogi 72d541cab2 allow admin to access orgSetting page 2026-05-13 17:47:48 +05:30
Satyam-Rastogi 9bc8a42354 commission overrides in org Settings page 2026-05-13 12:51:36 +05:30
Satyam-Rastogi 7598f8982a adds access modifiers for each role 2026-05-12 21:08:19 +05:30
Satyam-Rastogi e85ecd2571 Org settings module and user roles 2026-05-12 20:36:44 +05:30
Satyam-Rastogi 17c3dc7307 team management feature in Owners Box 2026-05-12 19:29:52 +05:30
Satyam-Rastogi 91392bebcb add name for each entry of budget & cost table 2026-05-12 17:37:11 +05:30
Satyam-Rastogi 3a47e1f88f remove Payments tab and adds sections into budges- costs 2026-05-12 16:58:33 +05:30
Satyam-Rastogi c82cadd547 configurable commission setting 2026-05-12 15:54:01 +05:30
Satyam-Rastogi d32b3ced21 add commission section 2026-05-11 19:53:32 +05:30
Satyam-Rastogi e7b0fae1b3 Gross, Net Profit calculate 2026-05-11 18:56:04 +05:30