From cb3233d63ca2295dce6cf2b2c62b0cc54a37cb38 Mon Sep 17 00:00:00 2001
From: Amit Sharma <coutamit.s19@gmail.com>
Date: Fri, 10 Mar 2023 12:33:35 +0000
Subject: [PATCH] Changed form config Added JSON/XML switch Animations, etc

---
 apps/wrapper/src/App.js                       |  6 +-
 .../src/components/GenericForm/index.js       | 42 ++++++++++-
 .../components/GenericForm/index.module.css   | 73 ++++++++++++++++++-
 apps/wrapper/src/index.js                     |  1 +
 apps/wrapper/src/workflow_first.json          | 17 ++++-
 5 files changed, 130 insertions(+), 9 deletions(-)

diff --git a/apps/wrapper/src/App.js b/apps/wrapper/src/App.js
index c68be45..b30a5ef 100644
--- a/apps/wrapper/src/App.js
+++ b/apps/wrapper/src/App.js
@@ -29,10 +29,10 @@ function App() {
       <div className='container'>
         {!Object.keys(selectedFlow).length ?
           <>
-            <div className='heading'>Workflow Demo App</div>
-            <div className='subtitle'>Please select one of the flows</div>
+            <div className='heading animate__animated animate__fadeInDown'>Workflow Demo App</div>
+            <div className='subtitle animate__animated animate__fadeInDown'>Please select one of the flows</div>
             <div className='btnContainer'>
-              {flows?.map(el => <div className='workflowBtns' onClick={() => setSelectedFlow(el)}>{el.name}</div>)}
+              {flows?.map(el => <div className='workflowBtns animate__animated animate__fadeIn' onClick={() => setSelectedFlow(el)}>{el.name}</div>)}
             </div>
           </>
           : <GenericForm {...{ selectedFlow, setSelectedFlow }} />
diff --git a/apps/wrapper/src/components/GenericForm/index.js b/apps/wrapper/src/components/GenericForm/index.js
index ae4d89d..dcdc823 100644
--- a/apps/wrapper/src/components/GenericForm/index.js
+++ b/apps/wrapper/src/components/GenericForm/index.js
@@ -8,6 +8,9 @@ const GenericForm = (props) => {
   const { selectedFlow, setSelectedFlow } = props;
   const formSpec = require(`../../${selectedFlow.config}`);
   const [formData, setFormData] = useState("");
+  const [formDataJson, setFormDataJSON] = useState("");
+  const [isXml, setIsXml] = useState(false);
+
   // Encode string method to URI
   const encodeFunction = (func) => {
     return encodeURIComponent(JSON.stringify(func));
@@ -28,7 +31,7 @@ const GenericForm = (props) => {
 
   useEffect(() => {
     // Manage onNext
-    window.addEventListener('message', function (e) {
+    window.addEventListener('message', async function (e) {
       const data = e.data;
 
       try {
@@ -39,7 +42,11 @@ const GenericForm = (props) => {
         */
         const { nextForm, formData, onSuccessData, onFailureData } = JSON.parse(data);
         console.log({ nextForm, formData, onSuccessData, onFailureData });
-        if (formData) setFormData(beautify(formData))
+        if (formData) {
+          setFormData(beautify(formData))
+          let jsonRes = await parseFormData(formData);
+          if (jsonRes) setFormDataJSON(JSON.stringify(jsonRes.data, null, 2));
+        }
         if (nextForm.type === 'form') {
           setFormId(nextForm.id);
           setOnFormSuccessData(onSuccessData);
@@ -56,6 +63,28 @@ const GenericForm = (props) => {
     });
   }, []);
 
+  const handleFormView = async (e) => {
+    setIsXml(e)
+    if (e) {
+      let jsonRes = await parseFormData(formData);
+      if (jsonRes) setFormDataJSON(JSON.stringify(jsonRes, null, 2));
+    }
+  }
+
+  const parseFormData = async (formData) => {
+    let jsonRes = await fetch(`${GITPOD_URL.slice(0, GITPOD_URL.indexOf('/') + 2) + "3006-" + GITPOD_URL.slice(GITPOD_URL.indexOf('/') + 2)}/parse`, {
+      method: 'POST',
+      body: JSON.stringify({
+        xml: formData,
+      }),
+      headers: {
+        "Content-type": "application/json; charset=UTF-8"
+      },
+    });
+    jsonRes = await jsonRes.json();
+    return jsonRes?.data;
+  }
+
 
   return (
     <div className={styles.container}>
@@ -71,7 +100,14 @@ const GenericForm = (props) => {
           }
         />
         <div className={styles.jsonResponse}>
-          <textarea value={formData} className={styles.formText}>
+          <div className={styles.toggleBtn}>
+            <label class={styles.switch}>
+              <input type="checkbox" value={isXml} onChange={e => handleFormView(e.target.checked)} />
+              <span class={styles.slider}></span>
+            </label>
+            {isXml ? <span className='animate__animated animate__fadeIn'>XML</span> : <span className='animate__animated animate__fadeIn'>JSON</span>}
+          </div>
+          <textarea value={!isXml ? formData : formDataJson} className={styles.formText}>
           </textarea>
         </div>
       </div>
diff --git a/apps/wrapper/src/components/GenericForm/index.module.css b/apps/wrapper/src/components/GenericForm/index.module.css
index 8afda42..bd23cdd 100644
--- a/apps/wrapper/src/components/GenericForm/index.module.css
+++ b/apps/wrapper/src/components/GenericForm/index.module.css
@@ -10,9 +10,9 @@
 }
 
 .header {
-    display:flex;
+    display: flex;
     flex-direction: row;
-    width:94%;
+    width: 94%;
     justify-content: space-between;
     font-size: 3rem;
     color: #ffc119;
@@ -39,6 +39,7 @@
 }
 
 .jsonResponse {
+    position: relative;
     border: 1px solid #efefef;
     width: 45%;
     height: 100%;
@@ -51,4 +52,72 @@
     background: #2b2b2b;
     color: #efefef;
     padding: 1rem;
+}
+
+.switch {
+    position: relative;
+    display: inline-block;
+    width: 3.5rem;
+    height: 1.5rem;
+}
+
+.switch input {
+    opacity: 0;
+    width: 0;
+    height: 0;
+}
+
+
+.slider {
+    position: absolute;
+    cursor: pointer;
+    top: 0;
+    left: 0;
+    right: 0;
+    border-radius: 34px;
+    bottom: 0;
+    background-color: #2b2b2b;
+    border: 1px solid #ffc119;
+    -webkit-transition: .4s;
+    transition: .4s;
+}
+
+.slider:before {
+    position: absolute;
+    content: "";
+    height: 1rem;
+    width: 1rem;
+    left: 4px;
+    bottom: 3px;
+    background-color: white;
+    -webkit-transition: .4s;
+    transition: .4s;
+    border-radius: 50%;
+}
+
+input:checked+.slider {
+    background-color: #ffc119;
+}
+
+input:focus+.slider {
+    box-shadow: 0 0 1px #ffc119;
+}
+
+input:checked+.slider:before {
+    -webkit-transform: translateX(28px);
+    -ms-transform: translateX(28px);
+    transform: translateX(28px);
+}
+
+.toggleBtn {
+    position: absolute;
+    top: 0;
+    right: 0;
+    margin-right: 1rem;
+    margin-top: 1rem;
+    z-index: 1;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    color: #fff;
 }
\ No newline at end of file
diff --git a/apps/wrapper/src/index.js b/apps/wrapper/src/index.js
index d563c0f..907bf1a 100644
--- a/apps/wrapper/src/index.js
+++ b/apps/wrapper/src/index.js
@@ -3,6 +3,7 @@ import ReactDOM from 'react-dom/client';
 import './index.css';
 import App from './App';
 import reportWebVitals from './reportWebVitals';
+import 'animate.css';
 
 const root = ReactDOM.createRoot(document.getElementById('root'));
 root.render(
diff --git a/apps/wrapper/src/workflow_first.json b/apps/wrapper/src/workflow_first.json
index c17e92a..b15ffd5 100644
--- a/apps/wrapper/src/workflow_first.json
+++ b/apps/wrapper/src/workflow_first.json
@@ -2,15 +2,30 @@
   "forms": {
     "jumping_form_1": {
       "skipOnSuccessMessage": true,
+      "prefill": {},
       "submissionURL": "",
+      "successCheck": "async (formData) => { return true; }",
+      "onFailure": {
+        "message": "Form submission failed",
+        "sideEffect": "async (formData) => { console.log(formData); }",
+        "next": {
+          "type": "url",
+          "id": "google"
+        }
+      },
       "name": "Jumping Form First",
       "isSuccess": "async (formData) => { console.log('From isSuccess', formData.getElementsByTagName('reg_no')[0].textContent); return formData.getElementsByTagName('reg_no')[0].textContent === 'registration123'; }",
       "messageOnFailure": "Form submission failed",
       "messageOnSuccess": "Form submitted successfully or Maybe you are already registered",
       "onFormSuccess": "async (formData) => { return JSON.parse(decodeURIComponent('%7B%0A%20%20%20%20%20%20%20%20%22name%22%3A%20%22DEVA%22%2C%0A%20%20%20%20%20%20%20%20%22batch%22%3A%20%222021-2023%22%2C%0A%20%20%20%20%20%20%20%20%22id%22%3A%208%2C%0A%20%20%20%20%20%20%20%20%22DOB%22%3A%20%222005-03-04%22%2C%0A%20%20%20%20%20%20%20%20%22affiliationType%22%3A%20%22NCVT%22%2C%0A%20%20%20%20%20%20%20%20%22registrationNumber%22%3A%20%22ICA211021569832%22%2C%0A%20%20%20%20%20%20%20%20%22tradeName%22%3A%20%22Electrician%22%2C%0A%20%20%20%20%20%20%20%20%22iti%22%3A%207%2C%0A%20%20%20%20%20%20%20%20%22industry%22%3A%201%2C%0A%20%20%20%20%20%20%20%20%22itiByIti%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22id%22%3A%207%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22name%22%3A%20%22GITI%20Nagina%22%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%22industryByIndustry%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22id%22%3A%201%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22name%22%3A%20%22Kaushal%20Bhawan%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22latitude%22%3A%2030.695753%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22longitude%22%3A%2076.872025%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22schedules%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22is_industry%22%3A%20true%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D')); }",
       "onFormFailure": "async (formData) => { console.log(formData); }",
+      "onSuccess": {
+        "notificationMessage": "Form submitted successfully",
+        "sideEffect": "async (formData) => { console.log(formData); }",
+        "message": "Form submitted successfully"
+      },
       "nextFormOnSuccess": {
-        "type": "jumping_form_2",
+        "type": "form",
         "id": "jumping_form_2"
       },
       "nextFormOnFailure": {
-- 
GitLab