import { useDispatch, useSelector } from "react-redux"; import { removeRecipientAsync, removeSelectedRecipient, updateRecipientOrder, TRANSACTION_TEMPLATE_TOGGLE, updateRecipient, recipientType, } 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 { FiEdit } from "react-icons/fi"; import { FaUsersLine } from "react-icons/fa6"; 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); }; return (
{recipients.length > 0 ? ( <> {recipients.length > 1 && (

Recipients ({recipients.length})

)}
{recipients.map((recipient, idx) => (
{/* Main Content Section */}
{/* Order Number */} {recipients.length > 1 ? (
handleOrderChange( recipient.id || recipient.email, Number(e.target.value) ) } 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 bg-slate-100" />
) : ( handleOrderChange( recipient.id || recipient.email, 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 */}

{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;