import { useDispatch, useSelector } from "react-redux"; import { removeRecipientAsync, removeSelectedRecipient, updateRecipientOrder, TRANSACTION_TEMPLATE_TOGGLE, updateRecipient, recipientType, setSelectedRecipients, reorderAllRecipientAscOrder, updateRecipientByIndxAndRo, } from "../../../store/slices/selectedRecipientsSlice"; import { AppDispatch, RootState } from "../../../store/store"; import { ImBin } from "react-icons/im"; import { useState } from "react"; import SigningOrderDiagram from "../../../SigningOrderDiagram "; import { IoCloseOutline } from "react-icons/io5"; import { useParams } from "react-router-dom"; import { FaUsersLine } from "react-icons/fa6"; import { BiSolidHelpCircle } from "react-icons/bi"; import { DndContext, closestCenter, DragEndEvent, } from "@dnd-kit/core"; import { arrayMove, SortableContext, useSortable, verticalListSortingStrategy, } from "@dnd-kit/sortable"; import { CSS } from "@dnd-kit/utilities"; import SortableRecipient from "./SortableRecipient"; const getInitials = (name: string) => { if (!name) return ""; return name .split(" ") .map((n) => n[0]) .join("") .toUpperCase(); }; type CardsData = { userEmail: string; // getMinRoutingOrder: () => number; editRecipient: any; setEditRecipient: (recipient: any) => void; setEditCase: (string: any) => void; transactionTemplateToggle: string; editRecipientCurrentEmail: string; setEditRecipientCurrentEmail: (email: string) => void; }; const RecipientCards = ({ setEditRecipient, setEditCase, transactionTemplateToggle, editRecipient, editRecipientCurrentEmail, setEditRecipientCurrentEmail, }: CardsData) => { const templateId = useParams<{ templateId: string }>().templateId; let { accountId, transactionId } = useParams<{ accountId: string; transactionId: string }>(); const dispatch = useDispatch(); if (!transactionId) { transactionId = templateId; } const recipients = useSelector((state: RootState) => state.selectedRecipients.recipients); const signType = useSelector((state: RootState) => state.selectedDocuments.signType); const [signingOrderModal, setSigningOrderModal] = useState({ open: false }); const [editingField, setEditingField] = useState<{ recipientId: string; fieldName: string } | null>(null); const [localChanges, setLocalChanges] = useState>({}); const [errors, setErrors] = useState>({}); const getRecipientIdentifier = (recipient: any) => { return recipient.id || recipient.uuid; }; const isEditable = (recipient: any) => { return transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES ? true : recipient.newOne || recipient.allowSenderToEdit; }; const validateInPersonSignerFields = (recipient: any, updatedFields: any) => { if (recipient.type !== recipientType.INPERSONSIGNER) return true; const hostName = updatedFields.hostName ?? getCurrentValue(recipient, "hostName"); const hostEmail = updatedFields.hostEmail ?? getCurrentValue(recipient, "hostEmail"); const identifier = getRecipientIdentifier(recipient); const newErrors = { hostName: !hostName, hostEmail: !hostEmail }; setErrors((prev) => ({ ...prev, [identifier]: newErrors })); return !newErrors.hostName && !newErrors.hostEmail; }; const handleFieldFocus = (recipientId: string, fieldName: string) => { setEditingField({ recipientId, fieldName }); }; const handleFieldBlur = (recipient: any, fieldName: string, value: any) => { const identifier = getRecipientIdentifier(recipient); const updatedRecipient = { ...recipient, [fieldName]: value, uuid: identifier }; if (recipient.type === recipientType.INPERSONSIGNER && (fieldName === "hostName" || fieldName === "hostEmail")) { if (!validateInPersonSignerFields(recipient, { [fieldName]: value })) { return; } } dispatch(updateRecipient(updatedRecipient)); setLocalChanges((prev) => ({ ...prev, [`${identifier}_${fieldName}`]: undefined, })); setEditingField(null); setErrors((prev) => ({ ...prev, [identifier]: { hostName: false, hostEmail: false } })); }; const handleFieldChange = (recipient: any, fieldName: string, value: any) => { const identifier = getRecipientIdentifier(recipient); setLocalChanges((prev) => ({ ...prev, [`${identifier}_${fieldName}`]: value, })); }; const getCurrentValue = (recipient: any, fieldName: string) => { const identifier = getRecipientIdentifier(recipient); const localValue = localChanges[`${identifier}_${fieldName}`]; return localValue !== undefined ? localValue : recipient[fieldName]; }; const hasValue = (recipient: any, fieldName: string) => { const currentValue = getCurrentValue(recipient, fieldName); return currentValue && currentValue.toString().trim() !== ""; }; const renderEditableField = ( recipient: any, fieldName: string, placeholder: string, className = "", type = "text" ) => { const identifier = getRecipientIdentifier(recipient); const currentValue = getCurrentValue(recipient, fieldName); const error = errors[identifier]?.[fieldName]; const editable = isEditable(recipient); return (
handleFieldFocus(identifier, fieldName)} onBlur={(e) => handleFieldBlur(recipient, fieldName, e.target.value)} onChange={(e) => handleFieldChange(recipient, fieldName, e.target.value)} onKeyPress={(e) => { if (e.key === "Enter") { e.currentTarget.blur(); } }} disabled={!editable} className={`w-full px-2 sm:px-3 lg:px-4 py-1.5 sm:py-2 font-normal border focus:outline-none focus:ring-2 focus:ring-[var(--primary)] transition ${error ? "border-red-500 placeholder-red-500 text-xs" : "border-gray-300"} rounded-lg text-xs sm:text-sm ${className} ${!editable ? "bg-gray-100 cursor-not-allowed" : ""}`} title={editable ? "Edit field" : "Editing disabled"} />
); }; const handleOrderChange = (id: string, value: number) => { dispatch(updateRecipientOrder({ id, routingOrder: value })); }; const handleEditRecipient = (recipient: any) => { setEditCase("Edit"); setEditRecipient(recipient); setEditRecipientCurrentEmail(recipient.id || recipient.uuid); }; const handleRemoveRecipient = (recipient: any) => { if (!accountId || !transactionId) return; if (recipient.uuid) { dispatch(removeSelectedRecipient(recipient)); } else { dispatch( removeRecipientAsync({ recipientId: recipient.id, email: recipient.email, accountId: accountId, transactionId: transactionId, }) ); } if (recipients.length === 2) { const leftRecipient = recipients.filter((obj) => { if ("id" in obj && "id" in recipient) { return obj.id !== recipient.id; } if ("email" in obj && "email" in recipient) { return obj.email !== recipient.email; } return false; }); dispatch( updateRecipientOrder({ id: leftRecipient[0].id || leftRecipient[0].email, routingOrder: 1 }) ); } }; const handleTypeChange = (recipient: any, type: string) => { const identifier = getRecipientIdentifier(recipient); const updatedRecipient = { ...recipient, type, uuid: identifier }; if (type === recipientType.SIGNER || type === recipientType.CC) { updatedRecipient.hostName = ""; updatedRecipient.hostEmail = ""; setErrors((prev) => ({ ...prev, [identifier]: { hostName: false, hostEmail: false } })); } else if (type === recipientType.INPERSONSIGNER) { if (!validateInPersonSignerFields(recipient, updatedRecipient)) { return; } } dispatch(updateRecipient(updatedRecipient)); setEditingField(null); }; const handleDragEnd = (event: DragEndEvent) => { const { active, over } = event; if (!over || active.id === over.id) return; console.log(over, "Over") console.log(active, "Active") const activeIndex = recipients.findIndex((r) => (r.id || r.uuid) === active.id); const overIndex = recipients.findIndex((r) => (r.id || r.uuid) === over.id); const activeRec = recipients[activeIndex] const overRec = recipients[overIndex] const activeRecRo = Number(activeRec.routingOrder) === 0 || !activeRec.routingOrder ? 1 : activeRec.routingOrder const overRecRo = Number(overRec.routingOrder) === 0 || !overRec.routingOrder ? 1 : overRec.routingOrder let newActiveRecRo = 1 let newOverRecRo = 1 // if (activeRec.routingOrder >= overRecRo && activeIndex > overIndex) { // newActiveRecRo = activeRecRo > 1 ? activeRecRo - 1 : 1 // newOverRecRo = activeRecRo > 1 ? activeRecRo + 1 : 2 // } // if (activeRec.routingOrder >= overRecRo && activeIndex < overIndex) { // newActiveRecRo = overRecRo > 1 ? overRecRo + 1 : 2 // newOverRecRo = overRecRo > 1 ? overRecRo - 1 : 1 // } // if (activeRec.routingOrder <= overRecRo && activeIndex > overIndex) { // newActiveRecRo = activeRecRo > 1 ? activeRecRo - 1 : 1 // newOverRecRo = activeRecRo > 1 ? activeRecRo + 1 : 2 // } // if (activeRec.routingOrder <= overRecRo && activeIndex < overIndex) { // newActiveRecRo = overRecRo > 1 ? overRecRo + 1 : 2 // newOverRecRo = overRecRo > 1 ? overRecRo - 1 : 1 // } // if (activeRec.routingOrder > overRecRo && activeIndex < overIndex) { // console.log(activeIndex, overIndex, "283 2") // newActiveRecRo = overRecRo > 1 ? overRecRo : 2 // newOverRecRo = activeRecRo > 1 ? activeRecRo : 1 // } // if (activeRec.routingOrder < overRecRo && activeIndex > overIndex) { // console.log(activeIndex, overIndex, "283 3") // newActiveRecRo = overRecRo > 1 ? overRecRo : 1 // newOverRecRo = activeRecRo > 1 ? activeRecRo : 2 // } if (activeRecRo > overRecRo && activeIndex > overIndex) { console.log(activeIndex, overIndex, "283 1") newActiveRecRo = activeRecRo > 1 ? overRecRo : 1 newOverRecRo = overRecRo > 1 ? activeRecRo : 2 } if (activeRecRo > overRecRo && activeIndex < overIndex) { console.log(activeIndex, overIndex, "283 kam") newActiveRecRo = activeRecRo > 1 ? activeRecRo : 2 newOverRecRo = overRecRo > 1 ? overRecRo : 1 } if (activeRecRo < overRecRo && activeIndex < overIndex) { console.log(activeIndex, overIndex, "283 4") newActiveRecRo = overRecRo > 1 ? overRecRo : 2 newOverRecRo = activeRecRo > 1 ? activeRecRo : 1 } if (activeRecRo < overRecRo && activeIndex > overIndex) { console.log(activeIndex, overIndex, "283 mak") newActiveRecRo = activeRecRo > 1 ? activeRecRo : 1 newOverRecRo = overRecRo > 1 ? overRecRo : 1 } if (activeRecRo === activeRecRo && activeIndex < overIndex) { newActiveRecRo = activeRecRo > 1 ? activeRecRo + 1 : 2 newOverRecRo = overRecRo > 1 ? overRecRo : 1 } if (activeRecRo === overRecRo && activeIndex > overIndex) { newActiveRecRo = activeRecRo > 1 ? activeRecRo : 1 newOverRecRo = overRecRo > 1 ? overRecRo + 1 : 2 } // let reordered = recipients.map((r, idx) => { // if (idx === activeIndex) { // return ( // { // ...r, routingOrder: newActiveRecRo // } // ) // } // if (idx === overRecRo) { // return ( // { // ...r, routingOrder: newOverRecRo // } // ) // } // }); // dispatch(updateRecipientOrder({ id: activeRec.id || activeRec.uuid, routingOrder: newActiveRecRo })); // dispatch(updateRecipientOrder({ id: overRec.id || overRec.uuid, routingOrder: newOverRecRo })); dispatch(updateRecipientByIndxAndRo({ indx1: activeIndex, ro1: newActiveRecRo, indx2: overIndex, ro2: newOverRecRo, })); // dispatch(reorderAllRecipientAscOrder()); }; return (
{recipients.length > 0 ? ( <> {recipients.length > 1 && (

Recipients ({recipients.length})

)} r.id || r.uuid)} strategy={verticalListSortingStrategy} >
{recipients.map((recipient, idx) => (
{/* Main Content Section */}
{/* Order Number */} {recipients.length > 1 ? (
{ const value = e.target.value; if (/^\d*$/.test(value)) { const num = Number(value); handleOrderChange(recipient.id || recipient.uuid, num); } }} onKeyDown={(e) => { if (!/[0-9]/.test(e.key) && e.key !== "Backspace" && e.key !== "Tab") { e.preventDefault(); } }} className="w-8 sm:w-10 h-6 text-center rounded text-sm text-gray-600 focus:outline-none focus:ring-[var(--primary)] border border-dashed border-gray-400" /> {idx === 0 && recipients.length > 1 &&

{/* Tooltip */} Signing order: Recipients receive emails one after another. Same order means they all receive at once.

}
) : ( handleOrderChange( recipient.id || recipient.uuid, Number(e.target.value) ) } className="w-6 sm:w-8 text-center rounded text-sm text-gray-700 border-none focus:outline-none focus:ring-[var(--primary)] flex-shrink-0" /> )} {/* Avatar */} {/*
{getInitials(`${recipient.firstName} ${recipient.lastName || ""}`)}
*/} {/* Form Fields Section */}
{/* Role Name and Permissions Row */}
{transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES &&
{renderEditableField(recipient, "roleName", "Role name")}
} {/* Permissions - Mobile: Below role, Desktop: Right side */}
{transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES && (
)}
{/* Name and Email Fields */}
{/* Mobile: Stack vertically, Tablet+: Side by side */}
{renderEditableField(recipient, "firstName", "First Name")}
{renderEditableField(recipient, "lastName", "Last Name")}
{renderEditableField(recipient, "email", "Recipient Email", "", "email")}
{/* Host Fields (for In-Person Signers) */} {recipient.type === recipientType.INPERSONSIGNER && (
{renderEditableField(recipient, "hostName", "Host Name")}
{renderEditableField(recipient, "hostEmail", "Host Email", "", "email")}
)} {/* Recipient Type Radio Buttons */}
{/* Action Buttons */} {signType !== "self-sign" && (
)}
))}
) : (
No Recipients Added
)} {/* Responsive Modal */} {signingOrderModal.open && (

Signing Order

setSigningOrderModal({ ...signingOrderModal, open: false })} className="text-xl sm:text-2xl cursor-pointer hover:text-gray-200 transition-all p-1" >
)}
); }; export default RecipientCards; // // r.id || r.uuid)} // strategy={verticalListSortingStrategy} // > //
// {recipients.map((recipient, idx) => ( // // {/* 🔹 your existing recipient card content goes here */} // // ))} //
//
//