Compare commits

..

3 Commits

9 changed files with 665 additions and 313 deletions

View File

@ -48,7 +48,7 @@ const RecipientAddCard = ({ transactionTemplateToggle }) => {
// Validation Ends // Validation Ends
dispatch(addRecipient(recipient)); dispatch(addRecipient(recipient));
setRecipients({ firstName: "", lastName: "", email: "", hostName: "", hostEmail: "", roleName: "", type: recipientType.SIGNER, allowSenderToEdit: Boolean, allowSenderToRemove: Boolean }); setRecipients({ firstName: "", lastName: "", email: "", hostName: "", hostEmail: "", roleName: "", type: recipientType.SIGNER, allowSenderToEdit: false, allowSenderToRemove: false });
formRef.current?.reset(); formRef.current?.reset();
} }

View File

@ -65,6 +65,11 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
// const selectedDocuments = useSelector((state: RootState) => state.selectedDocuments.selectedDocuments) // const selectedDocuments = useSelector((state: RootState) => state.selectedDocuments.selectedDocuments)
const selectedDocuments = useSelector((state: RootState) => state.documents.documents) const selectedDocuments = useSelector((state: RootState) => state.documents.documents)
console.log("selectedDocuments",selectedDocuments)
const [droppedItems, setDroppedItems] = useState<DroppedItemsObj>({});
console.log("droppedItems", droppedItems)
// const [uniqGroupIds, setUniqGroupIds] = useState<string[]>([]); // const [uniqGroupIds, setUniqGroupIds] = useState<string[]>([]);
@ -106,7 +111,7 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
// FETCHING TAG - END // FETCHING TAG - END
const [droppedItems, setDroppedItems] = useState<DroppedItemsObj>({});
const [droppedItemsCounter, setDroppedItemsCounter] = useState<number>(1); const [droppedItemsCounter, setDroppedItemsCounter] = useState<number>(1);
const [selectedTag, setSelectedTag] = useState<{ key: string, index: number } | null>(null); const [selectedTag, setSelectedTag] = useState<{ key: string, index: number } | null>(null);
@ -312,6 +317,7 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
const dragElemData = JSON.parse(data); // Get the dropped label const dragElemData = JSON.parse(data); // Get the dropped label
const field = { ...dragElemData } const field = { ...dragElemData }
if (!field.label) return; if (!field.label) return;
@ -329,8 +335,8 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
properties: data.properties, properties: data.properties,
icon: typeToIconMap[field.label.toUpperCase()] || <FaQuestionCircle />, icon: typeToIconMap[field.label.toUpperCase()] || <FaQuestionCircle />,
type: dragElemData.label, type: dragElemData.label,
subType: (dragElemData.label in droppedTagsDefaultField) ? droppedTagsDefaultField[dragElemData.label] : '',
label: dragElemData.label, label: dragElemData.label,
subType: (dragElemData.label in droppedTagsDefaultField) ? droppedTagsDefaultField[dragElemData.label] : '',
dimensions: { dimensions: {
left: x, left: x,
top: y, top: y,
@ -369,6 +375,8 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
prepData.currentTimeStamp = true; prepData.currentTimeStamp = true;
} }
if (prepData.type.toLowerCase() === "number") { if (prepData.type.toLowerCase() === "number") {
prepData.decimalPlace = 0; prepData.decimalPlace = 0;
prepData.isCurrency = false; prepData.isCurrency = false;
@ -412,6 +420,7 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
// setDroppedItems(dataToSet); // setDroppedItems(dataToSet);
// } // }
console.log("data311", dataToSet)
setDroppedItems(dataToSet); setDroppedItems(dataToSet);
setDroppedItemsCounter((prev) => prev + 1); setDroppedItemsCounter((prev) => prev + 1);
@ -423,13 +432,11 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
// HANDLE DROP - END // HANDLE DROP - END
// HANDLE TAG MOUSE DOWN - START // HANDLE TAG MOUSE DOWN - START
// Updated handleTagMouseDown function with proper group border positioning
const handleTagMouseDown = (event: React.MouseEvent<HTMLDivElement>, key: string, index: number) => { const handleTagMouseDown = (event: React.MouseEvent<HTMLDivElement>, key: string, index: number) => {
event.preventDefault(); event.preventDefault();
let targetContainer = event?.currentTarget?.parentElement?.parentElement; let targetContainer = event?.currentTarget?.parentElement?.parentElement;
console.log(targetContainer, "targetContainer line 421")
let targetElement = event?.currentTarget?.parentElement; let targetElement = event?.currentTarget?.parentElement;
if (!targetContainer || !targetElement) return; if (!targetContainer || !targetElement) return;
@ -450,9 +457,11 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
groupId = event.currentTarget.getAttribute("group"); groupId = event.currentTarget.getAttribute("group");
} }
let groupElements: NodeListOf<HTMLElement> | null = null let groupElements: NodeListOf<HTMLElement> | null = null;
if (isGroupAttr && groupId) { if (isGroupAttr && groupId) {
groupElements = document.querySelectorAll(`div[group="${groupId}"]`); groupElements = document.querySelectorAll(`div[group="${groupId}"]`);
// Show initial border position during drag start
handleGroupBorderPosition(groupElements, containerRect, offsetX, offsetY);
} }
const handleMouseMove = (event: MouseEvent) => { const handleMouseMove = (event: MouseEvent) => {
@ -460,26 +469,52 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
let left = event.clientX - containerRect.left - offsetX; let left = event.clientX - containerRect.left - offsetX;
let top = event.clientY - containerRect.top - offsetY; let top = event.clientY - containerRect.top - offsetY;
// Restrict movement within container bounds
// **Restrict movement within container bounds**
left = Math.max(0, Math.min(left, conScrollWidth - elementRect.width)); left = Math.max(0, Math.min(left, conScrollWidth - elementRect.width));
top = Math.max(0, Math.min(top, conScrollHeight - elementRect.height)); top = Math.max(0, Math.min(top, conScrollHeight - elementRect.height));
if (groupElements != null && groupElements.length) handleGroupBorderPosition(groupElements, containerRect, offsetX, offsetY); // Apply the movement to the element first
setDroppedItems(prevState => ({
// Apply the movement to the element ...prevState,
setDroppedItems({ [key]: Array.isArray(prevState[key])
...droppedItems, ? prevState[key].map((item, i) =>
[key]: Array.isArray(droppedItems[key]) // Ensure it's an array
? droppedItems[key].map((item, i) =>
i === index ? { ...item, dimensions: { ...item.dimensions, left, top }, update: true } : item i === index ? { ...item, dimensions: { ...item.dimensions, left, top }, update: true } : item
) )
: [], // Provide a fallback in case it's undefined or not an array : [],
}); }));
// Update group border position during drag if it's a group element
if (groupElements != null && groupElements.length) {
// Use a small timeout to ensure DOM is updated before recalculating borders
requestAnimationFrame(() => {
handleGroupBorderPosition(groupElements!, containerRect, offsetX, offsetY);
});
}
}; };
const handleMouseUp = () => { const handleMouseUp = () => {
// CRITICAL: Ensure group borders are properly positioned after drag ends
if (groupElements != null && groupElements.length && groupId) {
// Multiple approaches to ensure the positioning works:
// 1. Immediate update
setTimeout(() => {
handleIGroupBorderPosition(groupId);
}, 10);
// 2. Secondary update to ensure it's properly positioned
setTimeout(() => {
handleIGroupBorderPosition(groupId);
}, 100);
// 3. Final update using requestAnimationFrame for DOM sync
requestAnimationFrame(() => {
setTimeout(() => {
handleIGroupBorderPosition(groupId);
}, 50);
});
}
document.removeEventListener("pointermove", handleMouseMove); document.removeEventListener("pointermove", handleMouseMove);
document.removeEventListener("pointerup", handleMouseUp); document.removeEventListener("pointerup", handleMouseUp);
}; };
@ -550,13 +585,14 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
setSelectedTag({ key, index }) setSelectedTag({ key, index })
} }
// Updated handleRemoveTag function with your existing API logic and group handling
const handleRemoveTag = (key: string, targetIndex: number) => { const handleRemoveTag = (key: string, targetIndex: number) => {
const tag = droppedItems[key][targetIndex]; const tag = droppedItems[key][targetIndex];
const recipientId = tag.recipientId; const recipientId = tag.recipientId;
(async () => { (async () => {
if ("id" in tag) { if ("id" in tag) {
try { try {
const response = await api.delete(`/api/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}/recipients/${recipientId}/tags/${tag.id}`) const response = await api.delete(`/api/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}/recipients/${recipientId}/tags/${tag.id}`)
if (response.status !== 200) throw "Tag Deletion error" if (response.status !== 200) throw "Tag Deletion error"
} catch (err) { } catch (err) {
@ -564,41 +600,302 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
return; return;
} }
} }
setSelectedTag(null)
setSelectedTag(null);
// Check if this item has a group for special group handling
if ('group' in tag && tag.group) {
const groupId = tag.group;
// Find all items in the same group
const groupItems = droppedItems[key]
.map((item, idx) => ({ item, index: idx }))
.filter(({ item }) => 'group' in item && item.group === groupId && !item.isDeleted);
// Sort group items by their top position to identify the parent (top-most)
groupItems.sort((a, b) => a.item.dimensions.top - b.item.dimensions.top);
// Check if the item being removed is the parent (top-most item)
const isParentItem = groupItems.length > 0 && groupItems[0].index === targetIndex;
if (isParentItem && groupItems.length > 1) {
// If removing the parent and there are child items, mark all items in the group as deleted
console.log(`Removing parent item and all children for group: ${groupId}`);
// Get indices of all group items to mark as deleted
const indicesToDelete = groupItems.map(({ index }) => index);
setDroppedItems(prevState => ({
...prevState,
[key]: prevState[key].map((item, index) =>
indicesToDelete.includes(index) ? { ...item, isDeleted: true } : item
)
}));
// Remove group border elements after state update
setTimeout(() => {
removeGroupBorders(groupId);
}, 100);
} else {
// If removing a child item or the only item in group, just mark this item as deleted
console.log(`Removing individual item from group: ${groupId}`);
setDroppedItems(prevState => ({ setDroppedItems(prevState => ({
...prevState, ...prevState,
[key]: prevState[key].map((item, index) => [key]: prevState[key].map((item, index) =>
index === targetIndex ? { ...item, isDeleted: true } : item index === targetIndex ? { ...item, isDeleted: true } : item
) )
})); }));
})()
// Check if this was the last item in the group after state update
setTimeout(() => {
const remainingGroupItems = droppedItems[key].filter(item =>
'group' in item && item.group === groupId && !item.isDeleted
);
if (remainingGroupItems.length === 0) {
// Remove group borders if no items left
removeGroupBorders(groupId);
} else {
// Update group borders for remaining items
handleIGroupBorderPosition(groupId);
} }
}, 100);
}
} else {
// Handle non-group item removal (your existing logic)
setDroppedItems(prevState => ({
...prevState,
[key]: prevState[key].map((item, index) =>
index === targetIndex ? { ...item, isDeleted: true } : item
)
}));
}
})()
};
// Helper function to remove group border elements from DOM
const removeGroupBorders = (groupId: string) => {
console.log(`Removing borders for group: ${groupId}`);
const borderPositions = ['top', 'right', 'bottom', 'left'];
borderPositions.forEach(position => {
const borderElement = document.querySelector(`[border-group='${groupId}'][border-pos='${position}']`);
if (borderElement && borderElement.parentNode) {
borderElement.parentNode.removeChild(borderElement);
}
});
};
// const handleAddRadioClick = (key:string) => { // const handleAddRadioClick = (key:string) => {
// console.log("Handle Radio Clicled", key) // console.log("Handle Radio Clicled", key)
// console.log(droppedItems, "line 525") // console.log(droppedItems, "line 525")
// } // }
const handleIGroupBorderPosition = (groupId: string) => {
console.log("handleIGroupBorderPosition for group:", groupId);
const handleAddGroupItemClicked = (key: string, item) => { const groupElements: NodeListOf<HTMLElement> = document.querySelectorAll(`div[group="${groupId}"]`);
if (groupElements.length === 0) {
console.log("No group elements found for:", groupId);
return;
}
let targetContainer = groupElements[0].parentElement?.parentElement;
if (!targetContainer) {
console.log("No target container found");
return;
}
const containerRect = targetContainer.getBoundingClientRect();
// Use consistent offset values
const offsetX = 10;
const offsetY = 10;
// Ensure DOM is fully updated before positioning
requestAnimationFrame(() => {
requestAnimationFrame(() => {
handleGroupBorderPosition(groupElements, containerRect, offsetX, offsetY);
});
});
};
// Enhanced handleGroupBorderPosition with better positioning logic
const handleGroupBorderPosition = (groupElements: NodeListOf<HTMLElement>, containerRect: DOMRect, offsetX: number, offsetY: number) => {
if (!groupElements || groupElements.length === 0) return;
const groupId = groupElements[0].getAttribute('group');
if (!groupId) return;
// Calculate the bounding box of all group elements
let minLeft = Infinity, minTop = Infinity, maxRight = -Infinity, maxBottom = -Infinity;
groupElements.forEach(element => {
const parentElement = element.parentElement;
if (!parentElement) return;
const rect = parentElement.getBoundingClientRect();
const relativeLeft = rect.left - containerRect.left;
const relativeTop = rect.top - containerRect.top;
const relativeRight = relativeLeft + rect.width;
const relativeBottom = relativeTop + rect.height;
minLeft = Math.min(minLeft, relativeLeft);
minTop = Math.min(minTop, relativeTop);
maxRight = Math.max(maxRight, relativeRight);
maxBottom = Math.max(maxBottom, relativeBottom);
});
// Add some padding around the group
const padding = 10;
minLeft -= padding;
minTop -= padding;
maxRight += padding;
maxBottom += padding;
const width = maxRight - minLeft;
const height = maxBottom - minTop;
// Update or create border elements
const borderPositions = ['top', 'right', 'bottom', 'left'];
borderPositions.forEach(position => {
let borderElement = document.querySelector(`[border-group='${groupId}'][border-pos='${position}']`) as HTMLElement;
if (!borderElement) {
// Create border element if it doesn't exist
borderElement = document.createElement('div');
borderElement.className = `group-border ${position === 'bottom' ? 'bottom-border' : ''}`;
borderElement.setAttribute('border-group', groupId);
borderElement.setAttribute('border-pos', position);
// Add the + icon for bottom border
if (position === 'bottom') {
const addIcon = document.createElement('div');
addIcon.innerHTML = '<IoAdd />'; // You might need to adjust this based on your icon system
addIcon.onclick = () => {
// Find the original item to pass to handleAddGroupItemClicked
const originalItem = droppedItems[key]?.find(item => 'group' in item && item.group === groupId);
if (originalItem) {
handleAddGroupItemClicked(key, originalItem);
}
};
borderElement.appendChild(addIcon);
}
// Append to container
groupElements[0].parentElement?.parentElement?.appendChild(borderElement);
}
// Position the border element
borderElement.style.position = 'absolute';
borderElement.style.pointerEvents = position === 'bottom' ? 'auto' : 'none';
switch (position) {
case 'top':
borderElement.style.left = `${minLeft}px`;
borderElement.style.top = `${minTop}px`;
borderElement.style.width = `${width}px`;
borderElement.style.height = '2px';
break;
case 'right':
borderElement.style.left = `${maxRight - 2}px`;
borderElement.style.top = `${minTop}px`;
borderElement.style.width = '2px';
borderElement.style.height = `${height}px`;
break;
case 'bottom':
borderElement.style.left = `${minLeft}px`;
borderElement.style.top = `${maxBottom - 2}px`;
borderElement.style.width = `${width}px`;
borderElement.style.height = '2px';
break;
case 'left':
borderElement.style.left = `${minLeft}px`;
borderElement.style.top = `${minTop}px`;
borderElement.style.width = '2px';
borderElement.style.height = `${height}px`;
break;
}
});
};
const handleAddGroupItemClicked = (key: string, item: any) => {
console.log("handleAddGroupItemClicked", item);
const groupId = item.group; const groupId = item.group;
item = { ...item, dimensions: { ...item.dimensions, top: item.dimensions.top + item.dimensions.height + 20 } } // Find all existing items in this group to determine the bottom-most position
const existingGroupItems = droppedItems[key]?.filter(existingItem =>
'group' in existingItem && existingItem.group === groupId
) || [];
// dimensions: { ...item.dimensions, left: newLeft, top: newTop } // Find the bottom-most item in the group
let bottomMostItem = item;
setTimeout(() => { if (existingGroupItems.length > 0) {
handleIGroupBorderPosition(item.group) bottomMostItem = existingGroupItems.reduce((lowest, current) => {
}, 0) const currentBottom = current.dimensions.top + current.dimensions.height;
const lowestBottom = lowest.dimensions.top + lowest.dimensions.height;
setDroppedItems({ return currentBottom > lowestBottom ? current : lowest;
...droppedItems,
[key]: [...droppedItems[key], { ...item, isGroupExist: true }],
}); });
} }
// Calculate new position: place below the bottom-most item
const spacing = 10; // Adjust spacing as needed
const newTop = bottomMostItem.dimensions.top + bottomMostItem.dimensions.height + spacing;
// Use the same left position as the parent (original) item
const newItem = {
...item,
dimensions: {
...item.dimensions,
left: item.dimensions.left, // Keep same horizontal position as parent
top: newTop // Position below the bottom-most item
},
isGroupExist: true
};
// Update the dropped items
setDroppedItems({
...droppedItems,
[key]: [...droppedItems[key], newItem],
});
// Update group borders after adding the new item
// Use setTimeout to ensure state update is processed
setTimeout(() => {
handleIGroupBorderPosition(groupId);
}, 50); // Slightly longer timeout to ensure DOM updates
};
useEffect(() => {
// Initialize group borders for all existing groups after component updates
const timeoutId = setTimeout(() => {
const allGroupElements = document.querySelectorAll('[group]');
const groupIds = new Set<string>();
allGroupElements.forEach((element) => {
const groupId = element.getAttribute('group');
if (groupId) {
groupIds.add(groupId);
}
});
groupIds.forEach((groupId) => {
handleIGroupBorderPosition(groupId);
});
}, 100);
return () => clearTimeout(timeoutId);
}, [droppedItems]); // Re-run when droppedItems changes
// const handleAddRadio = (e: React.MouseEvent<HTMLElement>, key: string, index: number) => { // const handleAddRadio = (e: React.MouseEvent<HTMLElement>, key: string, index: number) => {
// // const dataToSet: DroppedItemsObj = { // // const dataToSet: DroppedItemsObj = {
@ -745,24 +1042,6 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
handleDirectionalMove(direction, 5); // Use default stepSize of 5 handleDirectionalMove(direction, 5); // Use default stepSize of 5
}; };
function handleIGroupBorderPosition(groupId: string) {
const groupElements: NodeListOf<HTMLElement> = document.querySelectorAll(`div[group="${groupId}"]`);
let targetContainer = groupElements[0].parentElement?.parentElement;
console.log(targetContainer, "targetContainer line 421")
let targetElement = groupElements[0].parentElement;
if (!targetContainer || !targetElement) return;
const containerRect = targetContainer.getBoundingClientRect();
handleGroupBorderPosition(groupElements, containerRect, 40, 40);
}
return ( return (
<> <>
{/* Center Doc Container - START */} {/* Center Doc Container - START */}
@ -815,7 +1094,7 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
{/* If Selected Tag Recipient Info- START */} {/* If Selected Tag Recipient Info- START */}
{selectedTag?.key && selectedTag.key === key && selectedTag.index === index && {selectedTag?.key && selectedTag.key === key && selectedTag.index === index &&
<div className='absolute flex justify-between items-center w-full max-w-max bg-white top-[-22px] shadow z-20 text-sm rounded-t-sm'> <div className='absolute flex justify-between items-center w-full max-w-max bg-white top-[-22px] shadow z-20 text-sm rounded-t-sm' >
<div className='flex justify-center items-center gap-1 bg-white px-2 shadow'> <div className='flex justify-center items-center gap-1 bg-white px-2 shadow'>
<p className='w-2.5 h-2.5 rounded' <p className='w-2.5 h-2.5 rounded'
style={{ background: selectedRecipient[0]?.color }} style={{ background: selectedRecipient[0]?.color }}
@ -929,6 +1208,6 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
{/* Center Doc Container - END */} {/* Center Doc Container - END */}
</> </>
) )
} }
export default DocumentContainer; export default DocumentContainer;

View File

@ -12,6 +12,8 @@ interface CommonAttrDropDownInt {
const CommonAttrDropDown: React.FC<CommonAttrDropDownInt> = ({selectedType, subType, dropDownToggle, setDropDownToggle, handlePropertyChange}) => { const CommonAttrDropDown: React.FC<CommonAttrDropDownInt> = ({selectedType, subType, dropDownToggle, setDropDownToggle, handlePropertyChange}) => {
console.log("selectedType, subType,",selectedType, subType)
return ( return (
<div className="flex flex-col"> <div className="flex flex-col">
<label htmlFor="" className="">Type</label> <label htmlFor="" className="">Type</label>

View File

@ -107,7 +107,7 @@ const RightSideBar: React.FC<DroppedItemProps> = ({ selectedTag, setDroppedItems
const selectedType = selectedTag.type in enumMap && enumMap[selectedTag.type as keyof typeof enumMap]; const selectedType = selectedTag.type in enumMap && enumMap[selectedTag.type as keyof typeof enumMap];
// console.log("selectedTag", selectedTag, selectedType) console.log("selectedTag", selectedTag, selectedType)
@ -118,25 +118,33 @@ const RightSideBar: React.FC<DroppedItemProps> = ({ selectedTag, setDroppedItems
const [styleOpen, setStyleOpen] = useState(false); const [styleOpen, setStyleOpen] = useState(false);
const handlePropertyChange = (changeTo: string, changeWith: string | boolean | number, is24Hrs = null) => { const handlePropertyChange = (changeTo: string, changeWith: string | boolean | number, is24Hrs = null) => {
console.log("Handle Property Change Called", "changeTo", changeTo, "changeWith", changeWith)
console.log("changeTo", changeTo, "changeWith", changeWith)
if (changeTo === '' || changeWith === '') return if (changeTo === '' || changeWith === '') return
if (changeWith === "paragraph") {
return
}
if (changeTo === "subType" && (changeWith === TEMPORAL.DATE || changeWith === TEMPORAL.DATE_TIME || changeWith === TEMPORAL.TIME)) { if (changeTo === "subType" && (changeWith === TEMPORAL.DATE || changeWith === TEMPORAL.DATE_TIME || changeWith === TEMPORAL.TIME)) {
// let change: string = changeWith; // let change: string = changeWith;
// if (change === "DATE TIME") { // if (change === "DATE TIME") {
// change = "DATE_TIME" // change = "DATE_TIME"
// } // }
setDroppedItems((prev) => ( setDroppedItems((prev) => {
{ console.log("Temporal30", prev);
return {
...prev, ...prev,
[selTagKey]: Array.isArray(prev[selTagKey]) // Ensure it's an array [selTagKey]: Array.isArray(prev[selTagKey]) // Ensure it's an array
? prev[selTagKey].map((item, i) => ? prev[selTagKey].map((item, i) =>
i === selTagIndx ? { ...item, [changeTo]: changeWith || "", format: "", update: true } : item i === selTagIndx ? { ...item, [changeTo]: changeWith || "", format: "", update: true } : item
) )
: [], : [], // Fallback in case it's undefined or not an array
}// Provide a fallback in case it's undefined or not an array };
)); });
} else if (changeTo === "subType" && typeof changeWith === "string" && changeWith.toLowerCase() === "password") { } else if (changeTo === "subType" && typeof changeWith === "string" && changeWith.toLowerCase() === "password") {
console.log("Second check")
console.log("Line 161") console.log("Line 161")
setDroppedItems((prev) => ( setDroppedItems((prev) => (
{ {
@ -150,6 +158,7 @@ const RightSideBar: React.FC<DroppedItemProps> = ({ selectedTag, setDroppedItems
)); ));
} }
else if (changeTo === "subType" && (changeWith === NUMBER.CURRENCY || changeWith === NUMBER.INTEGER || changeWith === NUMBER.DECIMAL)) { else if (changeTo === "subType" && (changeWith === NUMBER.CURRENCY || changeWith === NUMBER.INTEGER || changeWith === NUMBER.DECIMAL)) {
console.log("Third check")
let decPlace = changeWith !== NUMBER.DECIMAL ? 0 : decimalPlace; let decPlace = changeWith !== NUMBER.DECIMAL ? 0 : decimalPlace;
const isCurrency = changeWith === NUMBER.CURRENCY; const isCurrency = changeWith === NUMBER.CURRENCY;
// const currencyType = null // const currencyType = null
@ -166,6 +175,7 @@ const RightSideBar: React.FC<DroppedItemProps> = ({ selectedTag, setDroppedItems
)); ));
} else if (changeTo === "format" && selectedTag.subType === TEMPORAL.DATE_TIME) { } else if (changeTo === "format" && selectedTag.subType === TEMPORAL.DATE_TIME) {
console.log("Fourth Check")
let val = timeFormats[0].format; let val = timeFormats[0].format;
if (!is24Hrs) { if (!is24Hrs) {
val = timeFormats[1].format val = timeFormats[1].format
@ -183,7 +193,6 @@ const RightSideBar: React.FC<DroppedItemProps> = ({ selectedTag, setDroppedItems
} else { } else {
setDroppedItems((prev) => { setDroppedItems((prev) => {
console.log('Previous state:', prev);
const updatedItems = Array.isArray(prev[selTagKey]) const updatedItems = Array.isArray(prev[selTagKey])
? prev[selTagKey].map((item, i) => ? prev[selTagKey].map((item, i) =>
@ -302,7 +311,7 @@ const RightSideBar: React.FC<DroppedItemProps> = ({ selectedTag, setDroppedItems
<RecipientsAttrCon selectedRecipientId={selectedTag.recipientId} handlePropertyChange={handlePropertyChange} /> <RecipientsAttrCon selectedRecipientId={selectedTag.recipientId} handlePropertyChange={handlePropertyChange} />
} }
<DirectionalControls {...DirectionalControlsProps} selectedType={selectedTag.dimensions}/> <DirectionalControls {...DirectionalControlsProps} selectedType={selectedTag.dimensions} />
{selectedTag.label && {selectedTag.label &&

View File

@ -22,6 +22,8 @@ interface TemporalDateAttrInt {
} }
const TemporalDateAttr: React.FC<TemporalDateAttrInt> = ({ subType, format, dropDownToggle, setDropDownToggle, handlePropertyChange }) => { const TemporalDateAttr: React.FC<TemporalDateAttrInt> = ({ subType, format, dropDownToggle, setDropDownToggle, handlePropertyChange }) => {
const [is24Hrs, setIs24Hrs] = useState<boolean>(true); const [is24Hrs, setIs24Hrs] = useState<boolean>(true);
const handleIs24HrsClick = (checked: boolean) => { const handleIs24HrsClick = (checked: boolean) => {

View File

@ -6,6 +6,7 @@ import DrawSignatureCanvas from './DrawSignatureCanvas';
import { FaSpinner } from "react-icons/fa"; import { FaSpinner } from "react-icons/fa";
import { GrCheckboxSelected } from "react-icons/gr"; import { GrCheckboxSelected } from "react-icons/gr";
import { Bounce, toast } from "react-toastify"; import { Bounce, toast } from "react-toastify";
import { FiCheck } from 'react-icons/fi';
interface Signature { interface Signature {
id: string; id: string;
@ -72,6 +73,10 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({
{ id: 6, name: 'classic', initials: 'LA', style: 'classic' }, { id: 6, name: 'classic', initials: 'LA', style: 'classic' },
]; ];
const [checked, setChecked] = useState(false);
const toggleCheckbox = () => setChecked(!checked);
const [selectedSignature, setSelectedSignature] = useState<SelectStyle>( const [selectedSignature, setSelectedSignature] = useState<SelectStyle>(
signatureOptions.length > 0 ? { id: signatureOptions[0].id, style: signatureOptions[0].style } : { id: 0, style: "" } signatureOptions.length > 0 ? { id: signatureOptions[0].id, style: signatureOptions[0].style } : { id: 0, style: "" }
); );
@ -134,6 +139,10 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({
setPreview2(`data:image/png;base64,${editingSignature.initialsBlob}`); setPreview2(`data:image/png;base64,${editingSignature.initialsBlob}`);
} }
} }
if (editingSignature.default) {
setChecked(editingSignature.default)
}
} }
}, [editingSignature]); }, [editingSignature]);
@ -197,7 +206,8 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({
initialsBase64: signatures.initials, initialsBase64: signatures.initials,
firstName: fullName.split(' ')[0] || user.firstName, firstName: fullName.split(' ')[0] || user.firstName,
lastName: fullName.split(' ')[1] || user.lastName, lastName: fullName.split(' ')[1] || user.lastName,
font: selectedSignature.style font: selectedSignature.style,
default:checked
}; };
let res; let res;
@ -384,8 +394,6 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({
</div> </div>
); );
case 'SELECT': case 'SELECT':
return ( return (
<div className="h-full flex flex-col"> <div className="h-full flex flex-col">
@ -430,7 +438,7 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({
<div className="px-4 py-4 border-b border-gray-200"> <div className="px-4 py-4 border-b border-gray-200">
<div className="flex items-center space-x-3"> <div className="flex items-center space-x-3">
<div className='px-1 py-1'> <div className='px-1 py-1'>
<h3 className="text-md font-semibold text-gray-900">Add Signature</h3> <h3 className="text-md font-semibold text-gray-900">Add Signature </h3>
<p className="text-xs text-gray-500">Create your digital signature</p> <p className="text-xs text-gray-500">Create your digital signature</p>
</div> </div>
</div> </div>
@ -505,6 +513,35 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({
</button> */} </button> */}
{renderContent()} {renderContent()}
</div> </div>
<div className="text-right px-6 py-1 text-white">
<label className="inline-flex items-center cursor-pointer group">
<input
type="checkbox"
checked={checked}
onChange={toggleCheckbox}
className="sr-only"
/>
{/* Custom checkbox UI */}
<div
className={`w-4 h-4 border rounded transition-all duration-300 flex items-center justify-center
${checked ? 'bg-[var(--modalSubmitBG)] border-[var(--modalSubmitBG)] scale-110' : 'bg-white border-gray-400'}
`}
>
{checked && (
<FiCheck className="text-white text-sm transform scale-100 transition-transform duration-300" />
)}
</div>
<p className="text-sm text-gray-700 opacity-80 ms-1">
{checked
? 'Signature will be used by default.'
: 'Signature will not be used by default.'}
</p>
</label>
{/* Caption text below */}
</div>
{/* Footer Buttons in Main Area */} {/* Footer Buttons in Main Area */}
<div className="p-4 border-t border-gray-200 flex justify-end gap-3"> <div className="p-4 border-t border-gray-200 flex justify-end gap-3">

View File

@ -61,9 +61,28 @@ const Templates = () => {
return new Date(timestamp * 1000).toLocaleString(); return new Date(timestamp * 1000).toLocaleString();
}; };
const handleUseFun = (id) => { const handleUseClick = async (item: any) => {
alert(id) try {
} const payload = {
name: item?.name ?? "",
subject: item.subject,
message: item.message,
description: item.description,
expireAfter: item.expireAfter,
enableIdStamping: item.enableIdStamping,
allowViewAudit: item.allowViewAudit,
allowReassign: item.allowReassign,
enableSignatureIdStamping: item.enableSignatureIdStamping,
templateId: item.id,
};
let res = await api.post(`/api/accounts/${activeAccountId}/transactions`, payload)
console.log("handleUseClick", res.data)
// /process-step-one/:accountId/:transactionId
navigate(`/process-step-one/${activeAccountId}/${res?.data?.id}`);
} catch (error) {
console.log(error)
}
}
@ -130,7 +149,7 @@ alert(id)
<td className="px-4 py-2 text-sm text-center">{item.name || 'Dummy'}</td> <td className="px-4 py-2 text-sm text-center">{item.name || 'Dummy'}</td>
<td className="px-4 py-2 text-sm text-center">{formatDate(item.createdAt)}</td> <td className="px-4 py-2 text-sm text-center">{formatDate(item.createdAt)}</td>
<td className="px-4 py-2 text-sm text-center">{formatDate(item.lastModifiedAt)}</td> <td className="px-4 py-2 text-sm text-center">{formatDate(item.lastModifiedAt)}</td>
<td className="px-4 py-2 text-sm text-center" onClick={() => handleUseFun(item.id)}><span className="from-green-500 cursor-pointer to-blue-500 bg-gradient-to-br px-3 py-1 rounded-lg text-white font-semibold text-[12px]">Use</span></td> <td className="px-4 py-2 text-sm text-center" onClick={() => handleUseClick(item)}><span className="from-green-500 cursor-pointer to-blue-500 bg-gradient-to-br px-3 py-1 rounded-lg text-white font-semibold text-[12px]">Use</span></td>
{/* Dropdown Trigger + Tooltip */} {/* Dropdown Trigger + Tooltip */}
<td className="px-4 py-2 text-center relative"> <td className="px-4 py-2 text-center relative">
<button <button

View File

@ -351,6 +351,8 @@ export interface Recipient {
hostEmail: string; hostEmail: string;
type: recipientType; type: recipientType;
color?: string; color?: string;
allowSenderToEdit: Boolean;
allowSenderToRemove: Boolean;
roleName:string roleName:string
provideOwnTags?: boolean; provideOwnTags?: boolean;
} }

View File

@ -40,6 +40,8 @@ const handleGroupBorderPosition = (groupElements: NodeListOf<HTMLElement>, conta
const borderBottom: HTMLElement | null = document.querySelector("[border-group='" + groupElements[0].getAttribute("group") + "'][border-pos='bottom']"); const borderBottom: HTMLElement | null = document.querySelector("[border-group='" + groupElements[0].getAttribute("group") + "'][border-pos='bottom']");
const borderLeft: HTMLElement | null = document.querySelector("[border-group='" + groupElements[0].getAttribute("group") + "'][border-pos='left']"); const borderLeft: HTMLElement | null = document.querySelector("[border-group='" + groupElements[0].getAttribute("group") + "'][border-pos='left']");
console.log("handleGroupBorderPosition")
if (borderTop !== null && dimension.maxLeft !== null && dimension.minLeft !== null) { if (borderTop !== null && dimension.maxLeft !== null && dimension.minLeft !== null) {
borderTop.style.width = (dimension.maxLeft - dimension.minLeft) + "px"; borderTop.style.width = (dimension.maxLeft - dimension.minLeft) + "px";
borderTop.style.height = "1px"; borderTop.style.height = "1px";