-
+ {/* 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})
setSigningOrderModal({ ...signingOrderModal, open: true })}
>
Signing Order
@@ -254,18 +234,20 @@ const RecipientCards = ({
)}
-
+
{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 && (
+
+
+
+ dispatch(
+ updateRecipient({
+ ...recipient,
+ allowSenderToEdit: !recipient.allowSenderToEdit,
+ uuid: getRecipientIdentifier(recipient),
+ })
+ )
+ }
+ className="accent-blue-500 w-3 h-3 sm:w-4 sm:h-4"
+ />
+ Allow Edit
+
+
+
+
+ dispatch(
+ updateRecipient({
+ ...recipient,
+ allowSenderToDelete: !recipient.allowSenderToDelete,
+ uuid: getRecipientIdentifier(recipient),
+ })
+ )
+ }
+ className="accent-red-500 w-3 h-3 sm:w-4 sm:h-4"
+ />
+ Allow Delete
+
+
)}
- {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) && (
-
-
-
- handleTypeChange(recipient, recipientType.SIGNER)
- }
- onBlur={() => setEditingField(null)}
- className="accent-[var(--primary)]"
- disabled={!isEditable(recipient)}
- />
- Signer
-
-
-
- handleTypeChange(recipient, recipientType.INPERSONSIGNER)
- }
- onBlur={() => setEditingField(null)}
- className="accent-[var(--primary)]"
- disabled={!isEditable(recipient)}
- />
- In Person Signer
-
-
-
- handleTypeChange(recipient, recipientType.CC)
- }
- onBlur={() => setEditingField(null)}
- className="accent-[var(--primary)]"
- disabled={!isEditable(recipient)}
- />
- CC
-
+
+
+
+ {/* 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 */}
+
+
+ handleTypeChange(recipient, recipientType.SIGNER)}
+ onBlur={() => setEditingField(null)}
+ className="accent-[var(--primary)] w-3 h-3"
+ disabled={!isEditable(recipient)}
+ />
+ Signer
+
+
+ handleTypeChange(recipient, recipientType.INPERSONSIGNER)}
+ onBlur={() => setEditingField(null)}
+ className="accent-[var(--primary)] w-3 h-3"
+ disabled={!isEditable(recipient)}
+ />
+ In Person Signer
+
+
+ handleTypeChange(recipient, recipientType.CC)}
+ onBlur={() => setEditingField(null)}
+ className="accent-[var(--primary)] w-3 h-3"
+ disabled={!isEditable(recipient)}
+ />
+ CC
+
+
+
+ {/* 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
-
+
+ {/* 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
+
+
+ Browse Files
+
+
+
+ )}
+ {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 {