diff --git a/src/components/auth/UsertAuthUI.tsx b/src/components/auth/UsertAuthUI.tsx index 44224dc..202d9bc 100644 --- a/src/components/auth/UsertAuthUI.tsx +++ b/src/components/auth/UsertAuthUI.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from "react"; -import "../styles/style.css"; +// import "../styles/style.css"; import { useNavigate, useLocation } from "react-router-dom"; import LoginForm from "./LoginForm"; import RegisterForm from "./RegisterForm"; @@ -37,7 +37,7 @@ function UserAuthUI() { return (
{/* Left Side - Branding */} -
+
{/* Logos */}
diff --git a/src/components/process/processStepOne/ProcessStepOne.tsx b/src/components/process/processStepOne/ProcessStepOne.tsx index 0b3dbe0..3a2bbbb 100644 --- a/src/components/process/processStepOne/ProcessStepOne.tsx +++ b/src/components/process/processStepOne/ProcessStepOne.tsx @@ -193,7 +193,7 @@ const ProcessStepOne = () => { // minRoutingOrder = recipient.routingOrder ?? 1; // } // }); - + const recipientsData = selectedRecipients.map((recipient, index) => ({ id: "id" in recipient ? recipient.id : null, routingOrder: "routingOrder" in recipient && recipient.routingOrder ? recipient.routingOrder : 1, @@ -267,7 +267,7 @@ const ProcessStepOne = () => { } } else { - if(!accountId || !transactionId) return; + if (!accountId || !transactionId) return; dispatch(addRecipientAsync({ recipientsData: recipientsDataTemp, accountId, transactionId })); } dispatch(showLoader("Processing Message...")); @@ -345,50 +345,60 @@ const ProcessStepOne = () => {
{/* Top Navigation - Fixed */} -
-
- -

- {transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES ? - <> - - {!isTyping && ( - - )} - : - "Add Recipient and Message" - } -

-
+
+
-
+ {/* Left Section */} +
- {transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES && } + - +

+ {transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES ? ( + <> + + {!isTyping && ( + + )} + + ) : ( + "Add Recipient and Message" + )} +

+
+ {/* Right Section */} +
+ + {transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES && ( + + )} + + +
+ {/* Main Content - Scrollable */}
diff --git a/src/components/process/processStepOne/RecipientAddCard.tsx b/src/components/process/processStepOne/RecipientAddCard.tsx index d4d6f26..3325f97 100644 --- a/src/components/process/processStepOne/RecipientAddCard.tsx +++ b/src/components/process/processStepOne/RecipientAddCard.tsx @@ -363,27 +363,26 @@ const RecipientAddCard = ({ transactionTemplateToggle, editRecipient, editCase, - return ( + return (
{transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES && ( -
- {/* Top Row: Role Input + Settings */} -
+
+ {/* Role Name and Permissions Section - Responsive Layout */} +
{/* Role Name Input */} - {/* Role Name Input */} -
+
{ setRecipients({ ...recipient, roleName: e.target.value }); setErrors(prev => ({ ...prev, roleName: false })); @@ -394,125 +393,76 @@ const RecipientAddCard = ({ transactionTemplateToggle, editRecipient, editCase, )}
- - {/* Settings + Permissions */} -
-
- {/* Permission Status Text - Always Visible */} -
-
- {/* {recipient.allowSenderToEdit && recipient.allowSenderToDelete && "Full permissions granted"} - {recipient.allowSenderToEdit && !recipient.allowSenderToDelete && "Edit permission granted"} - {!recipient.allowSenderToEdit && recipient.allowSenderToDelete && "Delete permission granted"} - {!recipient.allowSenderToEdit && !recipient.allowSenderToDelete && "No permissions granted"} */} - Permissions granted : -
+ {/* Permissions Section */} +
+
+ {/* Edit Permission */} +
+
- {/* Permission Controls - Always Visible */} -
-
- {/* Edit Permission */} -
- - {/* Tooltip */} -
-
- Edit Permission -
-
-
-
- - {/* Delete Permission */} -
- - {/* Tooltip */} -
-
- Delete Permission -
-
-
-
-
+ {/* Delete Permission */} +
+
-
)} - {/* Name Inputs */} -
-
+ {/* Name and Email Inputs - Responsive Grid */} +
+ {/* First Name */} +
handleFocus("firstName")} onBlur={handleContactModalBlur} value={recipient.firstName} placeholder="First Name" - className={`w-full px-4 py-2 border rounded-md text-sm focus:outline-none transition - ${errors.firstName ? 'border-red-500 ring-2 ring-red-300' : 'border-gray-300 focus:ring-2 focus:ring-[var(--primary)]'}`} + className={`w-full px-3 sm:px-4 py-2 border rounded-md text-sm focus:outline-none transition + ${errors.firstName ? 'border-red-500 ring-2 ring-red-300' : 'border-gray-300 focus:ring-2 focus:ring-[var(--primary)]'}`} onChange={(e) => { setRecipients({ ...recipient, firstName: e.target.value }); - // setErrors((prev) => ({ ...prev, firstName: false })); }} />
- {/* {errors.firstName && ( -

First Name is required

- )} */} -
+ + {/* Last Name */} +
handleFocus("lastName")} onBlur={handleContactModalBlur} value={recipient.lastName} placeholder="Last Name" - className={` w-full px-4 py-2 border rounded-md text-sm focus:outline-none transition - ${errors.lastName ? 'border-red-500 ring-2 ring-red-300' : 'border-gray-300 focus:ring-2 focus:ring-[var(--primary)]'}`} + className={`w-full px-3 sm:px-4 py-2 border rounded-md text-sm focus:outline-none transition + ${errors.lastName ? 'border-red-500 ring-2 ring-red-300' : 'border-gray-300 focus:ring-2 focus:ring-[var(--primary)]'}`} onChange={(e) => { setRecipients({ ...recipient, lastName: e.target.value }); setErrors((prev) => ({ ...prev, lastName: false })); @@ -522,15 +472,17 @@ const RecipientAddCard = ({ transactionTemplateToggle, editRecipient, editCase,

Last Name is required

)}
-
+ + {/* Email - Full width on small screens, shares row on larger */} +
handleFocus("email")} onBlur={handleContactModalBlur} value={recipient.email} placeholder="Recipient Email" - className={`w-full px-4 py-2 border rounded-md text-sm focus:outline-none transition - ${errors.email ? 'border-red-500 ring-2 ring-red-300' : 'border-gray-300 focus:ring-2 focus:ring-[var(--primary)]'}`} + className={`w-full px-3 sm:px-4 py-2 border rounded-md text-sm focus:outline-none transition + ${errors.email ? 'border-red-500 ring-2 ring-red-300' : 'border-gray-300 focus:ring-2 focus:ring-[var(--primary)]'}`} onChange={(e) => { setRecipients({ ...recipient, email: e.target.value }); setErrors((prev) => ({ ...prev, email: false })); @@ -542,33 +494,35 @@ const RecipientAddCard = ({ transactionTemplateToggle, editRecipient, editCase,
+ {/* Host Fields for In-Person Signers */} + {recipient.type === recipientType.INPERSONSIGNER && ( +
+ setOpenContactModal(true)} + onBlur={handleContactModalBlur} + value={recipient.hostName} + placeholder="Host Name" + className="w-full px-3 sm: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 })} + /> + setOpenContactModal(true)} + onBlur={handleContactModalBlur} + value={recipient.hostEmail} + placeholder="Host Email" + className="w-full px-3 sm: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 })} + /> +
+ )} - {recipient.type === recipientType.INPERSONSIGNER &&
- 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 })} - /> - 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 })} - /> -
} - - {/* Contact Modal */} + {/* Contact Modal - Responsive Positioning */} {openContactModal && contactData.contacts.length > 0 && ( -
+
)} - - - {/* Signing options + Add button in one line */} -
-
+ {/* Signing Options and Add Button - Responsive Layout */} +
+ {/* Recipient Type Radio Options */} +
{[ { label: "Signer", value: recipientType.SIGNER }, { label: "In Person Signer", value: recipientType.INPERSONSIGNER }, { label: "CC", value: recipientType.CC }, ].map((option) => ( -
- {!showCard && } + {/* Add/Edit Button */} + {!showCard && ( + + )}
diff --git a/src/components/process/processStepOne/RecipientCards.tsx b/src/components/process/processStepOne/RecipientCards.tsx index 6ad5e37..aa0626b 100644 --- a/src/components/process/processStepOne/RecipientCards.tsx +++ b/src/components/process/processStepOne/RecipientCards.tsx @@ -121,7 +121,7 @@ const RecipientCards = ({ return currentValue && currentValue.toString().trim() !== ""; }; - const renderEditableField = ( + const renderEditableField = ( recipient: any, fieldName: string, placeholder: string, @@ -130,48 +130,28 @@ const RecipientCards = ({ ) => { const identifier = getRecipientIdentifier(recipient); const currentValue = getCurrentValue(recipient, fieldName); - const isEditing = editingField?.recipientId === identifier && editingField?.fieldName === fieldName; - const showValue = hasValue(recipient, fieldName); const error = errors[identifier]?.[fieldName]; const editable = isEditable(recipient); - if (isEditing && editable) { - 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(); - } - }} - className={`w-full px-3 py-1 border ${error ? "border-red-500 placeholder-red-500 text-xs" : "border-gray-300" - } rounded-lg text-sm focus:outline-none focus:ring-0 focus:ring-gray-300 ${className}`} - /> - {/* {error && ( - {`${placeholder} is required`} - )} */} -
- ); - } - return ( - handleFieldFocus(identifier, fieldName) : undefined} - className={`${editable - ? "cursor-pointer hover:bg-gray-100 rounded px-1 transition-colors" - : "cursor-not-allowed" - } ${showValue ? "text-gray-800" : "text-gray-400 italic"} ${className}`} - title={editable ? "Click to edit" : "Editing disabled"} - > - {showValue ? currentValue : placeholder} - +
+ 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"} + /> +
); }; @@ -235,17 +215,17 @@ const RecipientCards = ({ setEditingField(null); }; - return ( + return (
{recipients.length > 0 ? ( <> {recipients.length > 1 && ( -
+

Recipients ({recipients.length})

)} -
+
{recipients.map((recipient, idx) => (
-
+ {/* Main Content Section */} +
+ {/* Order Number */} {recipients.length > 1 ? ( -
+
) : ( @@ -291,140 +273,159 @@ const RecipientCards = ({ Number(e.target.value) ) } - className="w-8 text-center rounded text-sm text-gray-700 border-none focus:outline-none focus:ring-[var(--primary)]" + 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 || ""}`)}
-
-

- {renderEditableField(recipient, "firstName", "First Name")} - {renderEditableField(recipient, "lastName", "Last Name")} - {transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES && ( - - | Permissions granted : - - dispatch( - updateRecipient({ - ...recipient, - allowSenderToEdit: !recipient.allowSenderToEdit, - uuid: getRecipientIdentifier(recipient), - }) - ) - } - /> - - dispatch( - updateRecipient({ - ...recipient, - allowSenderToDelete: !recipient.allowSenderToDelete, - uuid: getRecipientIdentifier(recipient), - }) - ) - } - /> - - )} -

-

- {renderEditableField(recipient, "email", "Recipient Email", "", "email")} | - handleFieldFocus(getRecipientIdentifier(recipient), "type") - : undefined - } - className={`${isEditable(recipient) - ? "cursor-pointer hover:bg-gray-100" - : "cursor-not-allowed" - } rounded px-1 transition-colors`} - > - {recipient.type} - - {(hasValue(recipient, "roleName") || - transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES) && ( - - {" | Role: "} - {renderEditableField(recipient, "roleName", "Role name")} - + + {/* 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 && ( +
+ + + +
)} - {recipient.type === recipientType.INPERSONSIGNER && ( - <> - - {" | Host Name: "} - {renderEditableField(recipient, "hostName", "Host Name")} - {" | Host Email: "} - {renderEditableField(recipient, "hostEmail", "Host Email", "", "email")} - - - )} -

- {editingField?.recipientId === getRecipientIdentifier(recipient) && - editingField?.fieldName === "type" && - isEditable(recipient) && ( -
- - - +
+
+ + {/* 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" && ( -
+
)} @@ -446,24 +447,27 @@ const RecipientCards = ({
) : ( -
+
No Recipients Added
)} + {/* Responsive Modal */} {signingOrderModal.open && ( -
-
-
-

Signing Order

+
+
+
+

Signing Order

setSigningOrderModal({ ...signingOrderModal, open: false })} - className="text-xl cursor-pointer hover:text-gray-200 transition-all" + className="text-xl sm:text-2xl cursor-pointer hover:text-gray-200 transition-all p-1" >
- +
+ +
)} diff --git a/src/components/process/processStepOne/SelectedDocuments.tsx b/src/components/process/processStepOne/SelectedDocuments.tsx index b479bb1..6dbf3b3 100644 --- a/src/components/process/processStepOne/SelectedDocuments.tsx +++ b/src/components/process/processStepOne/SelectedDocuments.tsx @@ -90,15 +90,26 @@ const SelectedDocuments = ({ transactionTemplateToggle }) => { // Get proper Tailwind class names for upload card span const getUploadCardSpanClass = () => { - switch (docCount) { - case 0: return 'col-span-5'; // Full width when no docs - case 1: return 'col-span-4'; // 4 cols for upload, 1 for doc - case 2: return 'col-span-3'; // 3 cols for upload, 2 for docs - case 3: return 'col-span-2'; // 2 cols for upload, 3 for docs - case 4: return 'col-span-1'; // 1 col for upload, 4 for docs - default: return 'col-span-1'; // 1 col for upload, rest for docs - } - }; + if (docCount === 0) { + // Upload card takes all columns only when no docs + return "col-span-1 sm:col-span-2 md:col-span-3 lg:col-span-4 xl:col-span-5"; + } + + switch (docCount) { + case 1: + return "col-span-1 sm:col-span-1 md:col-span-2 lg:col-span-3 xl:col-span-4"; + case 2: + return "col-span-1 sm:col-span-1 md:col-span-1 lg:col-span-2 xl:col-span-3"; + case 3: + return "col-span-1 sm:col-span-1 md:col-span-1 lg:col-span-1 xl:col-span-2"; + case 4: + return "col-span-1"; // balanced + default: + return "col-span-1"; + } +}; + + // Calculate how many documents should be in the first row const getFirstRowDocCount = () => { @@ -113,150 +124,153 @@ const SelectedDocuments = ({ transactionTemplateToggle }) => { return ( <> {/* Upload Card First */} -
-
- {/* Upload Document Card - Always First */} +
setModalOpen(true)} - className={`${getUploadCardSpanClass()} cursor-pointer h-[170px] flex flex-col items-center justify-center border-2 border-dashed border-gray-300 rounded-xl bg-white hover:bg-gray-50 transition shadow-sm hover:shadow-md`} + id="upload-doc-step-one" + className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-5 gap-2" > - -

Upload Document

+ {/* Upload Document Card */} +
setModalOpen(true)} + className={`${getUploadCardSpanClass()} cursor-pointer h-[170px] flex flex-col items-center justify-center border-2 border-dashed border-gray-300 rounded-xl bg-white hover:bg-gray-50 transition shadow-sm hover:shadow-md`} + > + +

Upload Document

+
+ + {/* First Row Documents */} + ({ ...doc }))} + setList={(newState) => { + const updatedDocs = [...newState, ...documents.slice(firstRowDocCount)]; + dispatch(setDocuments(updatedDocs)); + }} + handle=".drag-handle" + animation={200} + ghostClass="sortable-ghost" + disabled={false} + > + {documents.slice(0, firstRowDocCount).map((doc) => ( +
+ +
+ ))} +
- {/* First Row Documents */} - ({ ...doc }))} - setList={(newState) => { - const updatedDocs = [ - ...newState, - ...documents.slice(firstRowDocCount) - ]; - dispatch(setDocuments(updatedDocs)); - }} - handle=".drag-handle" - animation={200} - ghostClass="sortable-ghost" - disabled={false} - > - {documents.slice(0, firstRowDocCount).map((doc) => ( -
- -
- ))} -
-
+ {/* Additional Rows */} + {remainingDocs > 0 && ( + ({ ...doc }))} + setList={(newState) => { + const updatedDocs = [ + ...documents.slice(0, firstRowDocCount), + ...newState, + ]; + dispatch(setDocuments(updatedDocs)); + }} + handle=".drag-handle" + animation={200} + ghostClass="sortable-ghost" + disabled={false} + > + {documents.slice(firstRowDocCount).map((doc) => ( +
+ +
+ ))} +
+ )} - {/* Additional Rows - Remaining Documents (5th, 6th, 7th, etc.) */} - {remainingDocs > 0 && ( - ({ ...doc }))} - setList={(newState) => { - const updatedDocs = [ - ...documents.slice(0, firstRowDocCount), - ...newState - ]; - dispatch(setDocuments(updatedDocs)); - }} - handle=".drag-handle" - animation={200} - ghostClass="sortable-ghost" - disabled={false} - > - {documents.slice(firstRowDocCount).map((doc) => ( -
- -
- ))} -
- )} + {/* Modal */} + {isModalOpen && ( +
+
+ {/* Close Button */} + - - {/* Modal */} - {isModalOpen && ( -
-
- {/* Close Button */} - - - {/* Sidebar Tabs */} -
- {tabs.map(tab => ( - - ))} -
- - {/* Modal Content */} -
- {activeTab === 'Upload' && ( -
fileInputRef.current?.click()} - onDragOver={(e) => e.preventDefault()} - onDrop={handleDrop} - className="flex flex-col items-center justify-center h-full border-2 border-dashed border-gray-300 rounded-xl p-6 text-center cursor-pointer hover:bg-gray-50" - > - -

Drag & drop files here or

- - -
- )} - {activeTab !== 'Upload' && ( -
-

{activeTab} integration coming soon...

-
- )} + ))} +
+ + {/* Modal Content */} +
+ {activeTab === "Upload" && ( +
fileInputRef.current?.click()} + onDragOver={(e) => e.preventDefault()} + onDrop={handleDrop} + className="flex flex-col items-center justify-center h-full border-2 border-dashed border-gray-300 rounded-xl p-6 text-center cursor-pointer hover:bg-gray-50" + > + +

+ Drag & drop files here or +

+ + +
+ )} + {activeTab !== "Upload" && ( +
+

{activeTab} integration coming soon...

+
+ )} +
-
- )} - + )}
+ ); }; diff --git a/src/index.css b/src/index.css index 1aab2b4..257b4ee 100644 --- a/src/index.css +++ b/src/index.css @@ -140,6 +140,34 @@ canvas { } } +/* Custom scrollbar size via CSS */ +@layer utilities { + .custom-scrollbar { + scrollbar-width: thin; /* For Firefox */ + scrollbar-color: rgba(120, 120, 120, 0.4) transparent; + } + + .custom-scrollbar::-webkit-scrollbar { + width: 1px; + height: 1px; + } + + .custom-scrollbar::-webkit-scrollbar-thumb { + background-color: rgba(120, 120, 120, 0.4); + border-radius: 9999px; /* fully rounded */ + } + + .custom-scrollbar::-webkit-scrollbar-thumb:hover { + background-color: rgba(120, 120, 120, 0.6); /* slightly darker on hover */ + } + + .custom-scrollbar::-webkit-scrollbar-track { + background-color: transparent; + } +} + + + /* Chrome, Safari, Edge, Opera */ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button {