feat(leads): Phase 5 & 6 — Insurance and Assignment sections

Phase 5 — Insurance (purple #8B5CF6):
- Insurance Company custom select, Claim Number + Claim Status (2-col grid)
- Adjuster Name + Adjuster Phone (2-col grid, flex-wrapper with Phone icon + mask)
- Policy Number full-width input, all focus rings use purple accent

Phase 6 — Assignment (cyan #06B6D4):
- Role-aware rep selector: Field Agents see self-assign toggle, Admins/Owners
  see scrollable list of all field agents with Unassigned option
- Priority pill selector (Low/Medium/High) with Framer Motion layoutId slide
- Follow-up Date: flex-wrapper with Calendar icon + color-scheme fix
- sectionCompletion wired for both sections

Fix: replace Framer Motion variant inheritance with explicit initial/animate on
each section motion.div — inherited variants from already-animated parent caused
Insurance and Assignment to render stuck at opacity:0 when added dynamically

Author: Satyam Rastogi
This commit is contained in:
Satyam
2026-03-14 23:43:08 +05:30
parent d3e2944fa3
commit d801f54600
3 changed files with 399 additions and 40 deletions
+26 -40
View File
@@ -11,6 +11,8 @@ import LeadSectionWrapper from '../components/leads/LeadSectionWrapper';
import LeadJobSection from '../components/leads/LeadJobSection';
import LeadContactSection from '../components/leads/LeadContactSection';
import LeadPropertySection from '../components/leads/LeadPropertySection';
import LeadInsuranceSection from '../components/leads/LeadInsuranceSection';
import LeadAssignmentSection from '../components/leads/LeadAssignmentSection';
import gsap from 'gsap';
// ---------------------------------------------------------------------------
@@ -59,23 +61,6 @@ const SECTIONS = [
},
];
// ---------------------------------------------------------------------------
// Animation variants
// ---------------------------------------------------------------------------
const containerVariants = {
hidden: {},
visible: { transition: { staggerChildren: 0.07 } },
};
const sectionVariants = {
hidden: { opacity: 0, y: 22 },
visible: {
opacity: 1,
y: 0,
transition: { type: 'spring', stiffness: 280, damping: 28 },
},
};
// ---------------------------------------------------------------------------
// Initial form state
// ---------------------------------------------------------------------------
@@ -144,8 +129,8 @@ export default function CreateLeadPage() {
job: isQuickCapture
? !!formData.leadSource
: !!(formData.leadSource && formData.leadType && formData.workType),
insurance: false, // Phase 5
assignment: false, // Phase 6
insurance: !!(formData.insuranceCompany && formData.claimStatus),
assignment: !!(formData.assignedTo && formData.followUpDate),
};
// Progress = % of visible sections that are complete
@@ -213,20 +198,24 @@ export default function CreateLeadPage() {
/>
);
}
// Placeholder for sections not yet built
return (
<div className={`rounded-xl border-2 border-dashed px-6 py-8 flex flex-col items-center justify-center gap-2 text-center
${isDark ? 'border-zinc-700' : 'border-zinc-200'}
`}>
<section.icon
size={28}
style={{ color: section.accentColor, opacity: 0.35 }}
if (section.id === 'insurance') {
return (
<LeadInsuranceSection
formData={formData}
updateField={updateField}
/>
<p className="text-xs font-semibold uppercase tracking-widest text-zinc-400">
{section.description}
</p>
</div>
);
);
}
if (section.id === 'assignment') {
return (
<LeadAssignmentSection
formData={formData}
updateField={updateField}
currentUser={user}
/>
);
}
return null;
};
return (
@@ -325,17 +314,14 @@ export default function CreateLeadPage() {
</div>
{/* --- Sections --- */}
<motion.div
variants={containerVariants}
initial="hidden"
animate="visible"
className="space-y-3"
>
<div className="space-y-3">
<AnimatePresence mode="popLayout">
{visibleSections.map(section => (
<motion.div
key={section.id}
variants={sectionVariants}
initial={{ opacity: 0, y: 22 }}
animate={{ opacity: 1, y: 0 }}
transition={{ type: 'spring', stiffness: 280, damping: 28 }}
layout
exit={{
opacity: 0,
@@ -357,7 +343,7 @@ export default function CreateLeadPage() {
</motion.div>
))}
</AnimatePresence>
</motion.div>
</div>
</div>
{/* ----------------------------------------------------------------