214 lines
7.4 KiB
TypeScript
214 lines
7.4 KiB
TypeScript
import { useEffect, useRef, useState } from "react";
|
|
import { FaPlus } from "react-icons/fa";
|
|
import { addRecipient, Recipient, recipientType } from "../../../store/slices/selectedRecipientsSlice";
|
|
import { useDispatch } from "react-redux";
|
|
import { AppDispatch } from "../../../store/store";
|
|
import api from "../../../config/api";
|
|
import ContactModal from "./ContactModal";
|
|
import useDebouncedEffect from "../../../utlity/useDebounce";
|
|
|
|
interface ContactType {
|
|
id: string;
|
|
email: string;
|
|
firstName: string;
|
|
lastName: string;
|
|
}
|
|
|
|
export interface ContactTypeObj {
|
|
type: string;
|
|
contacts: ContactType[];
|
|
}
|
|
|
|
const RecipientAddCard = () => {
|
|
|
|
const [contactData, setContactData] = useState<ContactTypeObj>({ type: "", contacts: [] });
|
|
const [openContactModal, setOpenContactModal] = useState(false);
|
|
|
|
const dispatch = useDispatch<AppDispatch>();
|
|
const formRef = useRef<HTMLFormElement | null>(null);
|
|
|
|
const [recipient, setRecipients] = useState<Recipient>({ firstName: "", lastName: "", email: "", hostName: "", hostEmail: "", type: recipientType.SIGNER });
|
|
|
|
const handleRecipientAdd = (e: React.FormEvent<HTMLFormElement>) => {
|
|
e.preventDefault();
|
|
|
|
if (recipient.firstName === "" || recipient.lastName === "" || recipient.email === "" || !recipient.type) return;
|
|
|
|
// Validate Email Format
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
if (!emailRegex.test(recipient.email)) {
|
|
console.log("Invalid email format");
|
|
return;
|
|
}
|
|
// Validation Ends
|
|
|
|
dispatch(addRecipient(recipient));
|
|
setRecipients({ firstName: "", lastName: "", email: "", hostName: "", hostEmail: "", type: recipientType.SIGNER });
|
|
formRef.current?.reset();
|
|
}
|
|
|
|
// useEffect(() => {
|
|
// if (!recipient.firstName.length) return;
|
|
|
|
// const handler = setTimeout(() => {
|
|
// api.get(`/api/contact?firstName=${recipient.firstName}`)
|
|
// .then(res => {
|
|
// setContactData({ type: "firstName", contacts: res.data.content });
|
|
// })
|
|
// .catch(err => console.log(err));
|
|
// }, 500); // wait 500ms after the last change
|
|
|
|
// return () => {
|
|
// clearTimeout(handler); // cancel previous timeout if effect runs again
|
|
// };
|
|
|
|
// }, [recipient.firstName]);
|
|
|
|
// useDebouncedEffect(() => {
|
|
// if (!recipient.firstName.length) return;
|
|
// api.get(`/api/contact?firstName=${recipient.firstName}`)
|
|
// .then(res => {
|
|
// setContactData({ type: "firstName", contacts: res.data.content });
|
|
// })
|
|
// .catch(err => console.log(err));
|
|
// }, [recipient.firstName], 500);
|
|
|
|
// useDebouncedEffect(() => {
|
|
// if (!recipient.lastName.length) return
|
|
// api.get(`/api/contact?lastName=${recipient.lastName}`)
|
|
// .then(res => {
|
|
// setContactData({ type: "lastName", contacts: res.data.content });
|
|
// })
|
|
// .catch(err => console.log(err))
|
|
// }, [recipient.lastName], 500);
|
|
|
|
// useDebouncedEffect(() => {
|
|
// if (!recipient.email.length) return
|
|
// api.get(`/api/contact?email=${recipient.email}`)
|
|
// .then(res => {
|
|
// setContactData({ type: "email", contacts: res.data.content });
|
|
// })
|
|
// .catch(err => console.log(err))
|
|
// }, [recipient.email], 500);
|
|
|
|
const handleContactModalBlur = () => {
|
|
setTimeout(() => {
|
|
setOpenContactModal(false)
|
|
}, 350)
|
|
}
|
|
|
|
return (
|
|
<form
|
|
ref={formRef}
|
|
onSubmit={handleRecipientAdd}
|
|
className="w-full bg-white border border-gray-200 rounded-lg shadow-md px-6 py-6 space-y-5 relative"
|
|
>
|
|
{/* Name Inputs */}
|
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
<input
|
|
required
|
|
type="text"
|
|
onFocus={() => setOpenContactModal(true)}
|
|
onBlur={handleContactModalBlur}
|
|
value={recipient.firstName}
|
|
placeholder="First Name"
|
|
className="w-full px-4 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-[var(--primary)] transition"
|
|
onChange={(e) => setRecipients({ ...recipient, firstName: e.target.value })}
|
|
/>
|
|
<input
|
|
required
|
|
type="text"
|
|
onFocus={() => setOpenContactModal(true)}
|
|
onBlur={handleContactModalBlur}
|
|
value={recipient.lastName}
|
|
placeholder="Last Name"
|
|
className="w-full px-4 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-[var(--primary)] transition"
|
|
onChange={(e) => setRecipients({ ...recipient, lastName: e.target.value })}
|
|
/>
|
|
</div>
|
|
|
|
{recipient.type === recipientType.INPERSONSIGNER && <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
<input
|
|
required
|
|
type="text"
|
|
onFocus={() => setOpenContactModal(true)}
|
|
onBlur={handleContactModalBlur}
|
|
value={recipient.hostName}
|
|
placeholder="Host Name"
|
|
className="w-full px-4 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-[var(--primary)] transition"
|
|
onChange={(e) => setRecipients({ ...recipient, hostName: e.target.value })}
|
|
/>
|
|
<input
|
|
required
|
|
type="email"
|
|
onFocus={() => setOpenContactModal(true)}
|
|
onBlur={handleContactModalBlur}
|
|
value={recipient.hostEmail}
|
|
placeholder="Host Email"
|
|
className="w-full px-4 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-[var(--primary)] transition"
|
|
onChange={(e) => setRecipients({ ...recipient, hostEmail: e.target.value })}
|
|
/>
|
|
</div>}
|
|
|
|
{/* Email Input */}
|
|
<input
|
|
required
|
|
type="email"
|
|
onFocus={() => setOpenContactModal(true)}
|
|
onBlur={handleContactModalBlur}
|
|
value={recipient.email}
|
|
placeholder="Recipient Email"
|
|
className="w-full px-4 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-[var(--primary)] transition"
|
|
onChange={(e) => setRecipients({ ...recipient, email: e.target.value })}
|
|
/>
|
|
|
|
{/* Contact Modal */}
|
|
{contactData.contacts.length > 0 && openContactModal && (
|
|
<div className="absolute z-50 mt-1 w-full max-w-2xl bg-white shadow-lg rounded-md p-3 border border-gray-100">
|
|
<ContactModal
|
|
contactData={contactData}
|
|
inpFirstName={recipient.firstName}
|
|
inpLastName={recipient.lastName}
|
|
inpEmail={recipient.email}
|
|
openContactModal={openContactModal}
|
|
setRecipients={setRecipients}
|
|
setOpenContactModal={setOpenContactModal}
|
|
/>
|
|
</div>
|
|
)}
|
|
|
|
{/* Signing options + Add button in one line */}
|
|
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
|
|
<div className="flex flex-wrap gap-6">
|
|
{[
|
|
{ label: "Signer", value: recipientType.SIGNER },
|
|
{ label: "In Person Signer", value: recipientType.INPERSONSIGNER },
|
|
{ label: "CC", value: recipientType.CC },
|
|
].map((option) => (
|
|
<label key={option.value} className="flex items-center gap-2 text-gray-700 text-sm cursor-pointer">
|
|
<input
|
|
type="radio"
|
|
name="recipient-type"
|
|
value={option.value}
|
|
defaultChecked={option.value === recipientType.SIGNER}
|
|
onClick={(e) => setRecipients({ ...recipient, type: e.target.value })}
|
|
className="accent-[var(--primary)] cursor-pointer"
|
|
/>
|
|
{option.label}
|
|
</label>
|
|
))}
|
|
</div>
|
|
|
|
<button
|
|
type="submit"
|
|
className="inline-flex items-center gap-2 bg-[var(--primary)] hover:bg-[var(--primaryLight2)] text-white text-sm font-semibold px-5 py-2 rounded-md transition"
|
|
>
|
|
<FaPlus size={14} /> Add Recipient
|
|
</button>
|
|
</div>
|
|
</form>
|
|
|
|
);
|
|
};
|
|
|
|
export default RecipientAddCard; |