SME-Web/src/components/process/processStepOne/ContactModal.tsx

136 lines
5.0 KiB
TypeScript

import React, { useState } from 'react';
import { ContactTypeObj } from './RecipientAddCard';
import { Recipient } from '../../../store/slices/selectedRecipientsSlice';
interface ContactDataProps {
contactData: ContactTypeObj;
inpFirstName: string;
inpLastName: string;
inpEmail: string;
openContactModal: boolean;
setOpenContactModal: React.Dispatch<React.SetStateAction<boolean>>;
setRecipients: React.Dispatch<React.SetStateAction<Recipient>>;
topRef?: React.RefObject<HTMLDivElement>;
setManualFocusTriggered: React.Dispatch<React.SetStateAction<boolean>>
}
// Helper function to highlight matching text
const highlightText = (text: string, searchTerm: string, shouldHighlight: boolean) => {
if (!shouldHighlight || !searchTerm.trim()) {
return <span>{text}</span>;
}
const searchTermLower = searchTerm.toLowerCase();
const textLower = text.toLowerCase();
const index = textLower.indexOf(searchTermLower);
if (index === -1) {
return <span>{text}</span>;
}
const beforeMatch = text.slice(0, index);
const match = text.slice(index, index + searchTerm.length);
const afterMatch = text.slice(index + searchTerm.length);
return (
<span>
{beforeMatch}
<span className="bg-yellow-200 font-medium">{match}</span>
{afterMatch}
</span>
);
};
const ContactModal: React.FC<ContactDataProps> = ({
contactData,
inpFirstName,
inpLastName,
inpEmail,
openContactModal,
setRecipients,
setOpenContactModal ,
setManualFocusTriggered
}) => {
const handleContactClick = (indx: number) => {
if (!contactData.contacts.length) return;
setRecipients((prev) => ({
...prev, // Preserve other properties like uuid, newOne, etc.
firstName: contactData.contacts[indx].firstName,
lastName: contactData.contacts[indx].lastName,
email: contactData.contacts[indx].email,
}));
setOpenContactModal(false);
setManualFocusTriggered(false)
};
const handleKeyDown = (event: React.KeyboardEvent, indx: number) => {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
handleContactClick(indx);
}
};
if (!openContactModal || !contactData.contacts.length) {
return null;
}
return (
<div className="max-h-60 overflow-y-auto">
{contactData.contacts.map((contact, indx) => (
<div
key={contact.id || indx}
tabIndex={0}
onMouseDown={() => handleContactClick(indx)}
onKeyDown={(e) => handleKeyDown(e, indx)}
className="flex items-center px-3 py-2 cursor-pointer hover:bg-gray-50 transition-colors duration-150 focus:bg-gray-100 focus:outline-none rounded-md"
role="button"
aria-label={`Select contact ${contact.firstName} ${contact.lastName}`}
>
{/* Avatar */}
<div className="w-8 h-8 bg-[var(--primaryLight2)] rounded-full flex items-center justify-center text-white text-sm font-medium">
{(contact.firstName?.[0] || '') + (contact.lastName?.[0] || '')}
</div>
{/* Contact Info */}
<div className="ml-3 flex-1 min-w-0">
<div className="flex gap-1.5 items-center">
<p className="text-sm font-semibold text-gray-900 truncate">
{highlightText(
contact.firstName,
inpFirstName,
contactData.type === "firstName"
)}
</p>
<p className="text-sm font-semibold text-gray-900 truncate">
{highlightText(
contact.lastName,
inpLastName,
contactData.type === "lastName"
)}
</p>
</div>
<p className="text-xs text-gray-500 truncate">
{highlightText(
contact.email,
inpEmail,
contactData.type === "email"
)}
</p>
</div>
</div>
))}
{/* No results message */}
{contactData.contacts.length === 0 && (
<div className="px-3 py-4 text-center text-gray-500 text-sm">
No contacts found
</div>
)}
</div>
);
};
export default ContactModal;