diff --git a/src/App.tsx b/src/App.tsx index 045023e..0486a18 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -94,7 +94,8 @@ const App = () => { {/* Links work wothout Login */} } /> } /> - } /> + } /> + } /> } /> {/* Links work wothout Login */} diff --git a/src/components/client/SignCompletionScreen.tsx b/src/components/client/SignCompletionScreen.tsx new file mode 100644 index 0000000..e4c9f5d --- /dev/null +++ b/src/components/client/SignCompletionScreen.tsx @@ -0,0 +1,380 @@ +import React, { useState, useEffect } from 'react'; +import { + FiDownload, + FiCheckCircle, + FiZap, + FiShield, + FiClock, + FiFileText, + FiX, +} from 'react-icons/fi'; +import { IoMdArrowRoundBack } from 'react-icons/io'; +import { useParams } from 'react-router-dom'; +import { SignTypeEnum } from '../../utlity/types'; + +const SignCompletionScreen: React.FC = () => { + const { signType } = useParams(); + const [showDownloadModal, setShowDownloadModal] = useState(false); + const [animationPhase, setAnimationPhase] = useState(0); + + useEffect(() => { + // Trigger animation phases sequentially + const timers = [ + setTimeout(() => setAnimationPhase(1), 200), + setTimeout(() => setAnimationPhase(2), 800), + setTimeout(() => setAnimationPhase(3), 1400), + setTimeout(() => setAnimationPhase(4), 2000), + ]; + + return () => timers.forEach(clearTimeout); + }, []); + + const handleDownload = (format: string) => { + console.log(`Downloading document in ${format} format`); + const content = `Signed document - ${new Date().toISOString()}`; + const blob = new Blob([content], { type: 'text/plain' }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = `signed-document.${format.toLowerCase()}`; + a.click(); + URL.revokeObjectURL(url); + }; + + return ( +
+ + + {/* Floating Particles Background */} +
+
+
+
+
+
+
+
+ + {/* Main Completion Screen */} +
+
+ + {/* Success Icon */} +
+
+ +
+ + +
+ + {/* Main Success Message */} +
= 1 ? 'fade-in-up' : ''}`}> +

+ Signature Complete! +

+

+ Your document has been successfully signed. +

+
+ + {/* Action Buttons */} +
+ + {signType === SignTypeEnum.selfSign ? + {/* */} + + Back Sign Made Easy + {/* */} + : + + {/* */} + + Visit Sign Made Easy + {/* */} + + } +
+ + {/* Additional Info */} +
+

+ Your document is signed and ready. You can download it or return to the sign made easy. +

+
+
+
+ + {/* Premium Download Modal */} + {/* {showDownloadModal && ( +
+
+ + +
+
+ +
+

Choose Download Format

+

Select your preferred file format

+
+ +
+ + + +
+ +
+

+ Files are automatically encrypted and timestamped +

+
+
+
+ )} */} +
+ ); +}; + +export default SignCompletionScreen; \ No newline at end of file diff --git a/src/components/client/SignDocument.tsx b/src/components/client/SignDocument.tsx index 076c84c..ce5e317 100644 --- a/src/components/client/SignDocument.tsx +++ b/src/components/client/SignDocument.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from "react"; import axios from "axios" import { RootState } from "../../store/store"; -import { useParams } from "react-router-dom" +import { useNavigate, useParams } from "react-router-dom" import { DroppedItem, DroppedItemsObj, TagsTypes } from "../../utlity/types"; import Loader from "../dashboard/Loader"; @@ -24,6 +24,7 @@ import DocumentPages from "./DocumentPages"; import FieldList from "../process/processStepTwo/FieldList"; import typeToIconMap from "../../helper/iconMap"; import { droppedTagsDefaultField } from "../process/processStepTwo/DocumentContainer"; +import SignCompletionScreen from "./SignCompletionScreen"; @@ -173,6 +174,7 @@ const SignDocument = () => { const [transparentTags, setTransparentTags] = useState(false); const [provideTags, setProvideTags] = useState(false) + const [showCompletionScreen, setShowCompletionScreen] = useState(false) const [saved, setSaved] = useState({ saveType: null, @@ -181,6 +183,7 @@ const SignDocument = () => { initial: null, }); + const navigate = useNavigate(); const [signConfObj, setSignConfObj] = useState({}); @@ -314,6 +317,10 @@ const SignDocument = () => { setProvideTags(true) } + if (res.data.status ==="COMPLETED" ) { + setShowCompletionScreen(true) + } + setTimeout(() => { dispatch(hideLoader()); }, 600); @@ -466,7 +473,10 @@ const SignDocument = () => { theme: "light", transition: Bounce, }); + // Completion Sign Screen Modal and download file + setShowCompletionScreen(true) }, 800) + } }) .catch((err) => { @@ -766,7 +776,7 @@ const SignDocument = () => {
<> {/* */} - + {showCompletionScreen && }
) => handleFormSubmit(e)} > @@ -1329,6 +1339,9 @@ const SignDocument = () => {
+ + + {/* */} diff --git a/src/components/home/Cards.tsx b/src/components/home/Cards.tsx index 7ce4bcf..94184ec 100644 --- a/src/components/home/Cards.tsx +++ b/src/components/home/Cards.tsx @@ -231,7 +231,7 @@ const Cards: React.FC = ({ type = 'dashboard', onOpenModal, onDateRa : -
+
{cards.map((card, index) => (
{ try { const res = await api.put(`/api/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}`, { status: "SENT" }) console.log(res, "Check123"); - navigate(`/sign/${recipientId}`); + navigate(`/sign/${recipientId}/self_sign`); } catch (err) { console.log("Error Transaction Sent", err.message); } diff --git a/src/components/process/processStepTwo/DocumentContainer.tsx b/src/components/process/processStepTwo/DocumentContainer.tsx index 22f1b3a..5663c1a 100644 --- a/src/components/process/processStepTwo/DocumentContainer.tsx +++ b/src/components/process/processStepTwo/DocumentContainer.tsx @@ -40,11 +40,13 @@ export const droppedTagsDefaultField: DroppedTagsDefaultFieldType = { } interface DocumentContainerProps { + transactionSaving: boolean; + setTransactionSaving: React.Dispatch>; isSend: boolean | null; setIsSend: React.Dispatch>; } -const DocumentContainer: React.FC = ({ isSend }) => { +const DocumentContainer: React.FC = ({ transactionSaving, setTransactionSaving, isSend }) => { let transactionTemplateToggle = TRANSACTION_TEMPLATE_TOGGLE.TRANSACTIONS; const dispatch = useDispatch(); const params = useParams<{ accountId?: string; transactionId?: string; templateId?: string }>(); @@ -75,8 +77,6 @@ const DocumentContainer: React.FC = ({ isSend }) => { selectedDocuments.length === 0 && dispatch(fetchDocuments({ accountId, transactionId })); }, []) - console.log(droppedItems, "line 78") - // FETCHING TAG - START useEffect(() => { if (selectedRecipients.length === 0) return; @@ -165,8 +165,8 @@ const DocumentContainer: React.FC = ({ isSend }) => { updatedData[recipientId] = updateTags } - - const requests = Object.entries(updatedData).map(([recipientId, tags]) => { + const requests = Object.entries(updatedData).filter(([recipientId, tags]) => { + if (tags.length === 0) return false; return api.put( `/api/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}/recipients/${recipientId}/tags`, tags @@ -192,7 +192,7 @@ const DocumentContainer: React.FC = ({ isSend }) => { const handleTransactionProcess = async (save: boolean = false) => { console.log(droppedItems, "called Line 189"); - + if (Object.keys(droppedItems).length === 0) return; if (!save && isSend === null) return; !save && dispatch(showLoader("Loading ...")) @@ -293,28 +293,21 @@ const DocumentContainer: React.FC = ({ isSend }) => { } } - // for(const recipient of selectedRecipients) { - // const recrecipient - // } - - tagsData = groupByRecipientId(tagsData); - console.log(tagsData, "Line 302"); + + console.log("Hefre is the line 299", tagsData); await sendTagsToRecipients(tagsData, accountId, transactionId); - // SENDING Transaction - START - // if (!save) { - // const res = await api.put(`/api/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}`, { status: "SENT" }) - // // const res = await api.put(`/api/accounts/${accountId}/transactions/${transactionId}`, { status: "SENT" }) - // console.log(res, "Check123") - // dispatch(hideLoader()) - // } - + if (!save) { + const res = await api.put(`/api/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}`, { status: "SENT" }) + // const res = await api.put(`/api/accounts/${accountId}/transactions/${transactionId}`, { status: "SENT" }) + console.log(res, "Check123") + dispatch(hideLoader()) + } // SENDING Transaction - END - } // Save Tags - START @@ -323,13 +316,24 @@ const DocumentContainer: React.FC = ({ isSend }) => { }, [isSend]) // Save Tags - END - // useEffect(() => { - // setTimeout(() => { - // setInterval(async () => { - // await handleTransactionProcess(true); - // }, 8000) - // }, 8000) - // }, []) + useEffect(() => { + // setTimeout(() => { + const interval = setInterval(async () => { + // debugger + setTransactionSaving(true) + handleTransactionProcess(true); + }, 8000) + // }, 8000) + return () => clearInterval(interval); + }, [droppedItems]) + + useEffect(() => { + if (transactionSaving) { + setTimeout(() => { + setTransactionSaving(false) + }, 1000) + } + }, [transactionSaving]) const handleDragOver = (event: React.DragEvent) => { event.preventDefault(); // Allows the drop event to work @@ -1020,6 +1024,8 @@ const DocumentContainer: React.FC = ({ isSend }) => { }); }; + console.log(droppedItems, "Line 1022") + return ( <> {/* Center Doc Container - START */} @@ -1177,9 +1183,9 @@ const DocumentContainer: React.FC = ({ isSend }) => {
- { - console.log(selectedTag, droppedItems, "Line 1175") - } + { + console.log(selectedTag, droppedItems, "Line 1175") + } {selectedTag && selectedTag !== null && "key" in selectedTag && "index" in selectedTag && > isFields: boolean; setIsFields: React.Dispatch> isSend: boolean | null; @@ -45,7 +47,7 @@ const fitObj = [ }, ] -const NavTwo: React.FC = ({ isFields, setIsFields, isSend, setIsSend }) => { +const NavTwo: React.FC = ({ transactionSaving, isFields, setIsFields, isSend, setIsSend }) => { let transactionTemplateToggle = TRANSACTION_TEMPLATE_TOGGLE.TRANSACTIONS; const dispatch = useDispatch(); const params = useParams<{ accountId?: string; transactionId?: string; templateId?: string }>(); @@ -61,7 +63,7 @@ const NavTwo: React.FC = ({ isFields, setIsFields, isSend, setIsSen return null; } - const [transactionSaving, setTransactionSaving] = useState(false); + // const [transactionSaving, setTransactionSaving] = useState(false); const [dotCount, setDotCount] = useState(0); const [isFitDd, setIsFitDd] = useState(false) diff --git a/src/components/process/processStepTwo/ProcessStepTwo.tsx b/src/components/process/processStepTwo/ProcessStepTwo.tsx index 9c47219..58043dd 100644 --- a/src/components/process/processStepTwo/ProcessStepTwo.tsx +++ b/src/components/process/processStepTwo/ProcessStepTwo.tsx @@ -8,6 +8,7 @@ import { useDispatch, useSelector } from 'react-redux'; import { RootState } from '../../../store/store'; import Loader from '../../dashboard/Loader'; import { hideLoader } from '../../../store/slices/loaderSlice'; +import { useNavigate } from 'react-router-dom'; export interface IsSendInterface { send: boolean | null; @@ -15,13 +16,16 @@ export interface IsSendInterface { } const ProcessStepTwo = () => { - + const [isFields, setIsFields] = useState(true); const [selectedRecipient, setSelectedRecipient] = useState(0); + const [transactionSaving, setTransactionSaving] = useState(false); + const [isSend, setIsSend] = useState(null); const globalLoader = useSelector((state: RootState) => state.loader) const dispatch = useDispatch(); + const navigate = useNavigate(); useEffect(() => { setTimeout(() => { @@ -29,13 +33,14 @@ const ProcessStepTwo = () => { }, 800) }, []) + return (
- +
- +
{globalLoader.isLoading && } diff --git a/src/index.css b/src/index.css index e9927b4..6375973 100644 --- a/src/index.css +++ b/src/index.css @@ -60,6 +60,23 @@ touch-action: none; } +@keyframes slowPing { + 0% { + transform: scale(1); + opacity: 1; + } + 75%, 100% { + transform: scale(2.2); + opacity: 0; + } +} + +.custom-ping { + animation: slowPing 2.5s cubic-bezier(0.4, 0, 0.2, 1) infinite; + transition: transform 0.3s ease-in-out, opacity 0.3s ease-in-out; +} + + canvas { touch-action: none; -ms-touch-action: none;