diff --git a/components.js b/components.js index bbc5e33..9ff07ca 100644 --- a/components.js +++ b/components.js @@ -204,18 +204,19 @@ border: none; .input { display: flex; align-items: center; + text-align: left; position: relative; gap: 1em; padding: 0.7em 1em; border-radius: 0.3em; transition: opacity 0.3s; - background: rgba(var(--text-color), 0.1); + background: rgba(var(--text-color), 0.06); + box-shadow: 0 0 0 0.1em rgba(var(--text-color), 0.2) inset; font-family: var(--font-family); width: 100% outline: none; min-width: 0; } - input:focus{ caret-color: var(--accent-color); } @@ -281,6 +282,9 @@ input{ border: solid 1px rgba(var(--text-color), 0.2); padding: 0.6em 1em; } +.helper-text:empty{ + padding: 0; +} @media (any-hover: hover){ .icon:hover{ background: rgba(var(--text-color), 0.1); @@ -288,19 +292,19 @@ input{ }
- -
+ +
`; customElements.define('sm-input', @@ -339,22 +343,22 @@ customElements.define('sm-input', return this.shadowRoot.querySelector('input').checkValidity() } - focusIn() { + focusIn = () => { this.shadowRoot.querySelector('input').focus() } - focusOut() { + focusOut = () => { this.shadowRoot.querySelector('input').blur() } - preventNonNumericalInput(e) { + preventNonNumericalInput = (e) => { let keyCode = e.keyCode; - if (!((keyCode > 47 && keyCode < 56) || (keyCode > 36 && keyCode < 39) || (keyCode > 95 && keyCode < 104) || keyCode === 110 || (keyCode > 7 && keyCode < 19))) { + if (!((keyCode > 47 && keyCode < 56) || (keyCode > 36 && keyCode < 39) || (keyCode > 95 && keyCode < 106) || keyCode === 110 || (keyCode > 7 && keyCode < 19))) { e.preventDefault(); } } - fireEvent() { + fireEvent = () => { let event = new Event('input', { bubbles: true, cancelable: true, @@ -363,7 +367,7 @@ customElements.define('sm-input', this.dispatchEvent(event); } - checkInput() { + checkInput = (e) => { if (!this.hasAttribute('placeholder') || this.getAttribute('placeholder') === '') return; if (this.input.value !== '') { @@ -392,6 +396,8 @@ customElements.define('sm-input', this.helperText = this.shadowRoot.querySelector('.helper-text') this.valueChanged = false; this.readonly = false + this.min + this.max this.animate = this.hasAttribute('animate') this.input = this.shadowRoot.querySelector('input') this.shadowRoot.querySelector('.label').textContent = this.getAttribute('placeholder') @@ -402,6 +408,19 @@ customElements.define('sm-input', if (this.hasAttribute('required')) { this.input.setAttribute('required', '') } + if (this.hasAttribute('min')) { + let minValue = this.getAttribute('min') + this.input.setAttribute('min', minValue) + this.min = parseInt(minValue) + } + if (this.hasAttribute('max')) { + let maxValue = this.getAttribute('max') + this.input.setAttribute('max', maxValue) + this.max = parseInt(maxValue) + } + if (this.hasAttribute('pattern')) { + this.input.setAttribute('pattern', this.getAttribute('pattern')) + } if (this.hasAttribute('readonly')) { this.input.setAttribute('readonly', '') this.readonly = true @@ -412,6 +431,7 @@ customElements.define('sm-input', if (this.hasAttribute('type')) { if (this.getAttribute('type') === 'number') { this.input.setAttribute('inputmode', 'numeric') + this.input.setAttribute('type', 'number') } else this.input.setAttribute('type', this.getAttribute('type')) @@ -434,6 +454,7 @@ customElements.define('sm-input', if (oldValue !== newValue) { if (name === 'placeholder') this.shadowRoot.querySelector('.label').textContent = newValue; + this.setAttribute('aria-label', newValue); } } }) @@ -1488,7 +1509,7 @@ customElements.define('sm-strip-select', class extends HTMLElement { set value(val) { this.setAttribute('value', val) } - scrollLeft() { + scrollLeft = () => { this.select.scrollBy({ top: 0, left: -this.scrollDistance, @@ -1496,7 +1517,7 @@ customElements.define('sm-strip-select', class extends HTMLElement { }) } - scrollRight() { + scrollRight = () => { this.select.scrollBy({ top: 0, left: this.scrollDistance, @@ -1572,13 +1593,13 @@ customElements.define('sm-strip-select', class extends HTMLElement { previousOption = firstElement; } }); - this.nextArrow.addEventListener('click', this.scrollRight.bind(this)) - this.previousArrow.addEventListener('click', this.scrollLeft.bind(this)) + this.nextArrow.addEventListener('click', this.scrollRight) + this.previousArrow.addEventListener('click', this.scrollLeft) } disconnectedCallback() { - this.nextArrow.removeEventListener('click', this.scrollRight.bind(this)) - this.previousArrow.removeEventListener('click', this.scrollLeft.bind(this)) + this.nextArrow.removeEventListener('click', this.scrollRight) + this.previousArrow.removeEventListener('click', this.scrollLeft) } }) @@ -1660,73 +1681,80 @@ const smPopup = document.createElement('template') smPopup.innerHTML = ` `; @@ -2039,7 +2104,11 @@ customElements.define('sm-carousel', class extends HTMLElement { this.attachShadow({ mode: 'open' }).append(smCarousel.content.cloneNode(true)) } - scrollLeft() { + static get observedAttributes() { + return ['indicator'] + } + + scrollLeft = () => { this.carousel.scrollBy({ top: 0, left: -this.scrollDistance, @@ -2047,7 +2116,7 @@ customElements.define('sm-carousel', class extends HTMLElement { }) } - scrollRight() { + scrollRight = () => { this.carousel.scrollBy({ top: 0, left: this.scrollDistance, @@ -2061,32 +2130,50 @@ customElements.define('sm-carousel', class extends HTMLElement { this.carouselSlot = this.shadowRoot.querySelector('slot') this.nextArrow = this.shadowRoot.querySelector('.next-item') this.previousArrow = this.shadowRoot.querySelector('.previous-item') - this.nextGradient = this.shadowRoot.querySelector('.right') - this.previousGradient = this.shadowRoot.querySelector('.left') + this.indicatorsContainer = this.shadowRoot.querySelector('.indicators') this.carouselItems + this.indicators + this.showIndicator = false this.scrollDistance = this.carouselContainer.getBoundingClientRect().width / 3 - const firstElementObserver = new IntersectionObserver(entries => { - if (entries[0].isIntersecting) { - this.previousArrow.classList.remove('expand') - this.previousGradient.classList.add('hide') - } - else { - this.previousArrow.classList.add('expand') - this.previousGradient.classList.remove('hide') - } - }, { - root: this.carouselContainer, - threshold: 0.9 - }) - const lastElementObserver = new IntersectionObserver(entries => { - if (entries[0].isIntersecting) { - this.nextArrow.classList.remove('expand') - this.nextGradient.classList.add('hide') - } - else { - this.nextArrow.classList.add('expand') - this.nextGradient.classList.remove('hide') - } + let frag = document.createDocumentFragment(); + if (this.hasAttribute('indicator')) + this.showIndicator = true + + + let firstVisible = false, + lastVisible = false + const allElementsObserver = new IntersectionObserver(entries => { + entries.forEach(entry => { + if(this.showIndicator) + if (entry.isIntersecting) { + this.indicators[parseInt(entry.target.attributes.rank.textContent)].classList.add('active') + } + else + this.indicators[parseInt(entry.target.attributes.rank.textContent)].classList.remove('active') + if (!entry.target.previousElementSibling) + if(entry.isIntersecting) { + this.previousArrow.classList.remove('expand') + firstVisible = true + } + else { + this.previousArrow.classList.add('expand') + firstVisible = false + } + if (!entry.target.nextElementSibling) + if(entry.isIntersecting) { + this.nextArrow.classList.remove('expand') + lastVisible = true + } + else { + this.nextArrow.classList.add('expand') + + lastVisible = false + } + if (firstVisible && lastVisible) + this.indicatorsContainer.classList.add('hide') + else + this.indicatorsContainer.classList.remove('hide') + }) }, { root: this.carouselContainer, threshold: 0.9 @@ -2102,8 +2189,18 @@ customElements.define('sm-carousel', class extends HTMLElement { this.carouselSlot.addEventListener('slotchange', e => { this.carouselItems = this.carouselSlot.assignedElements() - firstElementObserver.observe(this.carouselItems[0]) - lastElementObserver.observe(this.carouselItems[this.carouselItems.length - 1]) + this.carouselItems.forEach(item => allElementsObserver.observe(item)) + if(this.showIndicator){ + this.indicatorsContainer.innerHTML = `` + this.carouselItems.forEach((item, index) => { + let dot = document.createElement('div') + dot.classList.add('dot') + frag.append(dot) + item.setAttribute('rank', index) + }) + this.indicatorsContainer.append(frag) + this.indicators = this.indicatorsContainer.children + } }) this.addEventListener('keyup', e => { @@ -2113,13 +2210,22 @@ customElements.define('sm-carousel', class extends HTMLElement { this.scrollRight() }) - this.nextArrow.addEventListener('click', this.scrollRight.bind(this)) - this.previousArrow.addEventListener('click', this.scrollLeft.bind(this)) + this.nextArrow.addEventListener('click', this.scrollRight) + this.previousArrow.addEventListener('click', this.scrollLeft) + } + + attributeChangedCallback(name, oldValue, newValue) { + if (name === 'indicator') { + if (this.hasAttribute('indicator')) + this.showIndicator = true + else + this.showIndicator = false + } } disconnectedCallback() { - this.nextArrow.removeEventListener('click', this.scrollRight.bind(this)) - this.previousArrow.removeEventListener('click', this.scrollLeft.bind(this)) + this.nextArrow.removeEventListener('click', this.scrollRight) + this.previousArrow.removeEventListener('click', this.scrollLeft) } }) @@ -2156,27 +2262,28 @@ transform: none; opacity: 1; } .notification{ -display: flex; -opacity: 0; -padding: 1rem 1.5rem; -transform: translateY(-1rem); -position: relative; -border-radius: 0.3rem; -box-shadow: 0 0.1rem 0.2rem rgba(0, 0, 0, 0.1), - 0.5rem 1rem 2rem rgba(0, 0, 0, 0.1); -background: rgba(var(--foreground-color), 1); -transition: height 0.3s, transform 0.3s, opacity 0.3s; -overflow: hidden; -overflow-wrap: break-word; -word-wrap: break-word; --ms-word-break: break-all; -word-break: break-all; -word-break: break-word; --ms-hyphens: auto; --moz-hyphens: auto; --webkit-hyphens: auto; -hyphens: auto; -max-width: 100%; + display: flex; + opacity: 0; + padding: 1rem 1.5rem; + margin-bottom: 0.5rem; + transform: translateY(-1rem); + position: relative; + border-radius: 0.3rem; + box-shadow: 0 0.1rem 0.2rem rgba(0, 0, 0, 0.1), + 0.5rem 1rem 2rem rgba(0, 0, 0, 0.1); + background: rgba(var(--foreground-color), 1); + transition: height 0.3s, transform 0.3s, opacity 0.3s; + overflow: hidden; + overflow-wrap: break-word; + word-wrap: break-word; + -ms-word-break: break-all; + word-break: break-all; + word-break: break-word; + -ms-hyphens: auto; + -moz-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; + max-width: 100%; } h4:first-letter, p:first-letter{ @@ -2247,7 +2354,7 @@ stroke-width: 6; transform: translateX(1rem); } } -@media screen and (max-width: 640px){ +@media screen and (any-hover: none){ .close{ display: none } @@ -2263,14 +2370,14 @@ customElements.define('sm-notifications', class extends HTMLElement { this.shadow = this.attachShadow({ mode: 'open' }).append(smNotifications.content.cloneNode(true)) } - handleTouchStart(e) { + handleTouchStart =(e) => { this.notification = e.target.closest('.notification') this.touchStartX = e.changedTouches[0].clientX this.notification.style.transition = 'initial' this.touchStartTime = e.timeStamp } - handleTouchMove(e) { + handleTouchMove = (e) => { e.preventDefault() if (this.touchStartX < e.changedTouches[0].clientX) { this.offset = e.changedTouches[0].clientX - this.touchStartX; @@ -2282,7 +2389,7 @@ customElements.define('sm-notifications', class extends HTMLElement { } } - handleTouchEnd(e) { + handleTouchEnd = (e) => { this.notification.style.transition = 'transform 0.3s, opacity 0.3s' this.touchEndTime = e.timeStamp cancelAnimationFrame(this.touchEndAnimataion) @@ -2312,11 +2419,11 @@ customElements.define('sm-notifications', class extends HTMLElement { this.notification.style.transform = `translateX(${this.offset}px)` } - resetPosition() { + resetPosition = () => { this.notification.style.transform = `translateX(0)` } - push(messageBody, type, pinned) { + push = (messageBody, type, pinned) => { let notification = document.createElement('div'), composition = `` notification.classList.add('notification') @@ -2362,12 +2469,12 @@ customElements.define('sm-notifications', class extends HTMLElement { else { notification.setAttribute('style', `transform: translateY(0); opacity: 1`) } - notification.addEventListener('touchstart', this.handleTouchStart.bind(this)) - notification.addEventListener('touchmove', this.handleTouchMove.bind(this)) - notification.addEventListener('touchend', this.handleTouchEnd.bind(this)) + notification.addEventListener('touchstart', this.handleTouchStart) + notification.addEventListener('touchmove', this.handleTouchMove) + notification.addEventListener('touchend', this.handleTouchEnd) } - removeNotification(notification, toLeft) { + removeNotification = (notification, toLeft) => { if (!this.offset) this.offset = 0; diff --git a/index.html b/index.html index d73db9b..d8dccfa 100644 --- a/index.html +++ b/index.html @@ -5,7 +5,9 @@ Blockchain UPI - + @@ -14,262 +16,287 @@ -

Balance

- - refresh balance - - - + Check Balance
-
+
Rupee
-

0

-
-
-
Unconfirmed Rupee
-

0

+

0

FLO
-

0

+

0

@@ -702,12 +710,17 @@

*If your request isn't completed in 12hrs, use REPORT to get assistance from our helpline.

+ Sent Deposits Withdrawals Pay through cashier System Notifications + +
+

You haven't sent any rupee yet.

+

You haven't deposited rupee yet.

@@ -728,7 +741,7 @@
-

Complaints +

Complaints

Select Cashier
@@ -754,18 +767,19 @@

Settings

-

My FLO ID

-
-

- - Copy - - - -
- +

My FLO ID

+
+

+ + Copy + + + +
+
+ - @@ -817,7 +830,6 @@ currentTimeout, notificationSound = document.getElementById('notification_sound'); const render = { - // returns an order element; depositRequest(txid, floId) { let card = document.createElement('div'); card.classList.add('request') @@ -873,6 +885,63 @@ `; return card; }, + activityCard(type, amount, timesStamp){ + let card = document.createElement('div'), + composition = ``, + icon, + sign + card.classList.add('activity') + switch(type){ + case 'sent': + icon = ` + + + + ` + sign = '-' + break; + case 'deposit': + icon = ` + + deposit + + + + + + + ` + sign = '+' + break; + case 'withdraw': + icon = ` + + withdraw + + + + + + + + ` + sign = '-' + break; + } + composition = ` + ${icon} +

${type}

+

${sign} ₹${amount}

+
${formatedTime(timesStamp)}
+ ` + card.innerHTML = composition; + return card; + }, depositActivity(vectorClock, txid, amount) { let card = document.createElement('div'), time = parseInt(vectorClock.split('_')[0]) @@ -970,7 +1039,7 @@ paymentRequest(time, senderAddress, amount, id, enableActions) { let card = document.createElement('div') card.classList.add('request'), - markup = `` + markup = `` setAttributes(card, { 'data-sender-address': senderAddress, @@ -990,8 +1059,8 @@
amount

₹ ${amount}

`; - if(enableActions) - markup += ` + if (enableActions) + markup += `
-
` + ` card.innerHTML = markup return card; }, @@ -1285,85 +1354,67 @@ zIndex = 10; function showPopup(popup, permission) { - document.body.setAttribute('style', `overflow: hidden; top: -${window.scrollY}px`) let thisPopup = document.getElementById(popup); - thisPopup.parentNode.classList.remove('hide'); - thisPopup.classList.add('no-transformations'); - popupStack.push({ - popup, - permission - }) - zIndex++; - thisPopup.parentNode.setAttribute('style', `z-index: ${zIndex}`) - document.getElementById('main_page') - setTimeout(() => { - thisPopup.querySelectorAll('.input').forEach(input => { - animateInput(input) - formValidation(input.firstElementChild) - }) - }, 100); - if (popup === 'main_loader') { - loader.classList.add('animate-loader') - document.querySelector('main').classList.add('hide-completely') - document.querySelector('#main_header').classList.add('hide-completely') - document.querySelector('#navbar').classList.add('hide-completely') - } + zIndex++ + thisPopup.setAttribute('style', `z-index: ${zIndex}`) + popupStack = thisPopup.show(permission, popupStack) return thisPopup; } // hides the popup or modal function hidePopup() { - const scrollY = document.body.style.top; - window.scrollTo(0, parseInt(scrollY || '0') * -1); - setTimeout(() => { - document.body.setAttribute('style', `overflow: auto; top: initial`) - }, 300); if (popupStack.peek() === undefined) - return; - let { - popup, - permission - } = popupStack.pop(); - thisPopup = document.getElementById(popup); - thisPopup.closest('.popup-container').classList.add('hide'); - thisPopup.closest('.popup').classList.remove('no-transformations'); + return; + popupStack.peek().popup.hide() + } + + document.addEventListener('popupopened', e => { + let thisPopup = e.detail.popup + switch(e.detail.popup.id){ + case 'deposit_rupee' : + request_rupee_token() + break; + } + }) + document.addEventListener('popupclosed', e => { + popupStack = e.detail.popupStack + let thisPopup = e.detail.popup, + submitButton = thisPopup.querySelector('button[type="submit"]') + if (submitButton) + submitButton.disabled = true; setTimeout(() => { - clearAllInputs(thisPopup) - zIndex--; - thisPopup.parentNode.setAttribute('style', `z-index: ${zIndex}`) if (thisPopup.querySelector('.action')) { btnLoading(thisPopup.querySelector('.action'), 'stop') thisPopup.querySelector("button[type='submit']").disabled = true; } }, 400) - if (popup === 'main_loader' || popup === 'sign_in_popup') { - loader.classList.remove('animate-loader') - document.querySelector('main').classList.remove('hide-completely') - document.querySelector('#navbar').classList.remove('hide-completely') - document.querySelector('#main_header').classList.remove('hide-completely') - } - if (popup === 'prompt') { - if (thisPopup.querySelector('input').value == '') + zIndex-- + switch(e.detail.popup.id){ + case 'sign_in_popup' : + loader.classList.remove('animate-loader') + document.querySelector('main').classList.remove('hide-completely') + document.querySelector('#navbar').classList.remove('hide-completely') + document.querySelector('#main_header').classList.remove('hide-completely') + break; + case 'cash_transfer' : + payingRequested = false; + tokenReceiver.disabled = false + tokenAmount.disabled = false + break; + case 'transaction_result' : + setTimeout(() => { + transactionHeading.textContent = '' + transactionMessage.innerHTML = '' + transactionSuccessId.textContent = '' + transactionSuccessId.parentNode.classList.add('hide-completely') + transactionSuccessSection.classList.add('hide-completely') + transactionFailedSection.classList.add('hide-completely') + }, 300); + break; + case 'prompt': + if (thisPopup.querySelector('sm-input').value == '') thisPopup.querySelector('.cancel-btn').click() - } - if (popup === 'cash_transfer') { - payingRequested = false; - tokenReceiver.disabled = false - tokenAmount.disabled = false - } - if (popup === 'deposit_rupee') { - depositRequested = 0; - document.getElementById('upi_txId_section').classList.add('hide-completely') - document.getElementById('deposit_amount_section').classList.remove('hide-completely') - depositedRupeeTxId.disabled = true - document.getElementById('request_tokens_btn').children[0].textContent = 'Continue' - } - } - - addEventListener('mousedown', e => { - if (e.target.classList.contains('popup-container') && popupStack.peek() !== undefined && popupStack - .peek().permission !== 'no') { - hidePopup() + break } }) @@ -1379,6 +1430,22 @@ } } + const loaderPage = document.getElementById('main_loader') + function showLoader() { + loaderPage.classList.remove('hide-completely') + loader.classList.add('animate-loader') + document.querySelector('main').classList.add('hide-completely') + document.querySelector('#navbar').classList.add('hide-completely') + document.querySelector('#main_header').classList.add('hide-completely') + } + function hideLoader() { + loaderPage.classList.add('hide-completely') + loader.classList.remove('animate-loader') + document.querySelector('main').classList.remove('hide-completely') + document.querySelector('#navbar').classList.remove('hide-completely') + document.querySelector('#main_header').classList.remove('hide-completely') + } + function setAttributes(el, attrs) { for (var key in attrs) { @@ -1387,12 +1454,6 @@ } function clearAllInputs(parent) { - parent.querySelectorAll("input").forEach((field) => { - field.value = ''; - if (field.closest('.input')) { - field.closest('.input').classList.remove('animate-label') - } - }) if (parent.querySelectorAll("textarea")) parent.querySelectorAll("textarea").forEach((field) => { field.value = ''; @@ -1423,11 +1484,11 @@ showPopup('confirmation') popup.querySelector('#confirm_message').textContent = message; popup.querySelector('.submit-btn').onclick = () => { - hidePopup() + popup.hide() resolve(true); } popup.querySelector('.cancel-btn').onclick = () => { - hidePopup() + popup.hide() resolve(false); } }) @@ -1437,7 +1498,7 @@ let askPrompt = function (message, defaultVal) { return new Promise(resolve => { let popup = document.getElementById('prompt'), - input = popup.querySelector('input'); + input = popup.querySelector('sm-input'); if (defaultVal) input.value = defaultVal; showPopup('prompt') @@ -1445,20 +1506,22 @@ input.addEventListener('keyup', e => { if (e.key === 'Enter') { resolve(input.value); - hidePopup() + popup.hide() } }) popup.querySelector('#prompt_message').textContent = message; popup.querySelector('.submit-btn').onclick = () => { + popup.hide() resolve(input.value); } popup.querySelector('.cancel-btn').onclick = () => { - hidePopup() + popup.hide() resolve(null); } }) } + const currentYear = new Date().getFullYear() function formatedTime(time) { try { let timeFrag = new Date(parseInt(time)).toString().split(' '), @@ -1470,15 +1533,18 @@ hours = new Date(parseInt(time)).getHours() minutes = minutes < 10 ? `0${minutes}` : minutes let finalHours = ``; - if(hours > 12) + if (hours > 12) finalHours = `${hours - 12}:${minutes}` - else if(hours === 0) + else if (hours === 0) finalHours = `12:${minutes}` else finalHours = `${hours}:${minutes}` - + finalHours = hours >= 12 ? `${finalHours} PM` : `${finalHours} AM` - return `${finalHours} ${month} ${date} ${year}`; + if(year == currentYear) + return `${finalHours} ${month} ${date}`; + else + return `${finalHours} ${month} ${date} ${year}`; } catch (e) { console.error(e); return time; @@ -1492,78 +1558,51 @@ notify('Copied', 'success') } - // prevents non numerical input on firefox - function preventNonNumericalInput(e) { - e = e || window.event; - let charCode = (typeof e.which == "undefined") ? e.keyCode : e.which, - charStr = String.fromCharCode(charCode); - - if (!charStr.match(/[+-]?([0-9]*[.])?[0-9]+/)) - e.preventDefault(); + function areInputsValid(parent) { + let allInputs = parent.querySelectorAll("sm-input:not([disabled])"); + return [...allInputs].every(input => { + if(input.hasAttribute('floId')){ + if(floCrypto.validateAddr(input.value.trim())) return true + } + else + return input.isValid + }) } - function areInputsEmpty(parent) { - let allInputs = parent.querySelectorAll(".input input:not(:disabled)"); - return [...allInputs].every(input => input.checkValidity()) - } - - function formValidation(formElement, e) { - if (formElement.getAttribute('type') === 'number' && typeof e !== 'undefined') - preventNonNumericalInput(e); - let parent = formElement.closest('.popup'), + function formValidation(formElement) { + let parent = formElement.closest('sm-popup'), submitBtn = parent.querySelector("button[type='submit']"); if (!submitBtn) return; - if (formElement.hasAttribute('floId')) { - if (floCrypto.validateAddr(formElement.value.trim())) { - submitBtn.disabled = false; - } else { - submitBtn.disabled = true; - } - } - if (areInputsEmpty(parent)) + if (areInputsValid(parent)) submitBtn.disabled = false; else submitBtn.disabled = true; } - function animateInput(parent) { - if (parent.firstElementChild.value !== '') - parent.classList.add('animate-label') - else - parent.classList.remove('animate-label') - } - - let allForms = document.querySelectorAll('form'), - payingRequested = false, + let payingRequested = false, currentPaymentRequest; - const tokenReceiver = document.getElementById('token_receiver'), - tokenAmount = document.getElementById('token_amount') + const tokenReceiver = document.getElementById('token_receiver'), + tokenAmount = document.getElementById('token_amount'), + depositRupeeAmount = document.getElementById('token_amount_to_buy') + window.addEventListener('load', () => { - allForms.forEach((form) => { - form.addEventListener('input', (e) => { - if (e.target.closest('.input')) { - let parent = e.target.closest('.input'); - animateInput(parent) - formValidation(parent.firstElementChild, e) + document.addEventListener('input', e => { + if (e.target.closest('sm-input')) { + let input = e.target.closest('sm-input') + formValidation(input) + if(input.id === 'token_amount_to_buy'){ + let amount = input.value < 1 ? 0 : input.value + document.getElementById('send_amount_to_deposit').innerHTML = `Pay ₹${amount} to UPI Id below.`; } - }) - form.addEventListener('keyup', (e) => { - if (e.target.closest('.input')) { - if (e.key === 'Enter') { - e.target.closest('.popup').querySelector("button[type='submit']") - .click(); - } - } - }) + } }) - allForms.forEach((form) => { - form.addEventListener('blur', (e) => { - if (e.target.closest('.input')) { - let parent = e.target.closest('.input'); - if (parent.firstElementChild.value === '') - parent.classList.remove('animate-label') + document.addEventListener('keyup', (e) => { + if (e.target.closest('sm-input')) { + if (e.key === 'Enter') { + e.target.closest('sm-popup').querySelector("button[type='submit']") + .click(); } - }, true) + } }) // Function for confirming deposit requests @@ -1607,6 +1646,7 @@ } } }) + let currentRequest = null; document.getElementById('activity_page').addEventListener('click', (e) => { if (e.target.closest('.report')) { @@ -1639,7 +1679,7 @@ senderAddress = parent.dataset.senderAddress, amount = parent.dataset.amount, paymentRequestId = parent.dataset.paymentRequestId;; - let popup = showPopup('cash_transfer'); + showPopup('cash_transfer'); payingRequested = true; currentPaymentRequest = { paymentRequest: parent, @@ -1658,8 +1698,8 @@ const all_reqs = floDapps.getNextGeneralData(token_app.master_configurations .TYPE_REQUEST_PAYMENT, "0").reverse(); - const original_req = all_reqs.filter(f=>f.message.pay_req_id===paymentRequestId) - .map(m=>m.message)[0]; + const original_req = all_reqs.filter(f => f.message.pay_req_id === paymentRequestId) + .map(m => m.message)[0]; payment_request_status(original_req, 'DECLINED') e.target.closest('.request').remove() @@ -1685,6 +1725,29 @@ }) + const transactionSuccessSection = document.getElementById('success_section'), + transactionFailedSection = document.getElementById('failure_section'), + transactionSuccessId = document.getElementById('successful_transaction_id'), + transactionHeading = document.getElementById('transaction_heading'), + transactionMessage = document.getElementById('transaction_message') + + function showTrasactionStatus(status, heading, message, transactionId){ + transactionHeading.textContent = heading + transactionMessage.innerHTML = message + transactionSuccessId.textContent = transactionId + if(transactionId) + transactionSuccessId.parentNode.classList.remove('hide-completely') + else + transactionSuccessId.parentNode.classList.add('hide-completely') + if(status === 'success'){ + transactionSuccessSection.classList.remove('hide-completely') + } + else{ + transactionFailedSection.classList.remove('hide-completely') + } + showPopup('transaction_result') + } + let allPages = document.querySelectorAll('.page'), allTabs = document.querySelectorAll('.navbar-item'); @@ -1698,7 +1761,7 @@ document.getElementById(page).classList.remove('hide-completely') btn.classList.add('active', 'shrink') if (page === 'activity_page') { - show_user_activities() + show_all_user_activities() } if (page === 'request_page') { show_payment_requests() @@ -1707,7 +1770,7 @@ function signIn() { return new Promise((resolve, reject) => { - hidePopup() + hideLoader() showPopup('sign_in_popup', 'no') let signInBtn = document.getElementById('sign_in_btn'), privateKeyInput = document.getElementById('get_priv_key_field') @@ -10624,6 +10687,8 @@ deposits_flo_txids: {}, cash_sent_details: {}, pay_thru_cashier: {}, + //user UPIs + userUpis: {} } //add other given objectStores for (o in this.appObs) @@ -10733,7 +10798,7 @@ else { resolve(inputVal) hidePopup() - showPopup('main_loader', 'no') + showLoader() } }) } @@ -11129,14 +11194,14 @@ try { for (const ds of dataStores) { compactIDB.clearData(ds); - } + } return true; } catch (e) { console.error(e); return false; } } - + function delay(t, v) { return new Promise(function(resolve) { setTimeout(resolve.bind(null, v), t); @@ -11193,7 +11258,10 @@ { "FCja6sLv58e3RMy41T5AmWyvXEWesqBCkX": { "upi_id": "8507742774@ybl" - }, + } + }` + /* + , "FHW2kgYEhDt85vjAiMMF7bQqdP74L7iwvQ": { "upi_id": "8340617958@ybl" }, @@ -11209,7 +11277,7 @@ "FQ6udJuTbGDa2kWZAkmNpwgHaUEeYLPAtt": { "upi_id": "krishraj1012-2@okicici" } - }` + */ text = removeWhiteSpaces(text); return text; const master_data = await ajaxGet( @@ -11245,259 +11313,279 @@ try { for (const assets_string of floAssetsArray) { - let k = assets_string.split("="); + let k = assets_string.split("="); - if (k[1].indexOf(",") > 0 && k[1].indexOf("{") == -1) { - k[1] = k[1] - .split(",") - .map(val => - !isNaN(val) ? parseFloat(val) : val.trim() - ) - .filter(v => ![null, "", undefined, NaN].includes(v)); - } else if (!isNaN(k[1])) { - k[1] = parseFloat(k[1]); - } - if (typeof k[1] == "string" && k[1].indexOf("{") >= 0) { - k[1] = JSON.parse(k[1].replace(/ /g, "")); - } + if (k[1].indexOf(",") > 0 && k[1].indexOf("{") == -1) { + k[1] = k[1] + .split(",") + .map(val => + !isNaN(val) ? parseFloat(val) : val.trim() + ) + .filter(v => ![null, "", undefined, NaN].includes(v)); + } else if (!isNaN(k[1])) { + k[1] = parseFloat(k[1]); + } + if (typeof k[1] == "string" && k[1].indexOf("{") >= 0) { + k[1] = JSON.parse(k[1].replace(/ /g, "")); + } - if (typeof token_app.master_configurations !== "object") token_app - .master_configurations = {}; + if (typeof token_app.master_configurations !== "object") token_app + .master_configurations = {}; - Object.defineProperty( - token_app.master_configurations, - k[0], { + Object.defineProperty( + token_app.master_configurations, + k[0], { value: k[1], writable: false, configurable: false, enumerable: true } + ); + } + deepFreeze(token_app.master_configurations); + return token_app; + } catch (error) { + console.error( + "FATAL ERROR: Failed to fetch master configuration: ", + error ); } - deepFreeze(token_app.master_configurations); - return token_app; - } catch (error) { - console.error( - "FATAL ERROR: Failed to fetch master configuration: ", - error - ); } - } - return false; - }, + return false; + }, - doShreeGanesh: async function () { + doShreeGanesh: async function () { - // fetch configs from master comment - await this.fetch_configs(); + // fetch configs from master comment + await this.fetch_configs(); - await this.retrieveLatestContent(); + const allCashierOptions = document.querySelectorAll('.cashier-option'), + allUserOptions = document.querySelectorAll('.user-option'), + allHelplineOptions = document.querySelectorAll('.helpline-option'), + userType = document.querySelectorAll('.user-type') - request_rupee_token(); + //Cashier startup sequence + if (Object.keys(token_app.master_configurations.cashiers).includes(myFloID)) { + allCashierOptions.forEach(option => { + option.classList.remove('hide-completely') + }) + allUserOptions.forEach(option => { + option.classList.add('hide-completely') + }) + allHelplineOptions.forEach(option => { + option.classList.add('hide-completely') + }) + show_deposit_request() + show_withdraw_request() + showPayRequests() + userType.forEach(user => user.textContent = 'Cashier') + showPage(document.getElementById('deposit_page_btn'), 'deposit') + } - withdraw_token_to_get_cash(); + //Helpline startup sequence + else if (token_app.master_configurations.helplineFloId === myFloID) { + allCashierOptions.forEach(option => { + option.classList.add('hide-completely') + }) + allHelplineOptions.forEach(option => { + option.classList.remove('hide-completely') + }) + allUserOptions.forEach(option => { + option.classList.add('hide-completely') + }) + let cashierList = ``, + cashierSelect = document.getElementById('select_cashier') + cashierList += `Select Cashier...`; + for (cashier in token_app.master_configurations.cashiers) + cashierList += `${cashier}` + cashierSelect.innerHTML = cashierList; + await Promise.all([load_deposit_complaints(cashierSelect.value), load_withdraw_complaints( + cashierSelect.value), load_pay_thru_cashier_complaints(cashierSelect.value)]) + userType.forEach(user => user.textContent = 'Cashier') + showPage(document.getElementById('helpline_page_btn'), 'helpline_page') + } - transferTokensManually(); + //user startup sequence + else { + allCashierOptions.forEach(option => { + option.classList.add('hide-completely') + }) + allHelplineOptions.forEach(option => { + option.classList.add('hide-completely') + }) + allUserOptions.forEach(option => { + option.classList.remove('hide-completely') + }) + show_all_user_activities() + show_payment_requests() + userType.forEach(user => user.textContent = 'User') + showPage(document.getElementById('home_page_btn'), 'home_page') + } - const allCashierOptions = document.querySelectorAll('.cashier-option'), - allUserOptions = document.querySelectorAll('.user-option'), - allHelplineOptions = document.querySelectorAll('.helpline-option'), - userType = document.querySelectorAll('.user-type') + withdraw_token_to_get_cash(); - //Cashier startup sequence - if (Object.keys(token_app.master_configurations.cashiers).includes(myFloID)) { - allCashierOptions.forEach(option => { - option.classList.remove('hide-completely') - }) - allUserOptions.forEach(option => { - option.classList.add('hide-completely') - }) - allHelplineOptions.forEach(option => { - option.classList.add('hide-completely') - }) - show_deposit_request() - show_withdraw_request() - showPayRequests() - userType.forEach(user => user.textContent = 'Cashier') - showPage(document.getElementById('deposit_page_btn'), 'deposit') - } + transferTokensManually(); + + pay_through_cashier(); - //Helpline startup sequence - else if (token_app.master_configurations.helplineFloId === myFloID) { - allCashierOptions.forEach(option => { - option.classList.add('hide-completely') - }) - allHelplineOptions.forEach(option => { - option.classList.remove('hide-completely') - }) - allUserOptions.forEach(option => { - option.classList.add('hide-completely') - }) - let cashierList = ``, - cashierSelect = document.getElementById('select_cashier') - cashierList += `Select Cashier...`; - for (cashier in token_app.master_configurations.cashiers) - cashierList += `${cashier}` - cashierSelect.innerHTML = cashierList; - await Promise.all([load_deposit_complaints(cashierSelect.value), load_withdraw_complaints( - cashierSelect.value), load_pay_thru_cashier_complaints(cashierSelect.value)]) - userType.forEach(user => user.textContent = 'Cashier') - showPage(document.getElementById('helpline_page_btn'), 'helpline_page') - } + this.retrieveLatestContent(); + }, - //user startup sequence - else { - allCashierOptions.forEach(option => { - option.classList.add('hide-completely') - }) - allHelplineOptions.forEach(option => { - option.classList.add('hide-completely') - }) - allUserOptions.forEach(option => { - option.classList.remove('hide-completely') - }) - show_user_activities() - show_payment_requests() - userType.forEach(user => user.textContent = 'User') - showPage(document.getElementById('home_page_btn'), 'home_page') - } - - hidePopup() - - pay_through_cashier(); - }, - - retrieveLatestContent: async function (receiverID = floGlobals.adminID, senderIDs = floGlobals + retrieveLatestContent: async function (request_args='', receiverID = floGlobals.adminID, senderIDs = floGlobals .subAdmins) { - floCloudAPI.requestObjectData(floGlobals.application, { - receiverID, - senderIDs - }); + floCloudAPI.requestObjectData(floGlobals.application, { + receiverID, + senderIDs + }); - if (Object.keys(token_app.master_configurations.cashiers).includes(myFloID)) { - - await Promise.all([ - - create_root_structure(), - - floCloudAPI.requestGeneralData(token_app.master_configurations - .TYPE_DEPOSITS, { + if (Object.keys(token_app.master_configurations.cashiers).includes(myFloID)) { + + if(typeof request_args=='object' && typeof request_args.datatype=='string') { + return floCloudAPI.requestGeneralData(request_args.datatype, + request_args.options); + } + + await Promise.all([ + + create_root_structure(), + + floCloudAPI.requestGeneralData(token_app.master_configurations.TYPE_DEPOSITS, { receiverID: myFloID }), - floCloudAPI.requestGeneralData(token_app.master_configurations.TYPE_WITHDRAWS, { - receiverID: myFloID - }), + floCloudAPI.requestGeneralData(token_app.master_configurations.TYPE_WITHDRAWS, { + receiverID: myFloID + }), - floCloudAPI.requestGeneralData(token_app.master_configurations.TYPE_MSGES, { - receiverID: myFloID - }), + floCloudAPI.requestGeneralData(token_app.master_configurations.TYPE_MSGES, { + receiverID: myFloID + }), - floCloudAPI.requestGeneralData(token_app.master_configurations - .TYPE_PAY_THROUGH_CASHIER, { + floCloudAPI.requestGeneralData(token_app.master_configurations.TYPE_PAY_THROUGH_CASHIER, { receiverID: myFloID }) - ]) + ]) - return true; - } else if (token_app.master_configurations.helplineFloId === myFloID) { - await clearCashierData(); + return true; + } else if (token_app.master_configurations.helplineFloId === myFloID) { + await clearCashierData(); - await Promise.all([ - - create_root_structure(), - - floCloudAPI.requestGeneralData(token_app.master_configurations - .TYPE_FILE_DEPOSITS_COMPLAINT), - floCloudAPI.requestGeneralData(token_app.master_configurations - .TYPE_FILE_PAY_THROUGH_CASHIER_COMPLAINT), - floCloudAPI.requestGeneralData(token_app.master_configurations - .TYPE_FILE_WITHDRAWS_COMPLAINT), - floCloudAPI.requestGeneralData(token_app.master_configurations - .TYPE_PROCESSED_DEPOSITS_COMPLAINT), - floCloudAPI.requestGeneralData(token_app.master_configurations - .TYPE_PROCESSED_PAY_THROUGH_CASHIER_COMPLAINT), - floCloudAPI.requestGeneralData(token_app.master_configurations - .TYPE_PROCESSED_WITHDRAWS_COMPLAINT) - ]) - - return true; - } else { - - let promises = []; - - for (let cashier in token_app.master_configurations.cashiers) { - let p1 = { - func: floCloudAPI.requestGeneralData, - arg1: token_app.master_configurations.TYPE_DEPOSITS, - arg2: {receiverID: cashier, senderIDs: [myFloID]} + if(typeof request_args=='object' && typeof request_args.datatype=='string') { + return floCloudAPI.requestGeneralData(request_args.datatype); } - let p2 = { - func: floCloudAPI.requestGeneralData, - arg1: token_app.master_configurations.TYPE_WITHDRAWS, - arg2: {receiverID: cashier, senderIDs: [myFloID]} + await Promise.all([ + + create_root_structure(), + + floCloudAPI.requestGeneralData(token_app.master_configurations + .TYPE_FILE_DEPOSITS_COMPLAINT), + floCloudAPI.requestGeneralData(token_app.master_configurations + .TYPE_FILE_PAY_THROUGH_CASHIER_COMPLAINT), + floCloudAPI.requestGeneralData(token_app.master_configurations + .TYPE_FILE_WITHDRAWS_COMPLAINT), + floCloudAPI.requestGeneralData(token_app.master_configurations + .TYPE_PROCESSED_DEPOSITS_COMPLAINT), + floCloudAPI.requestGeneralData(token_app.master_configurations + .TYPE_PROCESSED_PAY_THROUGH_CASHIER_COMPLAINT), + floCloudAPI.requestGeneralData(token_app.master_configurations + .TYPE_PROCESSED_WITHDRAWS_COMPLAINT) + ]) + + return true; + } else { + + let promises = []; + + if(typeof request_args=='object' && typeof request_args.datatype=='string' + && request_args.datatype===token_app.master_configurations.TYPE_MSGES) { + await floCloudAPI.requestGeneralData(token_app.master_configurations.TYPE_MSGES, + {receiverID: myFloID}); + return true; + } else if(typeof request_args!=='object' || typeof request_args.datatype!=='string') { + let p4 = { + func: floCloudAPI.requestGeneralData, + arg1: token_app.master_configurations.TYPE_MSGES, + arg2: {receiverID: myFloID} + } + + promises.push(p4); } - let p3 = { - func: floCloudAPI.requestGeneralData, - arg1: token_app.master_configurations.TYPE_PAY_THROUGH_CASHIER, - arg2: {receiverID: cashier, senderIDs: [myFloID]} + for (let cashier in token_app.master_configurations.cashiers) { + if(typeof request_args=='object' && typeof request_args.datatype=='string') { + + promises.push({ + func: floCloudAPI.requestGeneralData, + arg1: request_args.datatype, + arg2: {receiverID: cashier, senderIDs: [myFloID]} + }) + + } else { + let p1 = { + func: floCloudAPI.requestGeneralData, + arg1: token_app.master_configurations.TYPE_DEPOSITS, + arg2: {receiverID: cashier, senderIDs: [myFloID]} + } + + let p2 = { + func: floCloudAPI.requestGeneralData, + arg1: token_app.master_configurations.TYPE_WITHDRAWS, + arg2: {receiverID: cashier, senderIDs: [myFloID]} + } + + let p3 = { + func: floCloudAPI.requestGeneralData, + arg1: token_app.master_configurations.TYPE_PAY_THROUGH_CASHIER, + arg2: {receiverID: cashier, senderIDs: [myFloID]} + } + + promises.push(p1, p2, p3); + } } - promises.push(p1, p2, p3); + await Promise.all(promises.map(prom => prom.func.call(floCloudAPI,prom.arg1, prom.arg2))); + + create_root_structure(); + + return promises; + } - let p4 = { - func: floCloudAPI.requestGeneralData, - arg1: token_app.master_configurations.TYPE_MSGES, - arg2: {receiverID: myFloID} - } - - promises.push(p4); - - await Promise.all(promises.map(prom => prom.func.call(floCloudAPI,prom.arg1, prom.arg2))); - - create_root_structure(); - - return promises; - } - } - } - + - + \ No newline at end of file