Compare commits
No commits in common. "8ec313e6d8dca24e543b286512dc67e10bcc5eff" and "063201751c641681eede92919dd984149aef3189" have entirely different histories.
8ec313e6d8
...
063201751c
|
|
@ -109,14 +109,14 @@ function LoginForm() {
|
|||
console.log(res.status, "Response Status Line 42 LoginForm.tsx", res);
|
||||
if (res.status === 200) {
|
||||
toast.dismiss();
|
||||
// console.log('User Logined Successfully Line 45 LoginForm.tsx headerCookie:', res.headers.authorization);
|
||||
console.log('User Logined Successfully Line 45 LoginForm.tsx headerCookie:', res.headers.authorization);
|
||||
// Cookies.set("authorization", res.headers.authorization, {
|
||||
// path: "/",
|
||||
// secure: true, // Required for HTTPS
|
||||
// sameSite: "Lax", // Required for cross-origin requests
|
||||
// });
|
||||
|
||||
// dispatch(updateUser({ ...res.data, authorized: true, accessToken: res.headers.authorization }));
|
||||
dispatch(updateUser({ ...res.data, authorized: true, accessToken: res.headers.authorization }));
|
||||
setTimeout(() => navigate('/'), 1000); // Redirect after 1 second
|
||||
toast.success("Login Successful", {
|
||||
position: "top-center",
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ function RegisterForm() {
|
|||
console.log(res, "line 58");
|
||||
toast.dismiss();
|
||||
// dispatch(updateUser({ ...res.data, authorized: true, accessToken: res.headers.authorization }));
|
||||
// dispatch(updateUser({ ...res.data, authorized: true }));
|
||||
dispatch(updateUser({ ...res.data, authorized: true }));
|
||||
navigate('/')
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -258,8 +258,6 @@ const SignDocument = () => {
|
|||
}
|
||||
|
||||
|
||||
console.log(tagJson, "Line 261")
|
||||
|
||||
const handleFormSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
const submitData: TagsSubmitDataObj = {
|
||||
|
|
@ -617,10 +615,9 @@ const SignDocument = () => {
|
|||
>
|
||||
|
||||
{
|
||||
selectedDocuments && selectedDocuments.length > 0 && selectedDocuments.map((doc) => {
|
||||
console.log(tagJson, "tagJsontagJsontagJson")
|
||||
selectedDocuments && selectedDocuments.length > 0 && selectedDocuments.map((doc, indxDoc) => {
|
||||
return (
|
||||
<div key={doc.documentId} className='flex flex-col'>
|
||||
<div key={indxDoc} className='flex flex-col'>
|
||||
<div className='py-2 text-sm'>
|
||||
<p className='text-center'>{doc.name}</p>
|
||||
</div>
|
||||
|
|
@ -629,13 +626,12 @@ const SignDocument = () => {
|
|||
{
|
||||
tagJson && tagJson.length > 0 && doc.images && doc.images.length > 0 && doc.images.map((page, indx) => {
|
||||
const key = `${doc.documentId}_${page.index}`;
|
||||
const currDocTags = tagJson.filter((val) => val.pageIndex === page.index)
|
||||
console.log(currDocTags, tagJson, page, doc, "innnnnnnnnnnnn")
|
||||
const currDocTags = tagJson.filter((val, indx) => val.documentIndex === indxDoc)
|
||||
return (
|
||||
<div
|
||||
key={indx}
|
||||
id={doc.documentId + indx}
|
||||
// onDrop={(e) => handleDrop(e, doc.documentId, doc.documentId, page.index)}
|
||||
// onDrop={(e) => handleDrop(e, doc.documentId, indxDoc, page.index)}
|
||||
// onDragOver={handleDragOver}
|
||||
className='drop-page-in shadow-md relative'
|
||||
>
|
||||
|
|
@ -644,7 +640,7 @@ const SignDocument = () => {
|
|||
|
||||
|
||||
{currDocTags.map((item, index) => {
|
||||
if (item.pageIndex !== page.index) return;
|
||||
if (item.pageNumber !== page.index) return;
|
||||
return (
|
||||
<div
|
||||
tabIndex={1}
|
||||
|
|
@ -654,11 +650,11 @@ const SignDocument = () => {
|
|||
className="absolute rounded dropped-item text-sm"
|
||||
// onClick={() => handleTagClick(key, index)}
|
||||
style={{
|
||||
left: `${item.dimensions.left}px`,
|
||||
top: `${item.dimensions.top}px`,
|
||||
width: `${item.dimensions.width}px`,
|
||||
height: `${item.dimensions.height}px`,
|
||||
border: `${((!hideTags && focusElement) && !transparentTags && focusElement.documentId === item.documentId && focusElement.focusElementIndx === index) ? '2px dashed #1c398e' : 'none'}`,
|
||||
left: `${item.dimension.left}px`,
|
||||
top: `${item.dimension.top}px`,
|
||||
width: `${item.dimension.width}px`,
|
||||
height: `${item.dimension.height}px`,
|
||||
border: `${((!hideTags && focusElement) && !transparentTags && focusElement.documentIndex === item.documentIndex && focusElement.focusElementIndx === index) ? '2px dashed #1c398e' : 'none'}`,
|
||||
// display: `${hideTags ? 'none' : 'block'}`
|
||||
}}
|
||||
>
|
||||
|
|
@ -669,7 +665,7 @@ const SignDocument = () => {
|
|||
id={item.id}
|
||||
tabIndex={1}
|
||||
className={`h-full text-[14px] font-medium w-full border-slate-100 rounded ${(transparentTags || hideTags) ? "pointer-events-none" : "bg-slate-200 shadow-sm opacity-80"} flex justify-start items-end`}
|
||||
// style={{ height: item.dimensions.height + "px" }}
|
||||
// style={{ height: item.dimension.height + "px" }}
|
||||
>
|
||||
|
||||
{/* <input
|
||||
|
|
@ -681,7 +677,7 @@ const SignDocument = () => {
|
|||
{
|
||||
item.subType === "SINGLE_LINE" && <p
|
||||
// name={item.id}
|
||||
// style={{ height: item.dimensions.height + "px" }}
|
||||
// style={{ height: item.dimension.height + "px" }}
|
||||
onInput={(e) => {
|
||||
const val = e.currentTarget.textContent;
|
||||
handleTagUpdate(index, val as string);
|
||||
|
|
@ -738,11 +734,11 @@ const SignDocument = () => {
|
|||
<div
|
||||
id={item.id}
|
||||
className={`h-full w-full rounded flex justify-center items-center ${transparentTags || hideTags ? "pointer-events-none" : "bg-slate-200 shadow-sm border-slate-100 opacity-80"}`}
|
||||
// style={{ height: item.dimensions.height + "px" }}
|
||||
// style={{ height: item.dimension.height + "px" }}
|
||||
>
|
||||
<input
|
||||
name={item.id}
|
||||
// style={{ height: item.dimensions.height + "px" }}
|
||||
// style={{ height: item.dimension.height + "px" }}
|
||||
className="w-full px-2 outline-none"
|
||||
type="checkbox" />
|
||||
</div>}
|
||||
|
|
@ -756,7 +752,7 @@ const SignDocument = () => {
|
|||
id={item.id}
|
||||
onClick={() => handleSignClick(index)}
|
||||
className={`flex justify-center items-center h-full w-full rounded cursor-pointer ${transparentTags || hideTags ? "pointer-events-none bg-transparent" : "bg-slate-200 shadow-sm border-slate-100 opacity-80"}`}
|
||||
// style={{ height: item.dimensions.height + "px" }}
|
||||
// style={{ height: item.dimension.height + "px" }}
|
||||
>
|
||||
{/* <input type="checkbox" className="" /> */}
|
||||
{
|
||||
|
|
@ -767,8 +763,8 @@ const SignDocument = () => {
|
|||
:
|
||||
<img
|
||||
style={{
|
||||
width: `${item.dimensions.width}px`,
|
||||
height: `${item.dimensions.height}px`,
|
||||
width: `${item.dimension.width}px`,
|
||||
height: `${item.dimension.height}px`,
|
||||
}}
|
||||
src={saved.signature as string} />
|
||||
}
|
||||
|
|
@ -783,15 +779,15 @@ const SignDocument = () => {
|
|||
id={item.id}
|
||||
onClick={() => handleSignClick(index)}
|
||||
className={`flex justify-center items-center h-full w-full rounded cursor-pointer ${transparentTags || hideTags ? "pointer-events-none" : "bg-slate-200 shadow-sm border-slate-100 opacity-80"}`}
|
||||
// style={{ height: item.dimensions.height + "px" }}
|
||||
// style={{ height: item.dimension.height + "px" }}
|
||||
>
|
||||
{((!transparentTags && !hideTags) && !(saved.save && (index in signConfObj) && signConfObj[index].accepted)) ?
|
||||
<TbSignature className="text-lg text-slate-600" />
|
||||
:
|
||||
<img
|
||||
style={{
|
||||
width: `${item.dimensions.width}px`,
|
||||
height: `${item.dimensions.height}px`,
|
||||
width: `${item.dimension.width}px`,
|
||||
height: `${item.dimension.height}px`,
|
||||
}}
|
||||
className="w-[100%] h-full"
|
||||
src={saved.initial as string} />
|
||||
|
|
@ -807,7 +803,7 @@ const SignDocument = () => {
|
|||
id={item.id}
|
||||
onClick={() => handleStampClick(index)}
|
||||
className={`flex justify-center items-center h-full w-full rounded cursor-pointer ${transparentTags || hideTags ? "pointer-events-none" : "bg-slate-200 shadow-sm border-slate-100 opacity-80"}`}
|
||||
// style={{ height: item.dimensions.height + "px" }}
|
||||
// style={{ height: item.dimension.height + "px" }}
|
||||
>
|
||||
{!transparentTags && !hideTags ?
|
||||
<FaStamp className="text-lg text-slate-600" />
|
||||
|
|
@ -824,7 +820,7 @@ const SignDocument = () => {
|
|||
id={item.id}
|
||||
// onClick={() => handleSignClick(index)}
|
||||
className={`flex justify-center items-center h-full w-full rounded cursor-pointer ${transparentTags || hideTags ? "pointer-events-none" : "bg-slate-200 shadow-sm border-slate-100 opacity-80"}`}
|
||||
// style={{ height: item.dimensions.height + "px" }}
|
||||
// style={{ height: item.dimension.height + "px" }}
|
||||
>
|
||||
{!transparentTags && !hideTags ?
|
||||
<FaFileAlt className="text-lg text-slate-600" />
|
||||
|
|
@ -913,7 +909,7 @@ const SignDocument = () => {
|
|||
|
||||
|
||||
{/* Focus Show Element */}
|
||||
{(!transparentTags && !hideTags) && (focusElement && focusElement.documentId === item.documentId && focusElement.focusElementIndx === index) &&
|
||||
{(!transparentTags && !hideTags) && (focusElement && focusElement.documentIndex === item.documentIndex && focusElement.focusElementIndx === index) &&
|
||||
<>
|
||||
<div
|
||||
className="absolute left-0 z-50 bg-blue-900 text-xs text-slate-100 px-2 py-[2px] rounded-sm whitespace-nowrap"
|
||||
|
|
@ -923,7 +919,7 @@ const SignDocument = () => {
|
|||
</div>
|
||||
<div
|
||||
className="absolute left-[-10px] z-50 flex max-w-max"
|
||||
style={{ left: -(item.dimensions.left + 20) + "px", top: ((item.dimensions.height / 2) - 18) + "px" }}
|
||||
style={{ left: -(item.dimension.left + 20) + "px", top: ((item.dimension.height / 2) - 18) + "px" }}
|
||||
>
|
||||
{/* <FaArrowRight className="text-[var(--primary)] text-xl" />
|
||||
*/}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ function Dashboard() {
|
|||
// window.location.href = '/login';
|
||||
// return;
|
||||
// }
|
||||
// console.log("OUT MIC CHECK", transactionStatus, TRANSACTION_STATUS_ENUMS.TRANSACTION_SEND_SUCCESS, TRANSACTION_STATUS_ENUMS.TRANSACTION_INITIATED);
|
||||
console.log("OUT MIC CHECK", transactionStatus, TRANSACTION_STATUS_ENUMS.TRANSACTION_SEND_SUCCESS, TRANSACTION_STATUS_ENUMS.TRANSACTION_INITIATED);
|
||||
|
||||
// Clear all if transaction success
|
||||
if (transactionStatus === TRANSACTION_STATUS_ENUMS.TRANSACTION_SEND_SUCCESS || transactionStatus === TRANSACTION_STATUS_ENUMS.TRANSACTION_INITIATED || transactionStatus === TRANSACTION_STATUS_ENUMS.TRANSACTION_SEND_FAILURE) {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import { AppDispatch } from '../../../store/store'
|
|||
import { IoMdClose } from 'react-icons/io'
|
||||
import api from '../../../config/api'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import axios from 'axios'
|
||||
|
||||
interface DocumentCardProps {
|
||||
id: string;
|
||||
|
|
@ -34,7 +33,7 @@ const DocumentCard: React.FC<DocumentCardProps> = ({ id, name, isCompleted }) =>
|
|||
let isCompleted = false;
|
||||
let updateTimeout: ReturnType<typeof setTimeout> | null = null;
|
||||
let lastUpdate = 0;
|
||||
const delay = 1000;
|
||||
const delay = 2000;
|
||||
|
||||
const docProgSSE = new EventSource(`http://192.168.2.112:8083/api/progress/${id}`);
|
||||
|
||||
|
|
@ -67,8 +66,6 @@ const DocumentCard: React.FC<DocumentCardProps> = ({ id, name, isCompleted }) =>
|
|||
lastUpdate = Date.now();
|
||||
}, delay - sinceLast);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
docProgSSE.onerror = (error) => {
|
||||
|
|
|
|||
|
|
@ -112,26 +112,32 @@ const ProcessStepOne = () => {
|
|||
name: `${recipient.firstName} ${recipient.lastName}`
|
||||
}));
|
||||
|
||||
console.log(recipientsData, "printing Recipient Data Line 114");
|
||||
|
||||
// await api.post(`/api/accounts/${accountId}/transactions/${transactionId}/recipients`, recipientsData).then((res) => {
|
||||
// console.log(res, "Response Line 117")
|
||||
// }).catch((err) => {
|
||||
// console.log(err)
|
||||
// })
|
||||
|
||||
dispatch(addRecipientAsync({recipientsData, accountId, transactionId}));
|
||||
|
||||
dispatch(showLoader("Processing Message..."));
|
||||
|
||||
await api.put(`/api/accounts/${accountId}/transactions/${transactionId}`, { subject: emailDtls.subject, message: emailDtls.message, status: "CREATED" }).then((res) => {
|
||||
console.log(res);
|
||||
})
|
||||
|
||||
dispatch(hideLoader());
|
||||
|
||||
if (isSendNow) {
|
||||
dispatch(updateTransactionStatus(TRANSACTION_STATUS_ENUMS.TRANSACTION_SEND_SUCCESS));
|
||||
setTimeout(() => {
|
||||
// navigate("/");
|
||||
navigate("/");
|
||||
}, 1000);
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
// Preview & Tag
|
||||
// Assuming you'd fetch or pass doc/recipients response here
|
||||
// dispatch(setImages(...));
|
||||
// dispatch(updateRecipientIds(...));
|
||||
// dispatch(setTransactionId(...));
|
||||
dispatch(resetDocuments())
|
||||
dispatch(resetRecipients())
|
||||
dispatch(hideLoader());
|
||||
setTimeout(() => {
|
||||
navigate(`/process-step-two/${accountId}/${transactionId}`);
|
||||
}, 1000);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,12 +4,13 @@ import { RootState } from '../../../store/store'
|
|||
|
||||
import api from '../../../config/api';
|
||||
|
||||
import RightSideBar from './rightSideBar/RightSideBar';
|
||||
import RightSideBar from './RightSideBar';
|
||||
import { DroppedItem } from '../../../utlity/types';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
|
||||
import { TRANSACTION_STATUS_ENUMS, updateTransactionStatus } from '../../../store/slices/transactionSlice';
|
||||
import { hideLoader, showLoader } from '../../../store/slices/loaderSlice';
|
||||
import { IoMdClose } from 'react-icons/io';
|
||||
|
||||
import fields from '../../../helper/fieldsListData';
|
||||
import { fetchRecipients } from '../../../store/slices/selectedRecipientsSlice';
|
||||
import { fetchDocuments } from '../../../store/slices/documentSlice';
|
||||
import { FaQuestionCircle } from 'react-icons/fa';
|
||||
|
|
@ -44,6 +45,8 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// const transactionId = useSelector((state: RootState) => state.transaction.transactionId)
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
|
|
@ -124,29 +127,7 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
|
|||
accountId: string,
|
||||
transactionId: string
|
||||
) => {
|
||||
// tagsData = tagsData.filter((tag, indx) => (("update" in tag && tag.update) || !("id" in tag)) )
|
||||
// Filter Tags that needs to update
|
||||
const updatedData = {}
|
||||
|
||||
// debugger
|
||||
|
||||
for (const [recipientId, tags] of Object.entries(tagsData)) {
|
||||
console.log(recipientId, tags, "line 133")
|
||||
const updateTags = []
|
||||
for (const tag of tags) {
|
||||
if ("update" in tag && tag.update) {
|
||||
updateTags.push(tag)
|
||||
}
|
||||
if (updateTags.length && "update" in updateTags[updateTags.length - 1]) {
|
||||
delete updateTags[updateTags.length - 1].update
|
||||
}
|
||||
}
|
||||
|
||||
updatedData[recipientId] = updateTags
|
||||
}
|
||||
|
||||
|
||||
const requests = Object.entries(updatedData).map(([recipientId, tags]) => {
|
||||
const requests = Object.entries(tagsData).map(([recipientId, tags]) => {
|
||||
return api.put(
|
||||
`/api/accounts/${accountId}/transactions/${transactionId}/recipients/${recipientId}/tags`,
|
||||
tags
|
||||
|
|
@ -155,12 +136,7 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
|
|||
|
||||
try {
|
||||
const responses = await Promise.all(requests);
|
||||
const droppedItemsUpdateFalse = Object.fromEntries(
|
||||
Object.entries(droppedItems).map(([recipientId, tags]) => {
|
||||
return [recipientId, tags.map(tag => ({ ...tag, update: false }))];
|
||||
})
|
||||
)
|
||||
setDroppedItems(droppedItemsUpdateFalse);
|
||||
console.log("All recipient tags submitted:", responses);
|
||||
} catch (error) {
|
||||
console.error("Error submitting recipient tags:", error);
|
||||
}
|
||||
|
|
@ -185,6 +161,7 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
|
|||
// const remove = []
|
||||
|
||||
// console.log(updatedTags, "updatedTags");
|
||||
|
||||
for (const dropPageIds of Object.keys(updatedTags)) {
|
||||
for (const dropTag of updatedTags[dropPageIds]) {
|
||||
let mask = null
|
||||
|
|
@ -200,8 +177,6 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
|
|||
}
|
||||
// }
|
||||
|
||||
console.log(dropTag, "line 204")
|
||||
|
||||
const isDeleted = "isDeleted" in dropTag ? dropTag.isDeleted : false
|
||||
|
||||
const updatedTagData = {
|
||||
|
|
@ -229,8 +204,7 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
|
|||
"textSize": 14.0
|
||||
},
|
||||
// "required": (dropTag.type.toUpperCase() !== "SIGNATURE" && dropTag.type.toUpperCase() !== "INITIALS") ? dropTag.required : true,
|
||||
"required": "required" in dropTag ? dropTag.required : true,
|
||||
"update": "update" in dropTag ? dropTag.update : false,
|
||||
"required": false,
|
||||
"readOnly": false,
|
||||
}
|
||||
|
||||
|
|
@ -272,13 +246,9 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
|
|||
// for(const recipient of selectedRecipients) {
|
||||
// const recrecipient
|
||||
// }
|
||||
|
||||
tagsData = groupByRecipientId(tagsData);
|
||||
sendTagsToRecipients(tagsData, accountId, transactionId);
|
||||
|
||||
// (async () => {
|
||||
// const res = await api.put(`/api/accounts/${accountId}/transactions/${transactionId}`, {status: "SENT"})
|
||||
// console.log(res, "Check123")
|
||||
// })()
|
||||
}, [isSend])
|
||||
// Save Tags - END
|
||||
|
||||
|
|
@ -309,7 +279,6 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
|
|||
// const IconComponent = typeToIconMap[field.type] || <FaQuestionCircle />;
|
||||
|
||||
let prepData = {
|
||||
properties: data.properties,
|
||||
icon: typeToIconMap[field.label.toUpperCase()] || <FaQuestionCircle />,
|
||||
type: dragElemData.label,
|
||||
subType: (dragElemData.label in droppedTagsDefaultField) ? droppedTagsDefaultField[dragElemData.label] : '',
|
||||
|
|
@ -332,7 +301,6 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
|
|||
pageIndex: pageIndex,
|
||||
recipientId: dragElemData.recipientId,
|
||||
recipientIndx: dragElemData.recipientIndx,
|
||||
update: true,
|
||||
isDeleted: false
|
||||
}
|
||||
|
||||
|
|
@ -419,7 +387,7 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
|
|||
...droppedItems,
|
||||
[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 } } : item
|
||||
)
|
||||
: [], // Provide a fallback in case it's undefined or not an array
|
||||
});
|
||||
|
|
@ -475,7 +443,7 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
|
|||
...droppedItems,
|
||||
[key]: Array.isArray(droppedItems[key]) // Ensure it's an array
|
||||
? droppedItems[key].map((item, i) =>
|
||||
i === index ? { ...item, dimensions: { ...item.dimensions, width: newWidth, height: newHeight }, update: true } : item
|
||||
i === index ? { ...item, dimensions: { ...item.dimensions, width: newWidth, height: newHeight } } : item
|
||||
)
|
||||
: [], // Provide a fallback in case it's undefined or not an array
|
||||
});
|
||||
|
|
@ -517,107 +485,109 @@ const DocumentContainer: React.FC<DocumentContainerProps> = ({ isSend }) => {
|
|||
)
|
||||
}));
|
||||
})()
|
||||
|
||||
}
|
||||
|
||||
// const handleAddRadio = (e: React.MouseEvent<HTMLElement>, key: string, index: number) => {
|
||||
// // const dataToSet: DroppedItemsObj = {
|
||||
// // ...droppedItems,
|
||||
// // [key]: [...(droppedItems[key] || []),
|
||||
// // {
|
||||
// // ...prepData,
|
||||
// // radioGroups: dragElemData.label === "radio" ? [{ ...prepData }] : []
|
||||
// // }],
|
||||
// // }
|
||||
|
||||
// // const lastRadioElemRect = e.currentTarget?.parentElement.previousSibling.getBoundingClientRect();
|
||||
// // console.log(lastRadioElemRect, "lastRadioElemRect")
|
||||
|
||||
// const setNewData = droppedItems;
|
||||
|
||||
// if (Array.isArray(setNewData[key][index].radioGroups) && setNewData[key][index].radioGroups?.length > 0) {
|
||||
// setNewData[key][index].radioGroups?.push(setNewData[key][index].radioGroups[0])
|
||||
const handleAddRadio = (e: React.MouseEvent<HTMLElement>, key: string, index: number) => {
|
||||
// const dataToSet: DroppedItemsObj = {
|
||||
// ...droppedItems,
|
||||
// [key]: [...(droppedItems[key] || []),
|
||||
// {
|
||||
// ...prepData,
|
||||
// radioGroups: dragElemData.label === "radio" ? [{ ...prepData }] : []
|
||||
// }],
|
||||
// }
|
||||
|
||||
// setDroppedItems(setNewData);
|
||||
// };
|
||||
// const lastRadioElemRect = e.currentTarget?.parentElement.previousSibling.getBoundingClientRect();
|
||||
// console.log(lastRadioElemRect, "lastRadioElemRect")
|
||||
|
||||
const setNewData = droppedItems;
|
||||
|
||||
if (Array.isArray(setNewData[key][index].radioGroups) && setNewData[key][index].radioGroups?.length > 0) {
|
||||
setNewData[key][index].radioGroups?.push(setNewData[key][index].radioGroups[0])
|
||||
}
|
||||
|
||||
setDroppedItems(setNewData);
|
||||
};
|
||||
|
||||
|
||||
|
||||
// const handleRadioTagMouseDown = (event: React.MouseEvent<HTMLDivElement>, key: string, index: number, radioIndex: number) => {
|
||||
const handleRadioTagMouseDown = (event: React.MouseEvent<HTMLDivElement>, key: string, index: number, radioIndex: number) => {
|
||||
|
||||
// event.preventDefault();
|
||||
event.preventDefault();
|
||||
|
||||
// let targetContainer = event?.currentTarget?.parentElement;
|
||||
// let targetElement = event?.currentTarget;
|
||||
let targetContainer = event?.currentTarget?.parentElement;
|
||||
let targetElement = event?.currentTarget;
|
||||
|
||||
// if (!targetContainer || !targetElement) return;
|
||||
if (!targetContainer || !targetElement) return;
|
||||
|
||||
// const containerRect = targetContainer.getBoundingClientRect();
|
||||
// const elementRect = targetElement.getBoundingClientRect();
|
||||
const containerRect = targetContainer.getBoundingClientRect();
|
||||
const elementRect = targetElement.getBoundingClientRect();
|
||||
|
||||
// // Calculate the initial offset (where the mouse was clicked inside the element)
|
||||
// const offsetX = event.clientX - elementRect.left;
|
||||
// const offsetY = event.clientY - elementRect.top;
|
||||
// Calculate the initial offset (where the mouse was clicked inside the element)
|
||||
const offsetX = event.clientX - elementRect.left;
|
||||
const offsetY = event.clientY - elementRect.top;
|
||||
|
||||
// const handleMouseMove = (event: PointerEvent) => {
|
||||
// // Get new X and Y positions relative to the container
|
||||
// // let x = offsetX;
|
||||
// // let y = offsetY;
|
||||
const handleMouseMove = (event: PointerEvent) => {
|
||||
// Get new X and Y positions relative to the container
|
||||
// let x = offsetX;
|
||||
// let y = offsetY;
|
||||
|
||||
// let x = event.clientX - elementRect.left;
|
||||
// let y = event.clientY - elementRect.top;
|
||||
let x = event.clientX - elementRect.left;
|
||||
let y = event.clientY - elementRect.top;
|
||||
|
||||
// const newData = droppedItems;
|
||||
const newData = droppedItems;
|
||||
|
||||
// if (newData[key][index].radioGroups && newData[key][index].radioGroups.length > 0) {
|
||||
// newData[key][index].radioGroups[radioIndex].dimensions.left = x;
|
||||
// newData[key][index].radioGroups[radioIndex].dimensions.top = y;
|
||||
if (newData[key][index].radioGroups && newData[key][index].radioGroups.length > 0) {
|
||||
newData[key][index].radioGroups[radioIndex].dimensions.left = x;
|
||||
newData[key][index].radioGroups[radioIndex].dimensions.top = y;
|
||||
|
||||
// let topMin = Number.POSITIVE_INFINITY;
|
||||
// let topMax = Number.NEGATIVE_INFINITY;
|
||||
// let leftMin = Number.POSITIVE_INFINITY;
|
||||
// let leftMax = Number.NEGATIVE_INFINITY;
|
||||
let topMin = Number.POSITIVE_INFINITY;
|
||||
let topMax = Number.NEGATIVE_INFINITY;
|
||||
let leftMin = Number.POSITIVE_INFINITY;
|
||||
let leftMax = Number.NEGATIVE_INFINITY;
|
||||
|
||||
// for (const radio of newData[key][index].radioGroups) {
|
||||
// if (radio.dimensions.left < leftMin) {
|
||||
// leftMin = radio.dimensions.left;
|
||||
// }
|
||||
// if (radio.dimensions.left > leftMax) {
|
||||
// leftMax = radio.dimensions.left;
|
||||
// }
|
||||
// if (radio.dimensions.top < topMin) {
|
||||
// topMin = radio.dimensions.top;
|
||||
// }
|
||||
// if (radio.dimensions.top > topMax) {
|
||||
// topMax = radio.dimensions.top;
|
||||
// }
|
||||
// }
|
||||
for (const radio of newData[key][index].radioGroups) {
|
||||
if (radio.dimensions.left < leftMin) {
|
||||
leftMin = radio.dimensions.left;
|
||||
}
|
||||
if (radio.dimensions.left > leftMax) {
|
||||
leftMax = radio.dimensions.left;
|
||||
}
|
||||
if (radio.dimensions.top < topMin) {
|
||||
topMin = radio.dimensions.top;
|
||||
}
|
||||
if (radio.dimensions.top > topMax) {
|
||||
topMax = radio.dimensions.top;
|
||||
}
|
||||
}
|
||||
|
||||
// newData[key][index].radioPosition = {
|
||||
// topMin: topMin,
|
||||
// topMax: topMax,
|
||||
// leftMin: leftMin,
|
||||
// leftMax: leftMax,
|
||||
// width: leftMax - leftMin,
|
||||
// height: topMax - topMin
|
||||
// }
|
||||
newData[key][index].radioPosition = {
|
||||
topMin: topMin,
|
||||
topMax: topMax,
|
||||
leftMin: leftMin,
|
||||
leftMax: leftMax,
|
||||
width: leftMax - leftMin,
|
||||
height: topMax - topMin
|
||||
}
|
||||
|
||||
// newData[key][index].dimensions.left = x;
|
||||
// newData[key][index].dimensions.top = y;
|
||||
// }
|
||||
newData[key][index].dimensions.left = x;
|
||||
newData[key][index].dimensions.top = y;
|
||||
}
|
||||
|
||||
// setDroppedItems({ ...newData });
|
||||
// };
|
||||
setDroppedItems({ ...newData });
|
||||
};
|
||||
|
||||
// const handleMouseUp = () => {
|
||||
// document.removeEventListener("pointermove", handleMouseMove);
|
||||
// document.removeEventListener("pointerup", handleMouseUp);
|
||||
// };
|
||||
const handleMouseUp = () => {
|
||||
document.removeEventListener("pointermove", handleMouseMove);
|
||||
document.removeEventListener("pointerup", handleMouseUp);
|
||||
};
|
||||
|
||||
// // Add event listeners
|
||||
// document.addEventListener("pointermove", handleMouseMove);
|
||||
// document.addEventListener("pointerup", handleMouseUp);
|
||||
// }
|
||||
// Add event listeners
|
||||
document.addEventListener("pointermove", handleMouseMove);
|
||||
document.addEventListener("pointerup", handleMouseUp);
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ import api from '../../../config/api';
|
|||
import { useParams } from 'react-router-dom';
|
||||
import typeToIconMap from '../../../helper/iconMap';
|
||||
import { FaQuestionCircle } from 'react-icons/fa';
|
||||
import { TagsProperties } from '../../../utlity/types';
|
||||
|
||||
const handlePointerDown = (event: React.DragEvent<HTMLDivElement>, label: string, recipientId: number, recipientIndx: number, tagsProperties: TagsProperties) => {
|
||||
const handlePointerDown = (event: React.DragEvent<HTMLDivElement>, label: string, recipientId: number, recipientIndx: number) => {
|
||||
|
||||
const dragElemRect = event.currentTarget.getBoundingClientRect();
|
||||
let width = dragElemRect.width
|
||||
let height = dragElemRect.height
|
||||
|
|
@ -27,8 +27,7 @@ const handlePointerDown = (event: React.DragEvent<HTMLDivElement>, label: string
|
|||
recipientId: recipientId,
|
||||
recipientIndx: recipientIndx,
|
||||
width,
|
||||
height,
|
||||
properties: tagsProperties
|
||||
height
|
||||
}
|
||||
|
||||
window.dragElemData = JSON.stringify(obj);
|
||||
|
|
@ -42,7 +41,7 @@ interface FieldListProps {
|
|||
|
||||
const FieldList: React.FC<FieldListProps> = ({ color, recipientId, recipientIndx }) => {
|
||||
|
||||
const [tagsData, setTagsData] = useState<TagsProperties[]>([]);
|
||||
const [tagsData, setTagsData] = useState([]);
|
||||
|
||||
const { accountId } = useParams<{ accountId: string }>();
|
||||
if (!accountId) {
|
||||
|
|
@ -92,7 +91,7 @@ const FieldList: React.FC<FieldListProps> = ({ color, recipientId, recipientIndx
|
|||
<div
|
||||
draggable={true}
|
||||
key={index}
|
||||
onPointerDown={(e) => handlePointerDown(e, field.type.toLowerCase(), recipientId, recipientIndx, field)}
|
||||
onPointerDown={(e) => handlePointerDown(e, field.type.toLowerCase(), recipientId, recipientIndx)}
|
||||
className="p-1 flex justify-start items-center gap-2 rounded-sm cursor-grab hover:bg-slate-200 transition-all duration-300">
|
||||
<div
|
||||
className={`p-1 text-sm rounded-sm text-white`}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import { useEffect, useState } from 'react'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
|
||||
import NavTwo from './NavTwo';
|
||||
import LeftSideBar from './LeftSideBar';
|
||||
import DocumentContainer from './DocumentContainer';
|
||||
|
||||
import { IoMdClose } from 'react-icons/io'
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { RootState } from '../../../store/store';
|
||||
import Loader from '../../dashboard/Loader';
|
||||
|
|
@ -24,6 +25,28 @@ const ProcessStepTwo = () => {
|
|||
|
||||
return (
|
||||
<div className={`min-w-full relative h-screen bg-slate-100 overflow-hidden ${(globalLoader.isLoading) ? 'pointer-events-none' : ''}`}>
|
||||
|
||||
{/* Top Header One */}
|
||||
|
||||
{/* <div className='flex items-center shadow-sm pb-3 bg-slate-100'>
|
||||
|
||||
<div className='flex w-full justify-center items-center px-4'>
|
||||
<div className='cursor-default flex justify-center items-center gap-4 border-b-3 relative border-[var(--primary)] py-1 px-4'>
|
||||
<p className="text-xs tracking-wider">Setup your Document</p>
|
||||
<div className='absolute bottom-[-7px] w-3 h-3 rounded-full right-[-4px] bg-[var(--primary)] z-50' ></div>
|
||||
</div>
|
||||
<div className='cursor-default flex justify-center items-center gap-4 border-b-3 relative border-[var(--primary)] py-1 px-4'>
|
||||
<p className="text-xs tracking-wider">Prepare</p>
|
||||
<div className='absolute bottom-[-7px] w-3 h-3 rounded-full right-[-4px] bg-[var(--primary)] z-50' ></div>
|
||||
</div>
|
||||
<div className='cursor-default flex justify-center items-center gap-4 border-b-3 relative border-[var(--primaryLight)] py-1 px-4'>
|
||||
<p className="text-xs tracking-wider">Hooray !</p>
|
||||
<div className='absolute bottom-[-7px] w-3 h-3 rounded-full right-[-4px] bg-[var(--primaryLight)] z-50' ></div>
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
{/* Top Header One */}
|
||||
|
||||
<NavTwo isFields={isFields} setIsFields={setIsFields} isSend={isSend} setIsSend={setIsSend} />
|
||||
|
||||
<div className='grid grid-cols-12 gap-1 mt-1 h-[calc(100vh-46px)] overflow-hidden'>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,653 @@
|
|||
import { MdKeyboardArrowDown } from "react-icons/md";
|
||||
import { DroppedItemsObj } from "./DocumentContainer";
|
||||
import React, { ReactHTMLElement, useEffect, useState } from "react";
|
||||
|
||||
|
||||
import { RiAsterisk } from "react-icons/ri";
|
||||
import { GoDotFill } from "react-icons/go";
|
||||
import { IoClose } from "react-icons/io5";
|
||||
import { LuAsterisk } from "react-icons/lu";
|
||||
import { dateFormats, dateTimeFormats, monthFormats, timeFormats, weekFormats, yearFormats } from "../../../utlity/dateTimeUtils";
|
||||
import { DroppedItem } from "../../../utlity/types";
|
||||
import { IoMdClose } from "react-icons/io";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
interface DroppedItemProps {
|
||||
selectedTag: DroppedItem
|
||||
setDroppedItems: React.Dispatch<React.SetStateAction<DroppedItemsObj>>
|
||||
selTagKey: string,
|
||||
selTagIndx: number
|
||||
}
|
||||
|
||||
enum TEXT {
|
||||
PARAGRAPH = "paragraph",
|
||||
SINGLE_LINE = "single_line",
|
||||
PASSWORD = "password",
|
||||
}
|
||||
// enum SIGNATURE {
|
||||
// TYPED = "typed",
|
||||
// DRAW = "draw",
|
||||
// UPLOAD = "upload",
|
||||
// }
|
||||
// enum INITIALS {
|
||||
// TYPED = "typed",
|
||||
// DRAW = "draw",
|
||||
// UPLOAD = "upload",
|
||||
// }
|
||||
export enum TEMPORAL {
|
||||
DATE = "date",
|
||||
TIME = "time",
|
||||
DATE_TIME = "date_time",
|
||||
// YEAR = "year",
|
||||
// MONTH = "month",
|
||||
// WEEK = "week",
|
||||
}
|
||||
|
||||
enum NUMBER {
|
||||
INTEGER = "integer",
|
||||
DECIMAL = "decimal",
|
||||
CURRENCY = "currency"
|
||||
}
|
||||
// enum IMAGE {
|
||||
// STAMP = "stamp",
|
||||
// LOGO = "logo"
|
||||
// }
|
||||
|
||||
enum SELECT {
|
||||
SINGLE_SELECT = "single select",
|
||||
MULTI_SELECT = "multi select"
|
||||
}
|
||||
|
||||
|
||||
enum MASKTYPE {
|
||||
ALL = "all",
|
||||
LAST_FOUR = "last_four",
|
||||
CREDIT_CARD = "credit_Card",
|
||||
NATIONAL_INSURANCE = "national_insurance",
|
||||
SOCIAL_SECURITY = "social_security",
|
||||
SOCIAL_INSURANCE = "social_insurance"
|
||||
}
|
||||
|
||||
enum MASKCHARACTER {
|
||||
ASTERISK = "ASTERISK",
|
||||
DOT = "DOT",
|
||||
X = "CROSS",
|
||||
}
|
||||
|
||||
const enumMap = {
|
||||
text: TEXT,
|
||||
temporal: TEMPORAL,
|
||||
number: NUMBER,
|
||||
image: String,
|
||||
select: SELECT
|
||||
}
|
||||
|
||||
enum DROPDOWNTOGGLE {
|
||||
TYPE,
|
||||
MASK_TYPE,
|
||||
MASK_CHARACTER,
|
||||
DDMMYY_FORMAT
|
||||
}
|
||||
|
||||
const dateTimeFormatMap = {
|
||||
"date": dateFormats,
|
||||
"time": timeFormats,
|
||||
"date_time": dateTimeFormats,
|
||||
"year": yearFormats,
|
||||
"month": monthFormats,
|
||||
"week": weekFormats
|
||||
}
|
||||
|
||||
const RightSideBar: React.FC<DroppedItemProps> = ({ selectedTag, setDroppedItems, selTagKey, selTagIndx }) => {
|
||||
console.log(selectedTag, "selectedTag Line 102")
|
||||
const selectedType = selectedTag.type in enumMap && enumMap[selectedTag.type as keyof typeof enumMap];
|
||||
const [dropDownToggle, setDropDownToggle] = useState<DROPDOWNTOGGLE | null>(null);
|
||||
|
||||
// const [showFormatEg, setShowFormatEg] = useState<boolean>(false);
|
||||
const [is24Hrs, setIs24Hrs] = useState<boolean>(true);
|
||||
const [isCurrentTimeStamp, setIsCurrentTimeStamp] = useState<boolean>(true);
|
||||
|
||||
// const [selectedOptions, setSelectedOptions] = useState<string[]>([])
|
||||
|
||||
const [decimalPlace, setDecimalPlace] = useState<number>(2)
|
||||
const [selectedOption, setSelectedOption] = useState<string>()
|
||||
|
||||
const handlePropertyChange = (changeTo: string, changeWith: string | boolean | number) => {
|
||||
console.log("Handle Property Change Called", "changeTo", changeTo, "changeWith", changeWith)
|
||||
if (changeTo === '' || changeWith === '') return
|
||||
|
||||
if (changeTo === "subType" && (changeWith === TEMPORAL.DATE || changeWith === TEMPORAL.DATE_TIME || changeWith === TEMPORAL.TIME)) {
|
||||
// let change: string = changeWith;
|
||||
// if (change === "DATE TIME") {
|
||||
// change = "DATE_TIME"
|
||||
// }
|
||||
setDroppedItems((prev) => (
|
||||
{
|
||||
...prev,
|
||||
[selTagKey]: Array.isArray(prev[selTagKey]) // Ensure it's an array
|
||||
? prev[selTagKey].map((item, i) =>
|
||||
i === selTagIndx ? { ...item, [changeTo]: changeWith || "", format: "" } : item
|
||||
)
|
||||
: [],
|
||||
}// Provide a fallback in case it's undefined or not an array
|
||||
));
|
||||
} else if (changeTo === "subType" && typeof changeWith === "string" && changeWith.toLowerCase() === "password") {
|
||||
console.log("Line 161")
|
||||
setDroppedItems((prev) => (
|
||||
{
|
||||
...prev,
|
||||
[selTagKey]: Array.isArray(prev[selTagKey])
|
||||
? prev[selTagKey].map((item, i) =>
|
||||
i === selTagIndx ? { ...item, [changeTo]: changeWith, maskType: "All", maskCharacter: "ASTERISK" } : item
|
||||
)
|
||||
: [],
|
||||
}
|
||||
));
|
||||
}
|
||||
else if (changeTo === "subType" && (changeWith === NUMBER.CURRENCY || changeWith === NUMBER.INTEGER || changeWith === NUMBER.DECIMAL)) {
|
||||
let decPlace = changeWith !== NUMBER.DECIMAL ? 0 : decimalPlace;
|
||||
const isCurrency = changeWith === NUMBER.CURRENCY;
|
||||
// const currencyType = null
|
||||
|
||||
setDroppedItems((prev) => (
|
||||
{
|
||||
...prev,
|
||||
[selTagKey]: Array.isArray(prev[selTagKey]) // Ensure it's an array
|
||||
? prev[selTagKey].map((item, i) =>
|
||||
i === selTagIndx ? { ...item, [changeTo]: changeWith, decimalPlace: decPlace, isCurrency } : item
|
||||
)
|
||||
: [],
|
||||
}// Provide a fallback in case it's undefined or not an array
|
||||
));
|
||||
|
||||
} else if (changeTo === "format" && selectedTag.subType === TEMPORAL.DATE_TIME) {
|
||||
let val = timeFormats[0].format;
|
||||
if (!is24Hrs) {
|
||||
val = timeFormats[1].format
|
||||
}
|
||||
setDroppedItems((prev) => (
|
||||
{
|
||||
...prev,
|
||||
[selTagKey]: Array.isArray(prev[selTagKey]) // Ensure it's an array
|
||||
? prev[selTagKey].map((item, i) =>
|
||||
i === selTagIndx ? { ...item, [changeTo]: changeWith + " " + val } : item
|
||||
)
|
||||
: [],
|
||||
}// Provide a fallback in case it's undefined or not an array
|
||||
));
|
||||
|
||||
} else {
|
||||
setDroppedItems((prev) => (
|
||||
{
|
||||
...prev,
|
||||
[selTagKey]: Array.isArray(prev[selTagKey]) // Ensure it's an array
|
||||
? prev[selTagKey].map((item, i) =>
|
||||
i === selTagIndx ? { ...item, [changeTo]: changeWith } : item
|
||||
)
|
||||
: [],
|
||||
}// Provide a fallback in case it's undefined or not an array
|
||||
));
|
||||
}
|
||||
setDropDownToggle(null)
|
||||
}
|
||||
|
||||
// const handleSelectTagOptions = () => {
|
||||
// if (!selectedOptions.length) return
|
||||
// setDroppedItems((prev) => (
|
||||
// {
|
||||
// ...prev,
|
||||
// [selTagKey]: Array.isArray(prev[selTagKey])
|
||||
// ? prev[selTagKey].map((item, i) => {
|
||||
// if (i === selTagIndx) {
|
||||
// return { ...item, options: [...selectedOptions] };
|
||||
// }
|
||||
// return item;
|
||||
// })
|
||||
// : [],
|
||||
// }
|
||||
// ));
|
||||
// }
|
||||
|
||||
// useEffect(() => {
|
||||
// handleSelectTagOptions();
|
||||
// }, [selectedOptions])
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedTag.subType === TEMPORAL.DATE || selectedTag.subType === TEMPORAL.DATE_TIME || selectedTag.subType === TEMPORAL.TIME) {
|
||||
|
||||
if (selectedTag.subType === TEMPORAL.DATE) {
|
||||
handlePropertyChange("format", dateFormats[0].format)
|
||||
}
|
||||
else if (selectedTag.subType === TEMPORAL.DATE_TIME) {
|
||||
handlePropertyChange("format", dateTimeFormats[0].format)
|
||||
}
|
||||
else if (selectedTag.subType === TEMPORAL.TIME) {
|
||||
handlePropertyChange("format", timeFormats[0].format)
|
||||
}
|
||||
}
|
||||
// else if(selectedTag.subType === TEXT.PASSWORD) {
|
||||
// handlePropertyChange("format", timeFormats[0].format)
|
||||
// }
|
||||
}, [selectedTag.subType])
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedTag.format === timeFormats[1].format && is24Hrs) {
|
||||
setIs24Hrs(false);
|
||||
} else if (selectedTag.format === timeFormats[0].format && !is24Hrs) {
|
||||
setIs24Hrs(true);
|
||||
}
|
||||
}, [selectedTag.format])
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedTag.label === "temporal") {
|
||||
handlePropertyChange("subType", TEMPORAL.DATE);
|
||||
handlePropertyChange("format", "DD/MM/YY");
|
||||
}
|
||||
}, [])
|
||||
|
||||
|
||||
const handleIs24HrsClick = (checked: boolean) => {
|
||||
if (selectedTag.subType === TEMPORAL.TIME) {
|
||||
if (!checked) {
|
||||
handlePropertyChange("format", timeFormats[1].format)
|
||||
} else {
|
||||
handlePropertyChange("format", timeFormats[0].format)
|
||||
}
|
||||
}
|
||||
setIs24Hrs(checked)
|
||||
}
|
||||
|
||||
|
||||
const handleIsCurrentTimeStamp = (checked: boolean) => {
|
||||
if (selectedTag.type.toLowerCase() === "temporal") {
|
||||
setIsCurrentTimeStamp(checked)
|
||||
handlePropertyChange("currentTimeStamp", checked);
|
||||
}
|
||||
}
|
||||
|
||||
const handleAddSelectOption = () => {
|
||||
if (selectedOption && selectedOption.length) {
|
||||
setDroppedItems((prev) => (
|
||||
{
|
||||
...prev,
|
||||
[selTagKey]: Array.isArray(prev[selTagKey])
|
||||
? prev[selTagKey].map((item, i) => {
|
||||
if (i === selTagIndx) {
|
||||
return { ...item, options: item.options ? [...item.options, selectedOption] : [selectedOption] };
|
||||
}
|
||||
return item;
|
||||
})
|
||||
: [],
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const handleSelectOptionDel = (indx: number) => {
|
||||
// setSelectedOptions(prev =>
|
||||
// prev.filter((_, i) => i !== indx)
|
||||
// )
|
||||
|
||||
setDroppedItems((prev) => (
|
||||
{
|
||||
...prev,
|
||||
[selTagKey]: Array.isArray(prev[selTagKey])
|
||||
? prev[selTagKey].map((item, i) => {
|
||||
if (i === selTagIndx) {
|
||||
return { ...item, options: item.options ? item.options.filter((_, i) => i !== indx) : [] };
|
||||
}
|
||||
return item;
|
||||
})
|
||||
: [],
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
const handleDecimalPlace = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const val = Number(e.target.value)
|
||||
setDecimalPlace(val)
|
||||
handlePropertyChange("decimalPlace", val)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if ("styles" in selectedTag) {
|
||||
const fontSize = selectedTag?.styles?.textSize;
|
||||
const tagHeight = selectedTag?.dimensions?.height - 18;
|
||||
|
||||
|
||||
console.log(fontSize, tagHeight, "Line 323", selectedTag?.styles)
|
||||
|
||||
if (selectedTag.subType !== "password" && selectedTag.subType !== "paragraph" && tagHeight > (fontSize + fontSize)) {
|
||||
console.log("Change subType Called from if")
|
||||
handlePropertyChange("subType", "paragraph")
|
||||
} else if (selectedTag.subType !== "password" && selectedTag.subType !== "single_line" && tagHeight <= (fontSize + fontSize)) {
|
||||
console.log("Change subType Called from elseif")
|
||||
handlePropertyChange("subType", "single_line")
|
||||
}
|
||||
}
|
||||
}, [selectedTag])
|
||||
|
||||
console.log("RightSideBar - selectedTag", selectedTag)
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Right Side Bar Start */}
|
||||
<div className='col-span-2 w-full h-full bg-white text-sm'>
|
||||
<p className="p-2 font-semibold text-md">Properties</p>
|
||||
<hr className="text-slate-200" />
|
||||
|
||||
<div className="p-3 text-sm text-slate-600 flex flex-col gap-2">
|
||||
|
||||
{/* label */}
|
||||
<div className="flex flex-col">
|
||||
<label htmlFor="" className="">Label</label>
|
||||
<input
|
||||
value={selectedTag.label}
|
||||
onChange={(e) => handlePropertyChange('label', e.target.value)}
|
||||
type="text"
|
||||
className="outline-none border-1 rounded px-2 py-1 border-slate-200" />
|
||||
</div>
|
||||
|
||||
{/* Required */}
|
||||
{(selectedTag.type !== "signature" && selectedTag.type !== "initials") && <div className="flex justify-between items-center">
|
||||
<label htmlFor="required" className="text-xs text-slate-600 transitions-all duration-150">Required</label>
|
||||
<input
|
||||
id="required"
|
||||
checked={selectedTag.required ? selectedTag.required : false}
|
||||
onChange={(e) => handlePropertyChange('required', e.target.checked)}
|
||||
type="checkbox"
|
||||
className="outline-none border-1 rounded px-2 py-1 border-slate-200"
|
||||
/>
|
||||
</div>}
|
||||
|
||||
{/* Use Current TimeStamp */}
|
||||
{selectedTag.type.toLowerCase() === "temporal" && <div className="flex justify-left items-center gap-1.5 mt-0.5">
|
||||
<label
|
||||
className={`text-xs ${isCurrentTimeStamp ? "text-slate-600" : "text-slate-400"} transitions-all duration-150`}
|
||||
htmlFor="use_current_timestamp"
|
||||
>
|
||||
Use Current Timestamp
|
||||
</label>
|
||||
<input
|
||||
checked={isCurrentTimeStamp ? isCurrentTimeStamp : false}
|
||||
onChange={(e) => handleIsCurrentTimeStamp(e.target.checked)}
|
||||
id="use_current_timestamp"
|
||||
type="checkbox"
|
||||
/>
|
||||
</div>}
|
||||
|
||||
{/* Type | SubType */}
|
||||
{selectedType && Object.keys(selectedType).length > 0 &&
|
||||
<div className="flex flex-col">
|
||||
<label htmlFor="" className="">Type</label>
|
||||
<div
|
||||
onClick={() => setDropDownToggle(dropDownToggle === DROPDOWNTOGGLE.TYPE ? null : DROPDOWNTOGGLE.TYPE)}
|
||||
className="flex justify-between items-center border-1 rounded px-2 py-1 border-slate-200">
|
||||
<p className="capitalize cursor-pointer">{selectedTag?.subType ? (selectedTag.subType === "date_time" ? "Date Time" : selectedTag.subType) : selectedType[Object.keys(selectedType)[0] as keyof typeof selectedType]}</p>
|
||||
<MdKeyboardArrowDown />
|
||||
</div>
|
||||
|
||||
{dropDownToggle === DROPDOWNTOGGLE.TYPE &&
|
||||
<div className="shadow bg-slate-100 mt-1 border-[1px] border-slate-100 rounded">
|
||||
{Object.keys(selectedType).map((val, indx) => (
|
||||
<div
|
||||
key={indx}
|
||||
onClick={() => handlePropertyChange("subType", selectedType[val as keyof typeof selectedType])}
|
||||
className={`capitalize px-2 py-1 hover:bg-slate-200 cursor-pointer`}
|
||||
>
|
||||
{selectedType[val as keyof typeof selectedType] === "date_time" ? "Date Time" : selectedType[val as keyof typeof selectedType]}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
{/* Mask Type */}
|
||||
{
|
||||
selectedTag?.subType === TEXT.PASSWORD &&
|
||||
<div>
|
||||
<label htmlFor="" className="">Mask Type</label>
|
||||
<div
|
||||
onClick={() => setDropDownToggle(dropDownToggle === DROPDOWNTOGGLE.MASK_TYPE ? null : DROPDOWNTOGGLE.MASK_TYPE)}
|
||||
className="flex justify-between items-center border-1 rounded px-2 py-1 border-slate-200">
|
||||
<p className="capitalize cursor-pointer">{(selectedTag.maskType && selectedTag.maskType.replace("_", " ")) ? selectedTag.maskType : MASKTYPE.ALL}</p>
|
||||
<MdKeyboardArrowDown />
|
||||
</div>
|
||||
|
||||
{
|
||||
dropDownToggle === DROPDOWNTOGGLE.MASK_TYPE &&
|
||||
<div className="shadow bg-slate-100 mt-1 border-[1px] border-slate-100 rounded">
|
||||
{(Object.keys(MASKTYPE) as (keyof typeof MASKTYPE)[]).map((val, indx) =>
|
||||
(
|
||||
<div
|
||||
key={indx}
|
||||
onClick={() => handlePropertyChange("maskType", MASKTYPE[val])}
|
||||
className="capitalize px-2 py-1 hover:bg-slate-200 cursor-pointer"
|
||||
>
|
||||
{(MASKTYPE[val]).replace("_", " ")}
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
{/* Mask Character - START */}
|
||||
{
|
||||
selectedTag?.subType === TEXT.PASSWORD &&
|
||||
<div>
|
||||
<label htmlFor="" className="">Mask Character</label>
|
||||
<div
|
||||
onClick={() => setDropDownToggle(dropDownToggle === DROPDOWNTOGGLE.MASK_CHARACTER ? null : DROPDOWNTOGGLE.MASK_CHARACTER)}
|
||||
className="flex justify-between items-center border-1 rounded px-2 py-1 border-slate-200">
|
||||
<p className="capitalize cursor-pointer py-1">
|
||||
{selectedTag?.maskCharacter
|
||||
?
|
||||
selectedTag.maskCharacter === MASKCHARACTER.ASTERISK && <LuAsterisk /> ||
|
||||
selectedTag.maskCharacter === MASKCHARACTER.DOT && <GoDotFill /> ||
|
||||
selectedTag.maskCharacter === MASKCHARACTER.X && <IoClose />
|
||||
:
|
||||
<LuAsterisk />
|
||||
}
|
||||
</p>
|
||||
|
||||
|
||||
<MdKeyboardArrowDown />
|
||||
</div>
|
||||
|
||||
{
|
||||
dropDownToggle === DROPDOWNTOGGLE.MASK_CHARACTER &&
|
||||
<div className="shadow bg-slate-100 mt-1 border-[1px] border-slate-100 rounded">
|
||||
{(Object.keys(MASKCHARACTER) as (keyof typeof MASKCHARACTER)[]).map((val, indx) =>
|
||||
(
|
||||
<div
|
||||
key={indx}
|
||||
onClick={() => handlePropertyChange("maskCharacter", MASKCHARACTER[val])}
|
||||
className="capitalize p-2 hover:bg-slate-200 cursor-pointer"
|
||||
>
|
||||
{
|
||||
MASKCHARACTER[val] === MASKCHARACTER.ASTERISK &&
|
||||
<LuAsterisk />
|
||||
}
|
||||
{
|
||||
MASKCHARACTER[val] === MASKCHARACTER.DOT &&
|
||||
<GoDotFill />
|
||||
}
|
||||
{
|
||||
MASKCHARACTER[val] === MASKCHARACTER.X &&
|
||||
<IoClose />
|
||||
}
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
{/* Mask Character - END */}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{/* TEMPORAL DATE FORMAT - START */}
|
||||
{
|
||||
(selectedTag?.subType === TEMPORAL.DATE ||
|
||||
selectedTag?.subType === TEMPORAL.TIME ||
|
||||
selectedTag?.subType === TEMPORAL.DATE_TIME) &&
|
||||
|
||||
<div>
|
||||
{/* <div className="flex justify-between">
|
||||
<label htmlFor="" className="">Formats</label>
|
||||
<div className="flex justify-center items-center gap-1.5">
|
||||
<input
|
||||
checked={showFormatEg ? showFormatEg : false}
|
||||
onChange={(e) => setShowFormatEg(e.target.checked)}
|
||||
id="data_time_format"
|
||||
type="checkbox" />
|
||||
<label className="text-xs text-slate-400" htmlFor="data_time_format">
|
||||
Show Example
|
||||
</label>
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
<div className="flex justify-between">
|
||||
<label htmlFor="" className="">Formats</label>
|
||||
{(selectedTag.subType === TEMPORAL.DATE_TIME || selectedTag.subType === TEMPORAL.TIME) &&
|
||||
<div className="flex justify-center items-center gap-1.5">
|
||||
<input
|
||||
checked={is24Hrs ? is24Hrs : false}
|
||||
onChange={(e) => handleIs24HrsClick(e.target.checked)}
|
||||
id="data_time_format"
|
||||
type="checkbox" />
|
||||
<label className={`text-xs ${is24Hrs ? "text-slate-600" : "text-slate-400"} transitions-all duration-150`} htmlFor="data_time_format">
|
||||
24 Hrs
|
||||
</label>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div
|
||||
onClick={() => setDropDownToggle(dropDownToggle === DROPDOWNTOGGLE.DDMMYY_FORMAT ? null : DROPDOWNTOGGLE.DDMMYY_FORMAT)}
|
||||
className="flex justify-between items-center border-1 rounded px-2 py-1 border-slate-200">
|
||||
<p className="cursor-pointer py-1">
|
||||
{selectedTag.format ? selectedTag.format : dateTimeFormatMap['date'][0].format}
|
||||
{/* {(selectedTag.subType !== TEMPORAL.DATE && selectedTag.subType !== TEMPORAL.TIME) ? (is24Hrs ? " " + timeFormats[0].format : " " + timeFormats[1].format) : ""} */}
|
||||
</p>
|
||||
<MdKeyboardArrowDown />
|
||||
</div>
|
||||
|
||||
{
|
||||
dropDownToggle === DROPDOWNTOGGLE.DDMMYY_FORMAT &&
|
||||
<div className="shadow bg-slate-100 mt-1 border-[1px] max-h-[200px] overflow-y-auto border-slate-100 rounded">
|
||||
{dateTimeFormatMap[selectedTag.subType].map((valObj, indx) => {
|
||||
// let val = showFormatEg ? valObj["example"] : valObj["format"]
|
||||
let val = valObj["format"]
|
||||
if (selectedTag.subType === TEMPORAL.DATE_TIME) {
|
||||
if (is24Hrs) {
|
||||
val = val + " " + timeFormats[0].format;
|
||||
} else {
|
||||
val = val + " " + timeFormats[1].format;
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div
|
||||
key={indx}
|
||||
onClick={() => handlePropertyChange("format", valObj["format"])}
|
||||
className="px-2 py-1 hover:bg-slate-200 cursor-pointer"
|
||||
>
|
||||
{val}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
|
||||
{selectedTag.format && <div className="pt-4">
|
||||
{/* <p>
|
||||
Example
|
||||
</p> */}
|
||||
<p className="text-center">{dayjs().format(selectedTag.format)}</p>
|
||||
</div>}
|
||||
</div>
|
||||
}
|
||||
{/* TEMPORAL DATE FORMAT - END */}
|
||||
|
||||
|
||||
|
||||
{/* NUMBER - DECIMAL PLACES */}
|
||||
{
|
||||
selectedTag?.subType === NUMBER.DECIMAL &&
|
||||
<div>
|
||||
<label htmlFor="" className="">Decimal Places</label>
|
||||
<input
|
||||
type="number"
|
||||
onChange={(e) => handleDecimalPlace(e)}
|
||||
value={decimalPlace}
|
||||
className="bg-slate-100 w-full outline-none p-2 rounded" />
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
{(selectedTag?.subType === "single select" || selectedTag?.subType === "multi select") &&
|
||||
<>
|
||||
<div>
|
||||
<label htmlFor="" className="">Add Options</label>
|
||||
<input
|
||||
type="text"
|
||||
onChange={(e) => setSelectedOption(e.target.value)}
|
||||
value={selectedOption}
|
||||
onKeyUp={(e) => {
|
||||
if (e.code === "Enter") {
|
||||
// if (selectedOption) {
|
||||
// setSelectedOptions((prev) => [...prev, selectedOption]);
|
||||
// setSelectedOption("");
|
||||
// }
|
||||
handleAddSelectOption()
|
||||
}
|
||||
}}
|
||||
className="bg-slate-100 w-full outline-none p-2 rounded" />
|
||||
|
||||
<div className="h-[150px] mt-1 overflow-hidden overflow-y-auto">
|
||||
{
|
||||
selectedTag.options && selectedTag.options.map((val, indx) => (
|
||||
<div
|
||||
key={indx}
|
||||
className="flex justify-between items-center px-2 py-1 my-1 rounded bg-slate-100">
|
||||
<p>{val}</p>
|
||||
<IoMdClose
|
||||
onClick={() =>
|
||||
// setSelectedOptions(prev =>
|
||||
// prev.filter((_, i) => i !== indx)
|
||||
// )
|
||||
handleSelectOptionDel(indx)
|
||||
}
|
||||
className="cursor-pointer text-slate-500 hover:text-slate-600" />
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{/* Right Side Bar End */}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default RightSideBar
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
|
||||
import { MdKeyboardArrowDown } from 'react-icons/md';
|
||||
import { DROPDOWNTOGGLE } from './RightSideBar';
|
||||
|
||||
interface CommonAttrDropDownInt {
|
||||
selectedType: any;
|
||||
subType: string | undefined;
|
||||
dropDownToggle: DROPDOWNTOGGLE | null;
|
||||
setDropDownToggle: React.Dispatch<React.SetStateAction<DROPDOWNTOGGLE | null>>;
|
||||
handlePropertyChange: (changeTo: string, changeWith: string | boolean | number) => void;
|
||||
}
|
||||
|
||||
const CommonAttrDropDown: React.FC<CommonAttrDropDownInt> = ({selectedType, subType, dropDownToggle, setDropDownToggle, handlePropertyChange}) => {
|
||||
|
||||
return (
|
||||
<div className="flex flex-col">
|
||||
<label htmlFor="" className="">Type</label>
|
||||
<div
|
||||
onClick={() => setDropDownToggle(dropDownToggle === DROPDOWNTOGGLE.TYPE ? null : DROPDOWNTOGGLE.TYPE)}
|
||||
className="flex justify-between items-center border-1 rounded px-2 py-1 border-slate-200">
|
||||
<p className="capitalize cursor-pointer">{subType ? (subType === "date_time" ? "Date Time" : subType) : selectedType[Object.keys(selectedType)[0] as keyof typeof selectedType]}</p>
|
||||
<MdKeyboardArrowDown />
|
||||
</div>
|
||||
|
||||
{dropDownToggle === DROPDOWNTOGGLE.TYPE &&
|
||||
<div className="shadow bg-slate-100 mt-1 border-[1px] border-slate-100 rounded">
|
||||
{Object.keys(selectedType).map((val, indx) => (
|
||||
<div
|
||||
key={indx}
|
||||
onClick={() => handlePropertyChange("subType", selectedType[val as keyof typeof selectedType])}
|
||||
className={`capitalize px-2 py-1 hover:bg-slate-200 cursor-pointer`}
|
||||
>
|
||||
{selectedType[val as keyof typeof selectedType] === "date_time" ? "Date Time" : selectedType[val as keyof typeof selectedType]}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default CommonAttrDropDown
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
import React, { useState } from 'react'
|
||||
|
||||
interface CurrTimeStampAttrInt {
|
||||
type: string;
|
||||
handlePropertyChange: (changeTo: string, changeWith: string | boolean | number) => void;
|
||||
}
|
||||
|
||||
const CurrTimeStampAttr: React.FC<CurrTimeStampAttrInt> = ({ type, handlePropertyChange}) => {
|
||||
|
||||
const [isCurrentTimeStamp, setIsCurrentTimeStamp] = useState<boolean>(true);
|
||||
|
||||
const handleIsCurrentTimeStamp = (checked: boolean) => {
|
||||
if (type.toLowerCase() === "temporal") {
|
||||
setIsCurrentTimeStamp(checked)
|
||||
handlePropertyChange("currentTimeStamp", checked);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex justify-left items-center gap-1.5 mt-0.5">
|
||||
<label
|
||||
className={`text-xs ${isCurrentTimeStamp ? "text-slate-600" : "text-slate-400"} transitions-all duration-150`}
|
||||
htmlFor="use_current_timestamp"
|
||||
>
|
||||
Use Current Timestamp
|
||||
</label>
|
||||
<input
|
||||
checked={isCurrentTimeStamp ? isCurrentTimeStamp : false}
|
||||
onChange={(e) => handleIsCurrentTimeStamp(e.target.checked)}
|
||||
id="use_current_timestamp"
|
||||
type="checkbox"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default CurrTimeStampAttr
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
import React from 'react'
|
||||
|
||||
interface LabelAttrInt {
|
||||
label: string;
|
||||
handlePropertyChange: (changeTo: string, changeWith: string | boolean | number) => void;
|
||||
}
|
||||
|
||||
const LabelAttr: React.FC<LabelAttrInt> = ({ label, handlePropertyChange }) => {
|
||||
return (
|
||||
<div className="flex flex-col">
|
||||
<label htmlFor="" className="">Label</label>
|
||||
<input
|
||||
value={label}
|
||||
onChange={(e) => handlePropertyChange('label', e.target.value)}
|
||||
type="text"
|
||||
className="outline-none border-1 rounded px-2 py-1 border-slate-200" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default LabelAttr
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
import { MdKeyboardArrowDown } from "react-icons/md";
|
||||
import { DROPDOWNTOGGLE, MASKCHARACTER, MASKTYPE } from "./RightSideBar";
|
||||
import { LuAsterisk } from "react-icons/lu";
|
||||
import { GoDotFill } from "react-icons/go";
|
||||
import { IoClose } from "react-icons/io5";
|
||||
|
||||
interface MaskTypePassAttrInt {
|
||||
maskType: string;
|
||||
maskCharacter: string;
|
||||
dropDownToggle: DROPDOWNTOGGLE | null;
|
||||
setDropDownToggle: React.Dispatch<React.SetStateAction<DROPDOWNTOGGLE | null>>;
|
||||
handlePropertyChange: (changeTo: string, changeWith: string | boolean | number) => void;
|
||||
}
|
||||
|
||||
const MaskTypePassAttr: React.FC<MaskTypePassAttrInt> = ({ maskType, maskCharacter, dropDownToggle, setDropDownToggle, handlePropertyChange }) => {
|
||||
return (
|
||||
<>
|
||||
{/* Mask Type */}
|
||||
<div>
|
||||
<label htmlFor="" className="">Mask Type</label>
|
||||
<div
|
||||
onClick={() => setDropDownToggle(dropDownToggle === DROPDOWNTOGGLE.MASK_TYPE ? null : DROPDOWNTOGGLE.MASK_TYPE)}
|
||||
className="flex justify-between items-center border-1 rounded px-2 py-1 border-slate-200">
|
||||
<p className="capitalize cursor-pointer">{(maskType && maskType.replace("_", " ")) ? maskType : MASKTYPE.ALL}</p>
|
||||
<MdKeyboardArrowDown />
|
||||
</div>
|
||||
|
||||
{
|
||||
dropDownToggle === DROPDOWNTOGGLE.MASK_TYPE &&
|
||||
<div className="shadow bg-slate-100 mt-1 border-[1px] border-slate-100 rounded">
|
||||
{(Object.keys(MASKTYPE) as (keyof typeof MASKTYPE)[]).map((val, indx) =>
|
||||
(
|
||||
<div
|
||||
key={indx}
|
||||
onClick={() => handlePropertyChange("maskType", MASKTYPE[val])}
|
||||
className="capitalize px-2 py-1 hover:bg-slate-200 cursor-pointer"
|
||||
>
|
||||
{(MASKTYPE[val]).replace("_", " ")}
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
{/* Mask Character */}
|
||||
<div>
|
||||
<label htmlFor="" className="">Mask Character</label>
|
||||
<div
|
||||
onClick={() => setDropDownToggle(dropDownToggle === DROPDOWNTOGGLE.MASK_CHARACTER ? null : DROPDOWNTOGGLE.MASK_CHARACTER)}
|
||||
className="flex justify-between items-center border-1 rounded px-2 py-1 border-slate-200">
|
||||
<p className="capitalize cursor-pointer py-1">
|
||||
{maskCharacter
|
||||
?
|
||||
maskCharacter === MASKCHARACTER.ASTERISK && <LuAsterisk /> ||
|
||||
maskCharacter === MASKCHARACTER.DOT && <GoDotFill /> ||
|
||||
maskCharacter === MASKCHARACTER.X && <IoClose />
|
||||
:
|
||||
<LuAsterisk />
|
||||
}
|
||||
</p>
|
||||
|
||||
|
||||
<MdKeyboardArrowDown />
|
||||
</div>
|
||||
|
||||
{
|
||||
dropDownToggle === DROPDOWNTOGGLE.MASK_CHARACTER &&
|
||||
<div className="shadow bg-slate-100 mt-1 border-[1px] border-slate-100 rounded">
|
||||
{(Object.keys(MASKCHARACTER) as (keyof typeof MASKCHARACTER)[]).map((val, indx) =>
|
||||
(
|
||||
<div
|
||||
key={indx}
|
||||
onClick={() => handlePropertyChange("maskCharacter", MASKCHARACTER[val])}
|
||||
className="capitalize p-2 hover:bg-slate-200 cursor-pointer"
|
||||
>
|
||||
{
|
||||
MASKCHARACTER[val] === MASKCHARACTER.ASTERISK &&
|
||||
<LuAsterisk />
|
||||
}
|
||||
{
|
||||
MASKCHARACTER[val] === MASKCHARACTER.DOT &&
|
||||
<GoDotFill />
|
||||
}
|
||||
{
|
||||
MASKCHARACTER[val] === MASKCHARACTER.X &&
|
||||
<IoClose />
|
||||
}
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
export default MaskTypePassAttr
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
import React from 'react'
|
||||
|
||||
interface MaxMinLenAttrIntr {
|
||||
maxLength: number;
|
||||
minLength: number;
|
||||
}
|
||||
|
||||
const MaxMinLenAttr : React.FC<MaxMinLenAttrIntr> = ({ maxLength, minLength }) => {
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<label htmlFor="">Max Length</label>
|
||||
<input
|
||||
value={minLength ? minLength : 0}
|
||||
type="number"
|
||||
className="outline-none border-1 rounded px-2 py-1 border-slate-200" />
|
||||
</div>
|
||||
<div className="mt-2">
|
||||
<label htmlFor="">Min Length</label>
|
||||
<input
|
||||
value={maxLength ? maxLength : 255}
|
||||
type="number"
|
||||
className="outline-none border-1 rounded px-2 py-1 border-slate-200" />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default MaxMinLenAttr
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
import React, { useEffect, useState } from 'react'
|
||||
import { IoCheckmark } from 'react-icons/io5';
|
||||
import { MdKeyboardArrowDown } from 'react-icons/md';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { RootState } from '../../../../store/store';
|
||||
|
||||
|
||||
interface SelectedRecipientsIntr {
|
||||
id: number;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
color: string;
|
||||
}
|
||||
|
||||
interface RecipientsAttrConIntr {
|
||||
selectedRecipientId: number;
|
||||
handlePropertyChange: (changeTo: string, changeWith: string | boolean | number) => void;
|
||||
}
|
||||
|
||||
const RecipientsAttrCon: React.FC<RecipientsAttrConIntr> = ({ selectedRecipientId, handlePropertyChange }) => {
|
||||
|
||||
const [selectedRecipient, setSelectedRecipient] = useState(null);
|
||||
|
||||
const selectedRecipients = useSelector((state: RootState) => state.selectedRecipients.recipients);
|
||||
const [dropDownToggle, setDropDownToggle] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedRecipients.length) {
|
||||
const filter = selectedRecipients.filter((obj, indx) => obj.id == selectedRecipientId)
|
||||
setSelectedRecipient(filter[0]);
|
||||
}
|
||||
}, [selectedRecipientId])
|
||||
|
||||
|
||||
if (!selectedRecipient) {
|
||||
return (
|
||||
<>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='relative'
|
||||
tabIndex={0}
|
||||
onBlur={() => setDropDownToggle(false)}>
|
||||
{/* Selected Recipient */}
|
||||
<div
|
||||
onClick={() => setDropDownToggle(!dropDownToggle)}
|
||||
className='flex items-center justify-between gap-2 w-full p-2 text-xs rounded-sm border-1 border-slate-200 cursor-pointer'>
|
||||
<div className='flex items-center gap-1.5'>
|
||||
<p className='w-3 h-3 rounded-sm' style={{ background: selectedRecipient.color }}></p>
|
||||
{/* <FaUserTie className='w-3 h-3 text-2xl mt-[1px]' style={{ color: selectedRecipient.color }} /> */}
|
||||
<p>{"firstName" in selectedRecipient && selectedRecipient.firstName} {"lastName" in selectedRecipient && selectedRecipient.lastName}</p>
|
||||
</div>
|
||||
<MdKeyboardArrowDown />
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`absolute w-full shadow-md rounded-md mt-1 px-2 py-1 z-20 bg-white ${dropDownToggle ? '' : 'hidden'}`}>
|
||||
{selectedRecipients.length && selectedRecipients.map((recipient, indx) => {
|
||||
return (<div
|
||||
key={indx}
|
||||
className='flex items-center justify-between gap-2 w-full p-2 text-xs rounded-sm cursor-pointer hover:bg-slate-100'
|
||||
onClick={() => {
|
||||
// handlePropertyChange()
|
||||
setTimeout(() => {
|
||||
setDropDownToggle(false);
|
||||
}, 0)
|
||||
}}
|
||||
>
|
||||
<div className='flex items-center gap-1.5'>
|
||||
<p className='w-3 h-3 rounded-sm' style={{ background: recipient.color }}></p>
|
||||
{/* <FaUser className='w-3 h-3 text-2xl mt-[1px]' style={{ color: recipient.color }} /> */}
|
||||
<p>{recipient.firstName} {recipient.lastName} </p>
|
||||
</div>
|
||||
{selectedRecipientId === recipient.id && <IoCheckmark className='text-[var(--primary)]' />}
|
||||
</div>)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default RecipientsAttrCon
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
import React from 'react'
|
||||
|
||||
interface RequiredAttrInt {
|
||||
required: boolean;
|
||||
handlePropertyChange: (changeTo: string, changeWith: string | boolean | number) => void;
|
||||
}
|
||||
|
||||
const RequiredAttr : React.FC<RequiredAttrInt> = ({required, handlePropertyChange}) => {
|
||||
return (
|
||||
<div className="flex justify-between items-center">
|
||||
<label htmlFor="required" className="text-xs text-slate-600 transitions-all duration-150">Required</label>
|
||||
<input
|
||||
id="required"
|
||||
checked={required ? required : false}
|
||||
onChange={(e) => handlePropertyChange('required', e.target.checked)}
|
||||
type="checkbox"
|
||||
className="outline-none border-1 rounded px-2 py-1 border-slate-200"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default RequiredAttr
|
||||
|
|
@ -1,367 +0,0 @@
|
|||
import { DroppedItemsObj } from "../DocumentContainer";
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import { dateFormats, dateTimeFormats, timeFormats } from "../../../../utlity/dateTimeFormats";
|
||||
import { DroppedItem } from "../../../../utlity/types";
|
||||
import { IoIosArrowDown } from "react-icons/io";
|
||||
|
||||
import { TagsTypes } from "../../../../utlity/types";
|
||||
|
||||
import LabelAttr from "./LabelAttr";
|
||||
import RequiredAttr from "./RequiredAttr";
|
||||
import CurrTimeStampAttr from "./currTimeStampAttr";
|
||||
import CommonAttrDropDown from "./CommonAttrDropDown";
|
||||
import MaskTypePassAttr from "./MaskTypePassAttr";
|
||||
import TemporalDateAttr from "./TemporalDateAttr";
|
||||
import SelectTagAttr from "./SelectTagAttr";
|
||||
import MaxMinLenAttr from "./MaxMinLenAttr";
|
||||
import RecipientsAttrCon from "./RecipientsAttrCon";
|
||||
|
||||
export interface DroppedItemProps {
|
||||
selectedTag: DroppedItem
|
||||
setDroppedItems: React.Dispatch<React.SetStateAction<DroppedItemsObj>>
|
||||
selTagKey: string,
|
||||
selTagIndx: number
|
||||
}
|
||||
|
||||
export enum TEXT {
|
||||
PARAGRAPH = "paragraph",
|
||||
SINGLE_LINE = "single_line",
|
||||
PASSWORD = "password",
|
||||
}
|
||||
|
||||
export enum TEMPORAL {
|
||||
DATE = "date",
|
||||
TIME = "time",
|
||||
DATE_TIME = "date_time",
|
||||
}
|
||||
|
||||
export enum NUMBER {
|
||||
INTEGER = "integer",
|
||||
DECIMAL = "decimal",
|
||||
CURRENCY = "currency"
|
||||
}
|
||||
|
||||
export enum SELECT {
|
||||
SINGLE_SELECT = "single select",
|
||||
MULTI_SELECT = "multi select"
|
||||
}
|
||||
|
||||
export enum MASKTYPE {
|
||||
ALL = "all",
|
||||
LAST_FOUR = "last_four",
|
||||
CREDIT_CARD = "credit_Card",
|
||||
NATIONAL_INSURANCE = "national_insurance",
|
||||
SOCIAL_SECURITY = "social_security",
|
||||
SOCIAL_INSURANCE = "social_insurance"
|
||||
}
|
||||
|
||||
export enum MASKCHARACTER {
|
||||
ASTERISK = "ASTERISK",
|
||||
DOT = "DOT",
|
||||
X = "CROSS",
|
||||
}
|
||||
|
||||
export const enumMap = {
|
||||
text: TEXT,
|
||||
temporal: TEMPORAL,
|
||||
number: NUMBER,
|
||||
image: String,
|
||||
select: SELECT
|
||||
}
|
||||
|
||||
export enum DROPDOWNTOGGLE {
|
||||
TYPE,
|
||||
MASK_TYPE,
|
||||
MASK_CHARACTER,
|
||||
DDMMYY_FORMAT
|
||||
}
|
||||
|
||||
const RightSideBar: React.FC<DroppedItemProps> = ({ selectedTag, setDroppedItems, selTagKey, selTagIndx }) => {
|
||||
|
||||
const selectedType = selectedTag.type in enumMap && enumMap[selectedTag.type as keyof typeof enumMap];
|
||||
|
||||
const [dropDownToggle, setDropDownToggle] = useState<DROPDOWNTOGGLE | null>(null);
|
||||
const [decimalPlace, setDecimalPlace] = useState<number>(2)
|
||||
const [styleOpen, setStyleOpen] = useState(false);
|
||||
|
||||
const handlePropertyChange = (changeTo: string, changeWith: string | boolean | number, is24Hrs=null) => {
|
||||
console.log("Handle Property Change Called", "changeTo", changeTo, "changeWith", changeWith)
|
||||
if (changeTo === '' || changeWith === '') return
|
||||
|
||||
if (changeTo === "subType" && (changeWith === TEMPORAL.DATE || changeWith === TEMPORAL.DATE_TIME || changeWith === TEMPORAL.TIME)) {
|
||||
// let change: string = changeWith;
|
||||
// if (change === "DATE TIME") {
|
||||
// change = "DATE_TIME"
|
||||
// }
|
||||
setDroppedItems((prev) => (
|
||||
{
|
||||
...prev,
|
||||
[selTagKey]: Array.isArray(prev[selTagKey]) // Ensure it's an array
|
||||
? prev[selTagKey].map((item, i) =>
|
||||
i === selTagIndx ? { ...item, [changeTo]: changeWith || "", format: "", update: true } : item
|
||||
)
|
||||
: [],
|
||||
}// Provide a fallback in case it's undefined or not an array
|
||||
));
|
||||
} else if (changeTo === "subType" && typeof changeWith === "string" && changeWith.toLowerCase() === "password") {
|
||||
console.log("Line 161")
|
||||
setDroppedItems((prev) => (
|
||||
{
|
||||
...prev,
|
||||
[selTagKey]: Array.isArray(prev[selTagKey])
|
||||
? prev[selTagKey].map((item, i) =>
|
||||
i === selTagIndx ? { ...item, [changeTo]: changeWith, maskType: "All", maskCharacter: "ASTERISK", update: true } : item
|
||||
)
|
||||
: [],
|
||||
}
|
||||
));
|
||||
}
|
||||
else if (changeTo === "subType" && (changeWith === NUMBER.CURRENCY || changeWith === NUMBER.INTEGER || changeWith === NUMBER.DECIMAL)) {
|
||||
let decPlace = changeWith !== NUMBER.DECIMAL ? 0 : decimalPlace;
|
||||
const isCurrency = changeWith === NUMBER.CURRENCY;
|
||||
// const currencyType = null
|
||||
|
||||
setDroppedItems((prev) => (
|
||||
{
|
||||
...prev,
|
||||
[selTagKey]: Array.isArray(prev[selTagKey]) // Ensure it's an array
|
||||
? prev[selTagKey].map((item, i) =>
|
||||
i === selTagIndx ? { ...item, [changeTo]: changeWith, decimalPlace: decPlace, isCurrency, update: true } : item
|
||||
)
|
||||
: [],
|
||||
}// Provide a fallback in case it's undefined or not an array
|
||||
));
|
||||
|
||||
} else if (changeTo === "format" && selectedTag.subType === TEMPORAL.DATE_TIME) {
|
||||
let val = timeFormats[0].format;
|
||||
if (!is24Hrs) {
|
||||
val = timeFormats[1].format
|
||||
}
|
||||
setDroppedItems((prev) => (
|
||||
{
|
||||
...prev,
|
||||
[selTagKey]: Array.isArray(prev[selTagKey]) // Ensure it's an array
|
||||
? prev[selTagKey].map((item, i) =>
|
||||
i === selTagIndx ? { ...item, [changeTo]: changeWith + " " + val, update: true } : item
|
||||
)
|
||||
: [],
|
||||
}// Provide a fallback in case it's undefined or not an array
|
||||
));
|
||||
|
||||
} else {
|
||||
setDroppedItems((prev) => (
|
||||
{
|
||||
...prev,
|
||||
[selTagKey]: Array.isArray(prev[selTagKey]) // Ensure it's an array
|
||||
? prev[selTagKey].map((item, i) =>
|
||||
i === selTagIndx ? { ...item, [changeTo]: changeWith, update: true } : item
|
||||
)
|
||||
: [],
|
||||
}// Provide a fallback in case it's undefined or not an array
|
||||
));
|
||||
}
|
||||
setDropDownToggle(null)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedTag.subType === TEMPORAL.DATE || selectedTag.subType === TEMPORAL.DATE_TIME || selectedTag.subType === TEMPORAL.TIME) {
|
||||
|
||||
if (selectedTag.subType === TEMPORAL.DATE) {
|
||||
handlePropertyChange("format", dateFormats[0].format)
|
||||
}
|
||||
else if (selectedTag.subType === TEMPORAL.DATE_TIME) {
|
||||
handlePropertyChange("format", dateTimeFormats[0].format)
|
||||
}
|
||||
else if (selectedTag.subType === TEMPORAL.TIME) {
|
||||
handlePropertyChange("format", timeFormats[0].format)
|
||||
}
|
||||
}
|
||||
}, [selectedTag.subType])
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedTag.label === "temporal") {
|
||||
handlePropertyChange("subType", TEMPORAL.DATE);
|
||||
handlePropertyChange("format", "DD/MM/YY");
|
||||
}
|
||||
}, [])
|
||||
|
||||
const handleDecimalPlace = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const val = Number(e.target.value)
|
||||
setDecimalPlace(val)
|
||||
handlePropertyChange("decimalPlace", val)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if ("styles" in selectedTag) {
|
||||
const fontSize = selectedTag?.styles?.textSize;
|
||||
const tagHeight = selectedTag?.dimensions?.height - 18;
|
||||
|
||||
if (selectedTag.subType !== TEXT.PASSWORD && selectedTag.subType !== TEXT.PARAGRAPH && tagHeight > (fontSize + fontSize)) {
|
||||
handlePropertyChange("subType", TEXT.PARAGRAPH)
|
||||
} else if (selectedTag.subType !== TEXT.PASSWORD && selectedTag.subType !== TEXT.SINGLE_LINE && tagHeight <= (fontSize + fontSize)) {
|
||||
console.log("Change subType Called from elseif")
|
||||
handlePropertyChange("subType", TEXT.SINGLE_LINE)
|
||||
}
|
||||
}
|
||||
}, [selectedTag])
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Right Side Bar Start */}
|
||||
<div className='col-span-2 w-full h-full bg-white text-sm'>
|
||||
<p className="p-2 font-semibold text-md">Properties</p>
|
||||
<hr className="text-slate-200" />
|
||||
|
||||
<div className="p-3 text-sm text-slate-600 flex flex-col gap-2">
|
||||
|
||||
{
|
||||
<RecipientsAttrCon selectedRecipientId={selectedTag.recipientId} handlePropertyChange={handlePropertyChange} />
|
||||
}
|
||||
|
||||
{selectedTag.label &&
|
||||
<LabelAttr label={selectedTag.label} handlePropertyChange={handlePropertyChange} />}
|
||||
|
||||
{(selectedTag.type !== TagsTypes.SIGNATURE && selectedTag.type !== TagsTypes.INITIALS) &&
|
||||
<RequiredAttr required={selectedTag.required ? selectedTag.required : false} handlePropertyChange={handlePropertyChange} />}
|
||||
|
||||
{selectedTag.type.toLowerCase() === TagsTypes.TEMPORAL &&
|
||||
<CurrTimeStampAttr type={selectedTag.type} handlePropertyChange={handlePropertyChange} />}
|
||||
|
||||
{
|
||||
selectedType && Object.keys(selectedType).length > 0 &&
|
||||
<CommonAttrDropDown
|
||||
selectedType={selectedType}
|
||||
subType={selectedTag.subType}
|
||||
dropDownToggle={dropDownToggle}
|
||||
setDropDownToggle={setDropDownToggle}
|
||||
handlePropertyChange={handlePropertyChange} />
|
||||
}
|
||||
|
||||
{/* Mask Type */}
|
||||
{
|
||||
selectedTag?.subType === TEXT.PASSWORD &&
|
||||
<MaskTypePassAttr
|
||||
maskType={selectedTag.maskType ? selectedTag.maskType : MASKTYPE.ALL}
|
||||
maskCharacter={selectedTag.maskCharacter ? selectedTag.maskCharacter : MASKCHARACTER.ASTERISK}
|
||||
dropDownToggle={dropDownToggle}
|
||||
setDropDownToggle={setDropDownToggle}
|
||||
handlePropertyChange={handlePropertyChange} />
|
||||
}
|
||||
|
||||
|
||||
{/* TEMPORAL DATE FORMAT - START */}
|
||||
{
|
||||
(selectedTag?.subType === TEMPORAL.DATE ||
|
||||
selectedTag?.subType === TEMPORAL.TIME ||
|
||||
selectedTag?.subType === TEMPORAL.DATE_TIME) &&
|
||||
<TemporalDateAttr
|
||||
subType={selectedTag.subType}
|
||||
format={selectedTag.format}
|
||||
dropDownToggle={dropDownToggle}
|
||||
setDropDownToggle={setDropDownToggle}
|
||||
handlePropertyChange={handlePropertyChange} />
|
||||
}
|
||||
{/* TEMPORAL DATE FORMAT - END */}
|
||||
|
||||
{/* NUMBER - DECIMAL PLACES */}
|
||||
{
|
||||
selectedTag?.subType === NUMBER.DECIMAL &&
|
||||
<div>
|
||||
<label htmlFor="" className="">Decimal Places</label>
|
||||
<input
|
||||
type="number"
|
||||
onChange={(e) => handleDecimalPlace(e)}
|
||||
value={decimalPlace}
|
||||
className="bg-slate-100 w-full outline-none p-2 rounded" />
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
(selectedTag?.subType === SELECT.SINGLE_SELECT || selectedTag?.subType === SELECT.MULTI_SELECT) &&
|
||||
<SelectTagAttr
|
||||
options={selectedTag.options}
|
||||
selTagKey={selTagKey}
|
||||
selTagIndx={selTagIndx}
|
||||
setDroppedItems={setDroppedItems}
|
||||
handlePropertyChange={handlePropertyChange} />
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
selectedTag.type === TagsTypes.TEXT &&
|
||||
<MaxMinLenAttr maxLength={selectedTag.maxLength} minLength={selectedTag.minLength} />
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
<div className="">
|
||||
<div className="flex items-center justify-between mr-2 cursor-pointer"
|
||||
onClick={() => setStyleOpen(!styleOpen)}
|
||||
>
|
||||
<label
|
||||
className="block mb-2">Styles</label>
|
||||
<IoIosArrowDown className={`${styleOpen ? "rotate-[-90deg]" : ""} transition-all`} />
|
||||
</div>
|
||||
{
|
||||
styleOpen && <>
|
||||
{/* Font */}
|
||||
<div className="mb-2">
|
||||
<label className="mr-2">Font</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="e.g. Arial"
|
||||
className="outline-none border-1 rounded px-2 py-1 border-slate-200"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Text Size */}
|
||||
<div className="mb-2">
|
||||
<label className="mr-2">Text Size</label>
|
||||
<input
|
||||
// value={}
|
||||
type="number"
|
||||
className="outline-none border-1 rounded px-2 py-1 border-slate-200"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Color */}
|
||||
<div className="mb-2">
|
||||
<label className="mr-2">Color</label>
|
||||
<input
|
||||
type="color"
|
||||
className="outline-none border-1 rounded px-2 py-1 border-slate-200 w-10 h-8"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Toggles for Bold, Italic, Underline */}
|
||||
<div className="flex gap-4 items-center mt-2">
|
||||
<label className="flex gap-1 items-center">
|
||||
<input type="checkbox" />
|
||||
Bold
|
||||
</label>
|
||||
<label className="flex gap-1 items-center">
|
||||
<input type="checkbox" />
|
||||
Italic
|
||||
</label>
|
||||
<label className="flex gap-1 items-center">
|
||||
<input type="checkbox" />
|
||||
Underline
|
||||
</label>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{/* Right Side Bar End */}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default RightSideBar
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
import { useState } from "react";
|
||||
import { DROPDOWNTOGGLE } from "./RightSideBar";
|
||||
import { DroppedItemsObj } from "../DocumentContainer";
|
||||
import { IoMdClose } from "react-icons/io";
|
||||
|
||||
interface SelectTagAttrInt {
|
||||
options: string[] | undefined;
|
||||
selTagKey: string;
|
||||
selTagIndx: number;
|
||||
setDroppedItems: React.Dispatch<React.SetStateAction<DroppedItemsObj>>;
|
||||
handlePropertyChange: (changeTo: string, changeWith: string | boolean | number) => void;
|
||||
}
|
||||
|
||||
const SelectTagAttr: React.FC<SelectTagAttrInt> = ({ options, selTagKey, selTagIndx, setDroppedItems, handlePropertyChange }) => {
|
||||
const [selectedOption, setSelectedOption] = useState<string>()
|
||||
|
||||
const handleAddSelectOption = () => {
|
||||
if (selectedOption && selectedOption.length) {
|
||||
setDroppedItems((prev) => (
|
||||
{
|
||||
...prev,
|
||||
[selTagKey]: Array.isArray(prev[selTagKey])
|
||||
? prev[selTagKey].map((item, i) => {
|
||||
if (i === selTagIndx) {
|
||||
return { ...item, options: item.options ? [...item.options, selectedOption] : [selectedOption], update: true };
|
||||
}
|
||||
return item;
|
||||
})
|
||||
: [],
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
const handleSelectOptionDel = (indx: number) => {
|
||||
setDroppedItems((prev) => (
|
||||
{
|
||||
...prev,
|
||||
[selTagKey]: Array.isArray(prev[selTagKey])
|
||||
? prev[selTagKey].map((item, i) => {
|
||||
if (i === selTagIndx) {
|
||||
return { ...item, options: item.options ? item.options.filter((_, i) => i !== indx) : [] };
|
||||
}
|
||||
return item;
|
||||
})
|
||||
: [],
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<label htmlFor="" className="">Add Options</label>
|
||||
<input
|
||||
type="text"
|
||||
onChange={(e) => setSelectedOption(e.target.value)}
|
||||
value={selectedOption}
|
||||
onKeyUp={(e) => {
|
||||
if (e.code === "Enter") {
|
||||
// if (selectedOption) {
|
||||
// setSelectedOptions((prev) => [...prev, selectedOption]);
|
||||
// setSelectedOption("");
|
||||
// }
|
||||
handleAddSelectOption()
|
||||
}
|
||||
}}
|
||||
className="bg-slate-100 w-full outline-none p-2 rounded" />
|
||||
|
||||
<div className="h-[150px] mt-1 overflow-hidden overflow-y-auto">
|
||||
{
|
||||
options && options.map((val, indx) => (
|
||||
<div
|
||||
key={indx}
|
||||
className="flex justify-between items-center px-2 py-1 my-1 rounded bg-slate-100">
|
||||
<p>{val}</p>
|
||||
<IoMdClose
|
||||
onClick={() =>
|
||||
// setSelectedOptions(prev =>
|
||||
// prev.filter((_, i) => i !== indx)
|
||||
// )
|
||||
handleSelectOptionDel(indx)
|
||||
}
|
||||
className="cursor-pointer text-slate-500 hover:text-slate-600" />
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
export default SelectTagAttr
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import { dateFormats, dateTimeFormats, monthFormats, timeFormats, weekFormats, yearFormats } from "../../../../utlity/dateTimeFormats";
|
||||
import { DROPDOWNTOGGLE, TEMPORAL } from "./RightSideBar";
|
||||
import { MdKeyboardArrowDown } from "react-icons/md";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
const dateTimeFormatMap = {
|
||||
"date": dateFormats,
|
||||
"time": timeFormats,
|
||||
"date_time": dateTimeFormats,
|
||||
"year": yearFormats,
|
||||
"month": monthFormats,
|
||||
"week": weekFormats
|
||||
}
|
||||
|
||||
interface TemporalDateAttrInt {
|
||||
subType: string;
|
||||
format: string | undefined;
|
||||
dropDownToggle: DROPDOWNTOGGLE | null;
|
||||
setDropDownToggle: React.Dispatch<React.SetStateAction<DROPDOWNTOGGLE | null>>;
|
||||
handlePropertyChange: (changeTo: string, changeWith: string | boolean | number, is24Hrs: boolean) => void;
|
||||
}
|
||||
|
||||
const TemporalDateAttr: React.FC<TemporalDateAttrInt> = ({ subType, format, dropDownToggle, setDropDownToggle, handlePropertyChange }) => {
|
||||
const [is24Hrs, setIs24Hrs] = useState<boolean>(true);
|
||||
|
||||
const handleIs24HrsClick = (checked: boolean) => {
|
||||
if (subType === TEMPORAL.TIME) {
|
||||
if (!checked) {
|
||||
handlePropertyChange("format", timeFormats[1].format, is24Hrs)
|
||||
} else {
|
||||
handlePropertyChange("format", timeFormats[0].format, is24Hrs)
|
||||
}
|
||||
}
|
||||
setIs24Hrs(checked)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (format === timeFormats[1].format && is24Hrs) {
|
||||
setIs24Hrs(false);
|
||||
} else if (format === timeFormats[0].format && !is24Hrs) {
|
||||
setIs24Hrs(true);
|
||||
}
|
||||
}, [format])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="flex justify-between">
|
||||
<label htmlFor="" className="">Formats</label>
|
||||
{(subType === TEMPORAL.DATE_TIME || subType === TEMPORAL.TIME) &&
|
||||
<div className="flex justify-center items-center gap-1.5">
|
||||
<input
|
||||
checked={is24Hrs ? is24Hrs : false}
|
||||
onChange={(e) => handleIs24HrsClick(e.target.checked)}
|
||||
id="data_time_format"
|
||||
type="checkbox" />
|
||||
<label className={`text-xs ${is24Hrs ? "text-slate-600" : "text-slate-400"} transitions-all duration-150`} htmlFor="data_time_format">
|
||||
24 Hrs
|
||||
</label>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div
|
||||
onClick={() => setDropDownToggle(dropDownToggle === DROPDOWNTOGGLE.DDMMYY_FORMAT ? null : DROPDOWNTOGGLE.DDMMYY_FORMAT)}
|
||||
className="flex justify-between items-center border-1 rounded px-2 py-1 border-slate-200">
|
||||
<p className="cursor-pointer py-1">
|
||||
{format ? format : dateTimeFormatMap['date'][0].format}
|
||||
{/* {(subType !== TEMPORAL.DATE && subType !== TEMPORAL.TIME) ? (is24Hrs ? " " + timeFormats[0].format : " " + timeFormats[1].format) : ""} */}
|
||||
</p>
|
||||
<MdKeyboardArrowDown />
|
||||
</div>
|
||||
|
||||
{
|
||||
dropDownToggle === DROPDOWNTOGGLE.DDMMYY_FORMAT &&
|
||||
<div className="shadow bg-slate-100 mt-1 border-[1px] max-h-[200px] overflow-y-auto border-slate-100 rounded">
|
||||
{dateTimeFormatMap[subType].map((valObj, indx) => {
|
||||
// let val = showFormatEg ? valObj["example"] : valObj["format"]
|
||||
let val = valObj["format"]
|
||||
if (subType === TEMPORAL.DATE_TIME) {
|
||||
if (is24Hrs) {
|
||||
val = val + " " + timeFormats[0].format;
|
||||
} else {
|
||||
val = val + " " + timeFormats[1].format;
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div
|
||||
key={indx}
|
||||
onClick={() => handlePropertyChange("format", valObj["format"])}
|
||||
className="px-2 py-1 hover:bg-slate-200 cursor-pointer"
|
||||
>
|
||||
{val}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
|
||||
{format && <div className="pt-4">
|
||||
<p className="text-center">{dayjs().format(format)}</p>
|
||||
</div>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default TemporalDateAttr
|
||||
|
|
@ -28,7 +28,6 @@ api.interceptors.response.use(
|
|||
async error => {
|
||||
const originalRequest = error.config;
|
||||
// Prevent multiple refresh attempts
|
||||
// if (error.response?.status === 401 || error.response?.status === 500) {
|
||||
if (error.response?.status === 401) {
|
||||
originalRequest._retry = true;
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ const documentSlice = createSlice({
|
|||
})
|
||||
.addCase(fetchDocuments.fulfilled, (state, action: PayloadAction<Document[]>) => {
|
||||
state.loading = false;
|
||||
console.log(action.payload, "action.payload")
|
||||
state.documents = action.payload;
|
||||
})
|
||||
.addCase(fetchDocuments.rejected, (state, action) => {
|
||||
|
|
|
|||
|
|
@ -180,9 +180,10 @@ const selectedRecipientsSlice = createSlice({
|
|||
extraReducers: (builder) => {
|
||||
builder
|
||||
.addCase(fetchRecipients.pending, (state) => {
|
||||
console.log("Fetching recipients...");
|
||||
})
|
||||
.addCase(fetchRecipients.fulfilled, (state, action: PayloadAction<Recipient[]>) => {
|
||||
// console.log("Fetched recipients successfully:", action.payload);
|
||||
console.log("Fetched recipients successfully:", action.payload);
|
||||
|
||||
// Assign colors to recipients
|
||||
const assignedRecipients = action.payload.map((recipient, index) => ({
|
||||
|
|
@ -208,7 +209,7 @@ const selectedRecipientsSlice = createSlice({
|
|||
|
||||
|
||||
.addCase(addRecipientAsync.pending, (state) => {
|
||||
|
||||
console.log("Fetching recipients...");
|
||||
})
|
||||
.addCase(addRecipientAsync.fulfilled, (state, action: PayloadAction<Recipient>) => {
|
||||
console.log("Added recipient successfully:", action.payload);
|
||||
|
|
|
|||
|
|
@ -79,41 +79,3 @@ export interface AccountData {
|
|||
role: UserRole;
|
||||
status: AccountStatus;
|
||||
}
|
||||
|
||||
export interface TagsProperties {
|
||||
"editable": boolean;
|
||||
"required": boolean;
|
||||
"navigationOrder": number;
|
||||
"type": string;
|
||||
"lastName"?: boolean;
|
||||
"firstName"?: boolean;
|
||||
"maxLength"?: number;
|
||||
"minLength"?: number;
|
||||
"readOnly"?: boolean;
|
||||
"multiLine"?: boolean;
|
||||
"regex"?: string[];
|
||||
"format"?: string;
|
||||
"dateFormat"?: string;
|
||||
"currentTimeStamp"?: boolean;
|
||||
"decimalPlace"?: number;
|
||||
"multiSelect"?: boolean;
|
||||
}
|
||||
|
||||
|
||||
export enum TagsTypes {
|
||||
TEXT= "text",
|
||||
SIGNATURE= "signature",
|
||||
INITIALS= "initials",
|
||||
TEMPORAL= "temporal",
|
||||
NUMBER= "number",
|
||||
IMAGE= "image",
|
||||
STAMP= "stamp",
|
||||
CHECKBOX= "checkbox",
|
||||
SELECT= "select",
|
||||
FILE= "file",
|
||||
ATTACHMENT= "attachment",
|
||||
RADIO= "radio",
|
||||
EMAIL= "email",
|
||||
NAME= "name",
|
||||
COMPANY= "company",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ export default defineConfig({
|
|||
allowedHosts: [
|
||||
'quality-friendly-goldfish.ngrok-free.app',
|
||||
'officially-powerful-goat.ngrok-free.app',
|
||||
'89f0-49-36-189-120.ngrok-free.app',
|
||||
'c8ee-49-36-191-130.ngrok-free.app'
|
||||
'89f0-49-36-189-120.ngrok-free.app'
|
||||
],
|
||||
},
|
||||
build: {
|
||||
|
|
|
|||
Loading…
Reference in New Issue