d801f54600
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
139 lines
5.4 KiB
React
139 lines
5.4 KiB
React
import React from 'react';
|
|
import { Phone } from 'lucide-react';
|
|
import { LEAD_FORM_OPTIONS } from '../../data/mockStore';
|
|
import LeadCustomSelect from './LeadCustomSelect';
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Shared field primitives
|
|
// ---------------------------------------------------------------------------
|
|
function FieldLabel({ children }) {
|
|
return (
|
|
<label className="block text-[11px] uppercase tracking-widest font-bold text-zinc-400 dark:text-zinc-500 mb-1.5">
|
|
{children}
|
|
</label>
|
|
);
|
|
}
|
|
|
|
function LeadInput({ label, value, onChange, placeholder, type = 'text' }) {
|
|
return (
|
|
<div>
|
|
<FieldLabel>{label}</FieldLabel>
|
|
<input
|
|
type={type}
|
|
value={value}
|
|
onChange={e => onChange(e.target.value)}
|
|
placeholder={placeholder}
|
|
className="w-full rounded-xl px-4 py-3 text-sm font-medium
|
|
outline-none transition-all duration-150
|
|
bg-white dark:bg-zinc-800/60
|
|
border border-zinc-200 dark:border-zinc-700
|
|
text-zinc-800 dark:text-white
|
|
placeholder-zinc-400 dark:placeholder-zinc-500
|
|
focus:border-purple-400 dark:focus:border-purple-500
|
|
focus:ring-2 focus:ring-purple-100 dark:focus:ring-purple-500/20"
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Phone input with (xxx) xxx-xxxx mask and purple focus ring
|
|
function AdjusterPhoneInput({ label, value, onChange }) {
|
|
const handleChange = (e) => {
|
|
const digits = e.target.value.replace(/\D/g, '').slice(0, 10);
|
|
let formatted = digits;
|
|
if (digits.length >= 7) {
|
|
formatted = `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6)}`;
|
|
} else if (digits.length >= 4) {
|
|
formatted = `(${digits.slice(0, 3)}) ${digits.slice(3)}`;
|
|
} else if (digits.length >= 1) {
|
|
formatted = `(${digits}`;
|
|
}
|
|
onChange(formatted);
|
|
};
|
|
|
|
return (
|
|
<div>
|
|
<FieldLabel>{label}</FieldLabel>
|
|
<div className="flex items-center rounded-xl
|
|
bg-white dark:bg-zinc-800/60
|
|
border border-zinc-200 dark:border-zinc-700
|
|
focus-within:border-purple-400 dark:focus-within:border-purple-500
|
|
focus-within:ring-2 focus-within:ring-purple-100 dark:focus-within:ring-purple-500/20
|
|
transition-all duration-150"
|
|
>
|
|
<Phone size={14} className="ml-4 shrink-0 text-zinc-400 pointer-events-none" />
|
|
<input
|
|
type="tel"
|
|
value={value}
|
|
onChange={handleChange}
|
|
placeholder="(555) 000-0000"
|
|
className="flex-1 py-3 pl-3 pr-4 text-sm font-medium
|
|
outline-none bg-transparent
|
|
text-zinc-800 dark:text-white
|
|
placeholder-zinc-400 dark:placeholder-zinc-500"
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Insurance Section — Phase 5 (Full Form only)
|
|
// ---------------------------------------------------------------------------
|
|
export default function LeadInsuranceSection({ formData, updateField }) {
|
|
return (
|
|
<div className="space-y-4">
|
|
{/* Row 1: Insurance Company (full width) */}
|
|
<LeadCustomSelect
|
|
label="Insurance Company"
|
|
value={formData.insuranceCompany}
|
|
onChange={v => updateField('insuranceCompany', v)}
|
|
options={LEAD_FORM_OPTIONS.insuranceCompanies}
|
|
placeholder="Select carrier…"
|
|
accent="purple"
|
|
/>
|
|
|
|
{/* Row 2: Claim Number + Claim Status */}
|
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
<LeadInput
|
|
label="Claim Number"
|
|
value={formData.claimNumber}
|
|
onChange={v => updateField('claimNumber', v)}
|
|
placeholder="e.g. CLM-2026-00482"
|
|
/>
|
|
<LeadCustomSelect
|
|
label="Claim Status"
|
|
value={formData.claimStatus}
|
|
onChange={v => updateField('claimStatus', v)}
|
|
options={LEAD_FORM_OPTIONS.claimStatuses}
|
|
placeholder="Select status…"
|
|
accent="purple"
|
|
/>
|
|
</div>
|
|
|
|
{/* Row 3: Adjuster Name + Adjuster Phone */}
|
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
<LeadInput
|
|
label="Adjuster Name"
|
|
value={formData.adjusterName}
|
|
onChange={v => updateField('adjusterName', v)}
|
|
placeholder="Full name"
|
|
/>
|
|
<AdjusterPhoneInput
|
|
label="Adjuster Phone"
|
|
value={formData.adjusterPhone}
|
|
onChange={v => updateField('adjusterPhone', v)}
|
|
/>
|
|
</div>
|
|
|
|
{/* Row 4: Policy Number (full width) */}
|
|
<LeadInput
|
|
label="Policy Number"
|
|
value={formData.policyNumber}
|
|
onChange={v => updateField('policyNumber', v)}
|
|
placeholder="e.g. POL-7734892-A"
|
|
/>
|
|
</div>
|
|
);
|
|
}
|