diff --git a/src/components/LeadVerification/AssignLeadModal.jsx b/src/components/LeadVerification/AssignLeadModal.jsx new file mode 100644 index 0000000..bd444b5 --- /dev/null +++ b/src/components/LeadVerification/AssignLeadModal.jsx @@ -0,0 +1,159 @@ +import React, { useEffect, useMemo, useState } from 'react'; +import { createPortal } from 'react-dom'; +import { X, User, Repeat, UserPlus, Loader2 } from 'lucide-react'; +import { useMockStore } from '../../data/mockStore'; +import Select from '../ui/Select'; + +// One modal handles both "Assign" and "Reassign" — `mode` differentiates copy +// and target action. `mode='reassign'` is the In Progress flow. +// Assignee list is sourced from `users` (store key) filtered to role === 'ADMIN'. +// Field names match our store shape: assigneeId / assigneeName (not assignedToId/assignedToName). +const AssignLeadModal = ({ isOpen, onClose, lead, mode = 'assign' }) => { + const { users, assignLeadVerification, reassignLeadVerification } = useMockStore(); + const [selectedId, setSelectedId] = useState(''); + const [submitting, setSubmitting] = useState(false); + + const isReassign = mode === 'reassign'; + + // Build the assignee list from admin users, excluding the currently assigned one. + const adminUsers = useMemo( + () => (users || []).filter(u => u.role === 'ADMIN'), + [users], + ); + + const available = useMemo( + () => adminUsers.filter(p => p.id !== lead?.assigneeId), + [adminUsers, lead], + ); + + useEffect(() => { + if (isOpen) { + setSelectedId(''); + setSubmitting(false); + } + }, [isOpen]); + + useEffect(() => { + if (!isOpen) return; + const onKey = (e) => { if (e.key === 'Escape') onClose(); }; + const prevOverflow = document.body.style.overflow; + document.body.style.overflow = 'hidden'; + window.addEventListener('keydown', onKey); + return () => { + document.body.style.overflow = prevOverflow; + window.removeEventListener('keydown', onKey); + }; + }, [isOpen, onClose]); + + if (!isOpen || !lead) return null; + + const handleConfirm = async () => { + if (!selectedId) return; + const target = adminUsers.find(a => a.id === selectedId); + if (!target) return; + setSubmitting(true); + await new Promise(r => setTimeout(r, 250)); + if (isReassign) reassignLeadVerification(lead.id, target.id, target.name); + else assignLeadVerification(lead.id, target.id, target.name); + setSubmitting(false); + onClose(); + }; + + const Icon = isReassign ? Repeat : UserPlus; + const headerIconCls = isReassign + ? 'bg-purple-500/10 text-purple-500' + : 'bg-blue-500/10 text-blue-500'; + + return createPortal( +
+
+
+
+
+
+ +
+

+ {isReassign ? 'Reassign Lead' : 'Assign Lead'} +

+
+ +
+ +
+
+ {isReassign ? 'Reassign ' : 'Assign '} + {lead.customerName} + {' '}({lead.leadId}) + {lead.assigneeName && ( + <> + {' currently with '} + {lead.assigneeName} + + )} + . +
+ +
+ + setSearch(e.target.value)} + className="w-full bg-zinc-100 dark:bg-black/40 border border-zinc-200 dark:border-white/10 rounded-xl py-2 pl-10 pr-4 text-sm text-zinc-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500/20" + /> +
+ + {/* Status */} +
+ + ({ value: s, label: s })), + ]} + /> +
+ + {/* Assignee */} +
+ +