mobile: Optimizations for Maps Drawer, Legend, and Customer Profile Tabs

This commit is contained in:
Satyam
2026-02-10 20:36:44 +05:30
parent 91b47e83c3
commit 83250d687e
15 changed files with 1140 additions and 91 deletions
+202
View File
@@ -0,0 +1,202 @@
import React, { useState, useEffect } from 'react';
import { Icons } from './landing/constants';
// Updated with DFW specific locations (roughly positioned for a conceptual map)
const hotspots = [
{ id: 1, top: '45%', left: '65%', address: '2800 Routh St, Dallas', problem: 'Hail Impact (Severe)', gain: '+$28k Opportunity', weather: 'Hail Expected', status: 'Action Required' },
{ id: 2, top: '20%', left: '55%', address: 'Legacy West, Plano', problem: 'Thermal Leak Detected', gain: '+$145k Commercial', weather: 'Clear', status: 'Monitoring' },
{ id: 3, top: '60%', left: '35%', address: 'Sundance Sq, Fort Worth', problem: 'Missing Shingles', gain: '+$15k Repair', weather: 'Rain Soon', status: 'Urgent' },
];
const IntelligenceMap = () => {
const [activeSpot, setActiveSpot] = useState(null);
const [showRescheduleDialog, setShowRescheduleDialog] = useState(false);
useEffect(() => {
// Simulate incoming weather alert
const timer = setTimeout(() => {
setShowRescheduleDialog(true);
}, 2500);
return () => clearTimeout(timer);
}, []);
return (
<section className="py-24 bg-gray-900 border-t border-white/5 relative overflow-hidden">
<div className="container mx-auto px-4 relative z-10">
<div className="mb-12 text-center max-w-4xl mx-auto">
<div className="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-cyan-400/10 border border-cyan-400/20 mb-4">
<div className="w-1.5 h-1.5 bg-cyan-400 rounded-full animate-pulse"></div>
<span className="text-cyan-400 text-xs font-mono font-bold uppercase tracking-widest">Live CRM Data Feed</span>
</div>
<h2 className="text-3xl md:text-5xl font-heading font-bold text-white mb-6">Hyper-Local Sales Intelligence</h2>
<p className="text-gray-400 text-lg max-w-2xl mx-auto">
Our systems overlay live NOAA weather data with property value insights. Maximize revenue by targeting neighborhoods directly in the storm path.
</p>
</div>
{/* Map Container Frame */}
<div className="relative w-full h-[650px] bg-black rounded-2xl border border-white/20 shadow-2xl overflow-hidden group isolate ring-1 ring-white/10">
{/* Map Background - DFW Satellite Style */}
<div className="absolute inset-0 bg-[#0f172a]">
{/* Aerial/Satellite View of a Grid City */}
<img
src="https://images.unsplash.com/photo-1477959858617-67f85cf4f1df?q=80&w=2613&auto=format&fit=crop"
alt="DFW Metroplex Map Overlay"
className="w-full h-full object-cover opacity-50 mix-blend-luminosity hover:scale-105 transition-transform duration-[20s]"
/>
{/* Map Grid Overlay */}
<div className="absolute inset-0 bg-[url('https://grainy-gradients.vercel.app/noise.svg')] opacity-20"></div>
<div className="absolute inset-0 bg-grid-pattern opacity-10 bg-[length:40px_40px] border-t border-white/5"></div>
{/* Region Indicator - HUD Style */}
<div className="absolute top-6 left-6 z-30">
<div className="bg-slate-900/80 backdrop-blur-md text-white pl-4 pr-6 py-2 rounded-r-lg border-l-4 border-cyan-400 shadow-[0_0_15px_rgba(0,229,255,0.2)] flex items-center gap-3">
<div>
<div className="text-[10px] text-cyan-400 font-bold uppercase tracking-widest mb-0.5">Active Region</div>
<div className="font-heading font-bold text-lg leading-none">North Texas / DFW</div>
</div>
</div>
</div>
{/* Weather Overlay Widget */}
<div className="absolute top-0 right-0 w-full h-full bg-gradient-to-bl from-slate-900/80 via-transparent to-transparent pointer-events-none"></div>
<div className="absolute top-6 right-6 p-4 bg-black/60 backdrop-blur-md rounded-lg border border-white/10 max-w-xs z-30">
<div className="flex items-center gap-4">
<div className="bg-white/10 p-2 rounded-full text-white">
<span className="text-2xl"></span>
</div>
<div>
<div className="font-bold text-white text-sm">Severe Hail Watch</div>
<div className="text-xs text-cyan-400 animate-pulse">Approaching Tarrant County</div>
<div className="text-[10px] text-gray-500 font-mono mt-1">ETA: 15 MINS</div>
</div>
</div>
</div>
</div>
{/* Interactive Pins */}
{hotspots.map((spot) => (
<div
key={spot.id}
className="absolute group/pin z-20 cursor-pointer"
style={{ top: spot.top, left: spot.left }}
onClick={() => setActiveSpot(spot)}
>
{/* Radar Ripple Effect */}
<div className="absolute -inset-4 bg-cyan-400/20 rounded-full animate-ping opacity-75"></div>
{/* Price Tag Pin */}
<div className="relative flex flex-col items-center transform group-hover/pin:scale-110 transition-transform duration-200">
<div className="bg-slate-900/90 backdrop-blur text-cyan-400 text-[10px] font-mono font-bold px-2 py-1 rounded border border-cyan-400/30 shadow-[0_0_10px_rgba(0,229,255,0.3)] whitespace-nowrap mb-1 opacity-0 group-hover/pin:opacity-100 transition-opacity">
{spot.gain}
</div>
{/* Pin Head */}
<div className={`w-3 h-3 rounded-full border-2 border-white shadow-lg relative z-10 ${spot.problem.includes('Severe') ? 'bg-red-600 shadow-[0_0_15px_rgba(214,40,40,0.6)]' : 'bg-cyan-400 shadow-[0_0_15px_rgba(0,229,255,0.6)]'}`}></div>
{/* Pin Line */}
<div className="w-[1px] h-8 bg-gradient-to-b from-white to-transparent opacity-50"></div>
{/* Ground Shadow */}
<div className="absolute bottom-0 w-6 h-1.5 bg-black/60 blur-sm rounded-[100%] translate-y-1"></div>
</div>
</div>
))}
{/* Reschedule Dialog Overlay */}
{showRescheduleDialog && (
<div className="absolute bottom-8 left-1/2 transform -translate-x-1/2 md:left-8 md:translate-x-0 z-50 w-[90%] md:w-96">
<div className="bg-white/95 backdrop-blur-xl rounded-xl shadow-2xl p-6 border-l-4 border-red-600 animate-[slideUp_0.5s_ease-out]">
<div className="flex justify-between items-start mb-3">
<div className="flex items-center gap-3">
<div className="w-8 h-8 bg-red-100 rounded-full flex items-center justify-center text-red-600 font-bold text-lg">!</div>
<div>
<h4 className="font-bold text-slate-900 text-sm uppercase tracking-wide">Schedule Conflict</h4>
</div>
</div>
<button onClick={() => setShowRescheduleDialog(false)} className="text-gray-400 hover:text-black"></button>
</div>
<p className="text-gray-600 text-sm mb-4 leading-relaxed">
<strong>Heavy rainfall expected in Plano at 2:00 PM.</strong> <br />
This conflicts with the inspection at <span className="text-slate-900 font-semibold">Legacy West</span>.
</p>
<div className="flex gap-3">
<button className="flex-1 bg-slate-900 text-white text-xs font-bold py-2.5 rounded hover:bg-slate-800 transition-colors uppercase tracking-wider">
Reschedule
</button>
<button onClick={() => setShowRescheduleDialog(false)} className="flex-1 bg-gray-100 text-gray-600 text-xs font-bold py-2.5 rounded hover:bg-gray-200 transition-colors uppercase tracking-wider">
Dismiss
</button>
</div>
</div>
</div>
)}
{/* Right Sidebar Panel (Glass Detail View) */}
{activeSpot && (
<div className="absolute top-4 right-4 bottom-4 w-80 bg-slate-900/80 backdrop-blur-xl rounded-xl p-6 shadow-2xl border border-white/10 transform transition-transform duration-300 z-40 flex flex-col text-white">
<div className="flex justify-between items-center mb-6 pb-4 border-b border-white/10">
<div className="flex items-center gap-2">
<div className="w-2 h-2 bg-cyan-400 rounded-full animate-pulse"></div>
<h3 className="font-heading font-bold text-lg tracking-wide">INTEL_FEED</h3>
</div>
<button onClick={() => setActiveSpot(null)} className="text-gray-400 hover:text-white transition-colors"></button>
</div>
<div className="flex-grow space-y-6">
<div className="p-4 bg-cyan-400/5 rounded-lg border border-cyan-400/20 relative overflow-hidden">
<div className="absolute top-0 right-0 p-1 opacity-20">
<Icons.Chart />
</div>
<label className="text-[10px] text-cyan-400 font-bold uppercase tracking-widest mb-1 block">Projected Value</label>
<div className="text-3xl font-heading font-bold text-white">{activeSpot.gain}</div>
</div>
<div>
<label className="text-[10px] text-gray-500 font-bold uppercase tracking-widest mb-1 block">Location Target</label>
<div className="text-white font-bold text-lg leading-tight mb-1">{activeSpot.address}</div>
<div className="text-xs text-gray-400">Dallas-Fort Worth Metroplex</div>
</div>
<div>
<label className="text-[10px] text-gray-500 font-bold uppercase tracking-widest mb-1 block">Detected Issue</label>
<div className={`flex items-center gap-2 font-bold ${activeSpot.problem.includes('Severe') ? 'text-red-500' : 'text-yellow-400'}`}>
<span></span> {activeSpot.problem}
</div>
</div>
<div className="p-3 bg-white/5 rounded border border-white/10 text-xs text-gray-300 font-mono leading-relaxed">
&gt; ANALYSIS: 85% probability of insurance approval due to recent hail corridor overlap in zip code 75201.
</div>
</div>
<button className="w-full bg-cyan-400 hover:bg-white text-slate-900 font-bold py-3 rounded-lg transition-all duration-300 shadow-[0_0_20px_rgba(0,229,255,0.3)] hover:shadow-[0_0_30px_rgba(255,255,255,0.4)] uppercase tracking-widest text-xs">
Dispatch Sales Rep
</button>
</div>
)}
</div>
</div>
<style>{`
@keyframes slideUp {
from { opacity: 0; transform: translate(-50%, 20px); }
to { opacity: 1; transform: translate(-50%, 0); }
}
@media (min-width: 768px) {
@keyframes slideUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
}
`}</style>
</section>
);
};
export default IntelligenceMap;