diff --git a/apps/wrapper/public/index.html b/apps/wrapper/public/index.html index aa069f27cbd9d53394428171c3989fd03db73c76..0a4852bd0d793725699633fe1861f1ec1a2ee7c4 100644 --- a/apps/wrapper/public/index.html +++ b/apps/wrapper/public/index.html @@ -24,7 +24,7 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> - <title>React App</title> + <title>Workflow Demo App</title> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> diff --git a/apps/wrapper/src/App.css b/apps/wrapper/src/App.css index 74b5e053450a48a6bdb4d71aad648e7af821975c..ef1b6605488a80f6ac777232653c3fe2ddf4322b 100644 --- a/apps/wrapper/src/App.css +++ b/apps/wrapper/src/App.css @@ -1,38 +1,49 @@ -.App { - text-align: center; +.container { + display: flex; + height: 100vh; + width: 100vw; + background: #2b2b2b; + justify-content: center; + align-items: center; + flex-direction: column; + gap: 2rem; } -.App-logo { - height: 40vmin; - pointer-events: none; +.heading { + font-size: 5rem; + color: #ffc119; } -@media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } +.subtitle { + font-size: 2rem; + color: #efefef; + margin-top: -2rem; + margin-bottom: 4rem; } -.App-header { - background-color: #282c34; - min-height: 100vh; +.btnContainer { display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; + flex-direction: row; + gap: 2rem; } -.App-link { - color: #61dafb; +.workflowBtns { + height: 8rem; + width: 8rem; + border: 1px solid #ffc119; + border-radius: 1rem; + display: flex; + justify-content: center; + align-items: center; + color: #efefef; + font-size: 1.5rem; + cursor: pointer; + transition: all 0.3s ease-in; } -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} +.workflowBtns:hover { + background: #ffc119; + color: #000; + transform: translateY(-5px); + box-shadow: #ffc119 0px 30px 60px -6px, #ffc119 0px 18px 36px -9px; +} \ No newline at end of file diff --git a/apps/wrapper/src/App.js b/apps/wrapper/src/App.js index 296537800d617bec06fe748b8e309bd02be3458d..3240c2eb2acb69cb269fc00c64d82348835b46f0 100644 --- a/apps/wrapper/src/App.js +++ b/apps/wrapper/src/App.js @@ -1,68 +1,49 @@ -import logo from './logo.svg'; import './App.css'; import React, { useState, useEffect } from 'react'; +import GenericForm from './components/GenericForm'; -import formSpecJSON from "./formsNew.json"; function App() { - - const formSpec = formSpecJSON; - const [isFirst, setIsFirst] = useState(true); - // Encode string method to URI - const encodeFunction = (func) => { - return encodeURIComponent(JSON.stringify(func)); - } - - const getFormURI = (form, ofsd, prefillSpec) => { - console.log(form, ofsd, prefillSpec); - return encodeURIComponent(`https://enketo-manager-ratings-tech.samagra.io/?form=${form}&onFormSuccessData=${encodeFunction(ofsd)}&prefillSpec=${encodeFunction(prefillSpec)}`); - } - - const startingForm = formSpec.start; - const [formId, setFormId] = useState(startingForm); - const [encodedFormSpec, setEncodedFormSpec] = useState(encodeURI(JSON.stringify(formSpec.forms[formId]))); - const [onFormSuccessData, setOnFormSuccessData] = useState(undefined); - const [onFormFailureData, setOnFormFailureData] = useState(undefined); - const [encodedFormURI, setEncodedFormURI] = useState(getFormURI(formId, formSpec.forms[formId].onSuccess, formSpec.forms[formId].prefill)); - - useEffect(() => { - // Manage onNext - window.addEventListener('message', function (e) { - const data = e.data; - try { - /* message = { - nextForm: "formID", - formData: {}, - } - */ - const { nextForm, formData, onSuccessData, onFailureData } = JSON.parse(data); - console.log({ nextForm, formData, onSuccessData, onFailureData }); - if (nextForm.type === 'form') { - setFormId(nextForm.id); - setOnFormSuccessData(onSuccessData); - setOnFormFailureData(onFailureData); - setEncodedFormSpec(encodeURI(JSON.stringify(formSpec.forms[formId]))); - setEncodedFormURI(getFormURI(nextForm.id, onSuccessData, formSpec.forms[nextForm.id].prefill)); - } else { - window.location.href = nextForm.url; - } - } - catch (e) { - // console.log(e) - } - }); - }, []); - + const [flows, setFlows] = useState([ + { + name: 'Flow 1', + config: 'workflow_first.json' + }, + { + name: 'Flow 2', + config: 'workflow_second.json' + }, + { + name: 'Flow 3', + config: 'workflow_3_config.json' + }, + { + name: 'Flow 4', + config: 'workflow_4_config.json' + }, + { + name: 'Flow 5', + config: 'workflow_5_config.json' + } + ]) + + const [selectedFlow, setSelectedFlow] = useState({}); return ( <div className="App"> - <iframe title='current-form' - style={{ height: "100vh", width: "100vw" }} - src={ - `http://localhost:8005/preview?formSpec=${encodedFormSpec}&xform=${encodedFormURI}` + <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='btnContainer'> + {flows?.map(el => <div className='workflowBtns' onClick={() => setSelectedFlow(el)}>{el.name}</div>)} + </div> + </> + : <GenericForm {...{ selectedFlow }} /> } - /> + </div> </div> ); } diff --git a/apps/wrapper/src/components/GenericForm/index.js b/apps/wrapper/src/components/GenericForm/index.js new file mode 100644 index 0000000000000000000000000000000000000000..122b8ee9064c93e61ca0522157cb844679284acc --- /dev/null +++ b/apps/wrapper/src/components/GenericForm/index.js @@ -0,0 +1,68 @@ +import React, { useState, useEffect } from 'react'; +import styles from './index.module.css'; + +const GenericForm = (props) => { + const { selectedFlow } = props; + const formSpec = require(`../../${selectedFlow.config}`); + const [isFirst, setIsFirst] = useState(true); + // Encode string method to URI + const encodeFunction = (func) => { + return encodeURIComponent(JSON.stringify(func)); + } + + const getFormURI = (form, ofsd, prefillSpec) => { + console.log(form, ofsd, prefillSpec); + return encodeURIComponent(`https://enketo-manager-ratings-tech.samagra.io/?form=${form}&onFormSuccessData=${encodeFunction(ofsd)}&prefillSpec=${encodeFunction(prefillSpec)}`); + } + + const startingForm = formSpec.start; + const [formId, setFormId] = useState(startingForm); + const [encodedFormSpec, setEncodedFormSpec] = useState(encodeURI(JSON.stringify(formSpec.forms[formId]))); + const [onFormSuccessData, setOnFormSuccessData] = useState(undefined); + const [onFormFailureData, setOnFormFailureData] = useState(undefined); + const [encodedFormURI, setEncodedFormURI] = useState(getFormURI(formId, formSpec.forms[formId].onSuccess, formSpec.forms[formId].prefill)); + + useEffect(() => { + // Manage onNext + window.addEventListener('message', function (e) { + const data = e.data; + + try { + /* message = { + nextForm: "formID", + formData: {}, + } + */ + const { nextForm, formData, onSuccessData, onFailureData } = JSON.parse(data); + console.log({ nextForm, formData, onSuccessData, onFailureData }); + if (nextForm.type === 'form') { + setFormId(nextForm.id); + setOnFormSuccessData(onSuccessData); + setOnFormFailureData(onFailureData); + setEncodedFormSpec(encodeURI(JSON.stringify(formSpec.forms[formId]))); + setEncodedFormURI(getFormURI(nextForm.id, onSuccessData, formSpec.forms[nextForm.id].prefill)); + } else { + window.location.href = nextForm.url; + } + } + catch (e) { + // console.log(e) + } + }); + }, []); + + + return ( + <div className={styles.container}> + <div>ODK FORM</div> + <iframe title='current-form' + style={{ height: "100vh", width: "100vw" }} + src={ + `http://localhost:8005/preview?formSpec=${encodedFormSpec}&xform=${encodedFormURI}` + } + /> + </div> + ); +} + +export default GenericForm; diff --git a/apps/wrapper/src/components/GenericForm/index.module.css b/apps/wrapper/src/components/GenericForm/index.module.css new file mode 100644 index 0000000000000000000000000000000000000000..cc1237dc2b7cfa039a8830d412943231d28a0ff5 --- /dev/null +++ b/apps/wrapper/src/components/GenericForm/index.module.css @@ -0,0 +1,3 @@ +.container { + +} \ No newline at end of file diff --git a/apps/wrapper/src/index.css b/apps/wrapper/src/index.css index ec2585e8c0bb8188184ed1e0703c4c8f2a8419b0..078727b8a5a0de31ab0931e940b76dd715f9c07b 100644 --- a/apps/wrapper/src/index.css +++ b/apps/wrapper/src/index.css @@ -1,6 +1,8 @@ +@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300&display=swap'); + body { margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + font-family: Poppins, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; -webkit-font-smoothing: antialiased; diff --git a/apps/wrapper/src/forms.json b/apps/wrapper/src/workflow_first.json similarity index 97% rename from apps/wrapper/src/forms.json rename to apps/wrapper/src/workflow_first.json index 57fead0a5bedc033d913dc337e5bb7b4fdd3d094..23cf8cc5d26e8c14553278a8ab814133357e672c 100644 --- a/apps/wrapper/src/forms.json +++ b/apps/wrapper/src/workflow_first.json @@ -1,9 +1,9 @@ { "forms": { - "form1": { + "test": { "skipOnSuccessMessage": true, "submissionURL": "http://esamwad.samagra.io/api/v4/form/submit", - "name": "SampleForm", + "name": "Test Form", "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", @@ -44,6 +44,6 @@ } } }, - "startingForm": "form1", + "startingForm": "test", "metaData": {} } \ No newline at end of file diff --git a/apps/wrapper/src/formsNew.json b/apps/wrapper/src/workflow_second.json similarity index 100% rename from apps/wrapper/src/formsNew.json rename to apps/wrapper/src/workflow_second.json