UI/UX update

-- added transaction details when user receives FLO from cashier on low balance
This commit is contained in:
sairaj mote 2022-06-08 17:35:38 +05:30
parent 56910d5e98
commit 46904b2411
6 changed files with 72 additions and 60 deletions

View File

@ -1422,7 +1422,6 @@ ol li::before {
color: rgba(var(--text-color), 0.8);
}
.wallet-request__status {
text-transform: capitalize;
text-align: right;
}
.wallet-request__status .icon {
@ -1549,6 +1548,10 @@ ol li::before {
gap: 1rem;
grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
}
body[data-theme=dark] #main_navbar {
background-color: rgba(0, 0, 0, 0.2);
}
}
@media screen and (min-width: 56rem) {
#main_card {

2
css/main.min.css vendored

File diff suppressed because one or more lines are too long

View File

@ -1328,7 +1328,6 @@ ol {
color: rgba(var(--text-color), 0.8);
}
&__status {
text-transform: capitalize;
text-align: right;
.icon {
margin-left: 0.3rem;
@ -1414,7 +1413,6 @@ ol {
#main_header {
grid-area: header;
}
#main_navbar {
grid-area: nav;
border-top: none;
@ -1449,6 +1447,11 @@ ol {
gap: 1rem;
grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
}
body[data-theme="dark"] {
#main_navbar {
background-color: rgba(0 0 0/ 0.2);
}
}
}
@media screen and (min-width: 56rem) {
#main_card {

View File

@ -77,7 +77,7 @@
<section>
<h1 class="h2">Sign In</h1>
<p>Welcome back, glad to see you again</p>
<sm-form>
<sm-form id="sign_in_form">
<sm-input id="private_key_field" type="password" placeholder="FLO private key"
error-text="Private key is invalid" data-private-key required></sm-input>
<sm-button id="sign_in_button" variant="primary" disabled>Sign In</sm-button>
@ -478,17 +478,7 @@
</button>
<h4 id="transaction__type"></h4>
</div>
<div class="grid gap-1">
<div id="transaction__amount"></div>
<div id="transaction__remark" class="hide"></div>
<div class="flex align-center" style="font-size: 0.8rem;">
<time id="transaction__time"></time>
<div class="bullet-point"></div>
<span id="transaction__status"></span>
</div>
</div>
<a id="transaction__link" target="_blank" rel="noopener noreferrer">See transaction on blockchain</a>
<p id="transaction__note" class="hide flex flex-direction-column gap-0-5"></p>
<div id="transaction_details" class="grid gap-2"></div>
</div>
<section id="settings" class="inner-page hide">
<div class="page__header">
@ -799,7 +789,7 @@
<h4>Top-up wallet</h4>
<p>Add money to your wallet</p>
</div>
<sm-input id="request_cashier_amount" type="number" min="1" error-text="Amount should al least be ₹1"
<sm-input id="request_cashier_amount" type="number" min="10" error-text="Amount should at least be ₹10"
name="amount" placeholder="Amount" autofocus animate required>
<svg class="icon" slot="icon" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24"
height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
@ -1271,12 +1261,11 @@
await floExchangeAPI.init("FMxYC7gYZhouzqtHZukGnPiQ8nvG4CMzXM", "exchange")
console.log('Exchange API initialized!')
floDapps.launchStartUp().then(result => {
console.log(`Welcome ${myFloID}`);
floGlobals.savedIds = {};
floGlobals.savedUserData = {
upiIds: {}
}
console.log(`Welcome ${myFloID}`);
document.querySelectorAll('.logged-in-user-id').forEach(elem => elem.value = myFloID);
floGlobals.isSubAdmin = floGlobals.subAdmins.includes(myFloID)
refreshBalance()
@ -1309,7 +1298,9 @@
floGlobals.loaded = true
}).catch(error => console.error(error))
}
}).catch(error => console.error(error))
}).catch(error => {
console.error(error)
})
}
</script>
</body>

View File

@ -587,16 +587,16 @@ const render = {
walletRequestCard(details) {
const { time, message: { mode, amount }, note, tag, vectorClock } = details;
const clone = getRef('wallet_request_template').content.cloneNode(true).firstElementChild.firstElementChild;
const type = mode === 'cash-to-token' ? 'Wallet top-up' : 'Withdraw';
const type = mode === 'cash-to-token' ? 'Top-up' : 'Withdraw';
let status = tag ? tag : (note ? 'REJECTED' : "PENDING");
clone.classList.add(status.toLowerCase());
clone.classList.add(mode === 'cash-to-token' ? 'added' : 'withdrawn');
clone.dataset.vc = vectorClock;
clone.href = `#/transaction?transactionId=${vectorClock}&type=wallet`;
clone.querySelector('.wallet-request__icon').innerHTML = mode === 'cash-to-token' ?
`<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none" /><path d="M21 18v1c0 1.1-.9 2-2 2H5c-1.11 0-2-.9-2-2V5c0-1.1.89-2 2-2h14c1.1 0 2 .9 2 2v1h-9c-1.11 0-2 .9-2 2v8c0 1.1.89 2 2 2h9zm-9-2h10V8H12v8zm4-2.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z" /></svg>`
:
`<svg class="icon" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24" /></g><g><g><rect height="7" width="3" x="4" y="10" /><rect height="7" width="3" x="10.5" y="10" /><rect height="3" width="20" x="2" y="19" /><rect height="7" width="3" x="17" y="10" /><polygon points="12,1 2,6 2,8 22,8 22,6" /></g></g></svg>`;
`<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none" /><path d="M21 18v1c0 1.1-.9 2-2 2H5c-1.11 0-2-.9-2-2V5c0-1.1.89-2 2-2h14c1.1 0 2 .9 2 2v1h-9c-1.11 0-2 .9-2 2v8c0 1.1.89 2 2 2h9zm-9-2h10V8H12v8zm4-2.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z" /></svg>`
:
`<svg class="icon" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24" /></g><g><g><rect height="7" width="3" x="4" y="10" /><rect height="7" width="3" x="10.5" y="10" /><rect height="3" width="20" x="2" y="19" /><rect height="7" width="3" x="17" y="10" /><polygon points="12,1 2,6 2,8 22,8 22,6" /></g></g></svg>`;
clone.querySelector('.wallet-request__details').textContent = type;
clone.querySelector('.wallet-request__amount').textContent = formatAmount(amount);
clone.querySelector('.wallet-request__time').textContent = getFormattedTime(time);
@ -604,6 +604,12 @@ const render = {
if (status === 'REJECTED') {
icon = `<svg class="icon failed" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/></svg>`
clone.querySelector('.wallet-request__status').innerHTML = `Failed ${icon}`;
clone.querySelector('.wallet-request__status').classList.add('capitalize')
}
if (status === 'COMPLETED' && note.includes('#')) {
const [txid,finalAmount] = note.split('#');
clone.querySelector('.wallet-request__amount').textContent = formatAmount(parseFloat(finalAmount));
clone.querySelector('.wallet-request__status').innerHTML = `<b style="color:var(--green)">+ 1 FLO</b>&nbsp; worth ${formatAmount(amount - parseFloat(finalAmount))}`;
}
return clone;
},
@ -1079,8 +1085,18 @@ function changeUpi() {
notify(err, 'error');
});
}
function getSignedIn() {
function getSignedIn(passwordType) {
return new Promise((resolve, reject) => {
if (passwordType === 'PIN/Password') {
getRef('private_key_field').removeAttribute('data-private-key');
getRef('private_key_field').setAttribute('placeholder', 'PIN');
getRef('private_key_field').customValidation = null
} else {
getRef('private_key_field').dataset.privateKey = ''
getRef('private_key_field').setAttribute('placeholder', 'FLO private key');
getRef('private_key_field').customValidation = floCrypto.getPubKeyHex
}
if (window.location.hash.includes('sign_in') || window.location.hash.includes('sign_up')) {
showPage(window.location.hash);
} else {

View File

@ -258,7 +258,6 @@ window.addEventListener('hashchange', e => showPage(window.location.hash))
window.addEventListener("load", () => {
document.body.classList.remove('hide')
document.querySelectorAll('sm-input[data-flo-id]').forEach(input => input.customValidation = floCrypto.validateAddr)
document.querySelectorAll('sm-input[data-private-key]').forEach(input => input.customValidation = floCrypto.getPubKeyHex)
document.addEventListener('keyup', (e) => {
if (e.key === 'Escape') {
closePopup()
@ -440,22 +439,16 @@ async function showPage(targetPage, options = {}) {
case 'transaction':
let transactionDetails
let status
getRef('transaction__link').classList.add('hide')
getRef('transaction__remark').classList.add('hide')
getRef('transaction__note').classList.add('hide')
let shouldRender = {}
if (params.type === 'request') {
transactionDetails = User.moneyRequests[params.transactionId]
const { message: { remark }, note, tag } = transactionDetails
status = note ? note.split(':')[0] : 'PENDING';
getRef('transaction__type').textContent = 'Payment request'
if (status === 'PAID') {
getRef('transaction__link').href = `https://flosight.duckdns.org/tx/${note.split(':')[1].trim()}`
getRef('transaction__link').classList.remove('hide')
}
if (remark !== '') {
getRef('transaction__remark').textContent = remark
getRef('transaction__remark').classList.remove('hide')
}
if (status === 'PAID')
shouldRender['txLink'] = `https://flosight.duckdns.org/tx/${note.split(':')[1].trim()}`;
if (remark !== '')
shouldRender.txRemark = remark
} else if (params.type === 'wallet') {
transactionDetails = User.cashierRequests[params.transactionId]
console.log(transactionDetails)
@ -463,45 +456,51 @@ async function showPage(targetPage, options = {}) {
status = tag ? tag : (note ? 'REJECTED' : "PENDING");
getRef('transaction__type').textContent = mode === 'cash-to-token' ? 'Wallet top-up' : 'Withdraw';
if (status === 'COMPLETED') {
getRef('transaction__link').href = `https://flosight.duckdns.org/tx/${mode === 'cash-to-token' ? note : token_txid}`
getRef('transaction__link').classList.remove('hide')
shouldRender['txLink'] = `https://flosight.duckdns.org/tx/${mode === 'cash-to-token' ? note : token_txid}`
} else if (status === 'REJECTED') {
getRef('transaction__note').innerHTML = `<svg class="icon failed" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"></path><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"></path></svg> ${note.split(':')[1]}`
getRef('transaction__note').classList.remove('hide')
shouldRender.txNote = html`<svg class="icon failed" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"></path><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"></path></svg> ${note.split(':')[1]}`
}
if (mode === 'cash-to-token') {
if (status === 'COMPLETED') {
if (txCode) {
getRef('transaction__note').textContent = `Transaction code: ${txCode}`
shouldRender.txNote = `Transaction code: ${txCode}`
} else if (upi_txid) {
getRef('transaction__note').textContent = `UPI Transaction ID: ${upi_txid}`
shouldRender.txNote = `UPI Transaction ID: ${upi_txid}`
}
getRef('transaction__note').classList.remove('hide')
} else if (status === 'REJECTED') {
const reason = cashierRejectionErrors.hasOwnProperty(note.split(':')[1]) ? cashierRejectionErrors[note.split(':')[1]] : note.split(':')[1]
getRef('transaction__note').innerHTML = `
<svg class="icon failed" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"></path><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"></path></svg>
${reason}
`
getRef('transaction__note').classList.remove('hide')
} else {
getRef('transaction__note').classList.add('hide')
getRef('transaction__note').textContent = ''
shouldRender.txNote = html` <svg class="icon failed" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"></path><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"></path></svg> ${reason} `
}
} else {
if (status === 'PENDING') {
getRef('transaction__note').textContent = `Pending transfer of ${formatAmount(amount)} to bank account linked to ${upi_id}`
shouldRender.txNote = `Pending transfer of ${formatAmount(amount)} to bank account linked to ${upi_id}`
} else if (status === 'COMPLETED') {
getRef('transaction__note').textContent = `Transfer of ${formatAmount(amount)} to bank account linked to ${upi_id} completed`
shouldRender.txNote = `Transfer of ${formatAmount(amount)} to bank account linked to ${upi_id} completed`
}
getRef('transaction__note').classList.remove('hide')
}
}
const { message: { amount }, time } = transactionDetails
getRef('transaction__time').textContent = getFormattedTime(time)
getRef('transaction__amount').textContent = formatAmount(amount)
getRef('transaction__status').textContent = status
const { message: { amount }, time, note } = transactionDetails
let txAmount = formatAmount(amount)
if (status === 'COMPLETED' && note.includes('#')) {
const [txid,finalAmount] = note.split('#');
txAmount = formatAmount(parseFloat(finalAmount));
shouldRender.txNote = `Also received 1 FLO worth of ${formatAmount(amount - parseFloat(finalAmount))} due to low FLO balance`;
}
renderElem(getRef('transaction_details'), html`
<div class="grid gap-1">
<div id="transaction__amount">${txAmount}</div>
${shouldRender.remark ? html`<div id="transaction__remark">${shouldRender.remark}</div>` : ''}
<div class="flex align-center" style="font-size: 0.8rem;">
<time id="transaction__time">${getFormattedTime(time)}</time>
<div class="bullet-point"></div>
<span id="transaction__status">${status}</span>
</div>
</div>
${shouldRender.txLink ? html`<a id="transaction__link" href="${shouldRender.txLink}" target="_blank">See transaction
on blockchain</a>` : ''}
${shouldRender.txNote ? html`<div id="transaction__note" class="flex flex-direction-column gap-0-5">${shouldRender.txNote}</div>` : ''}
`)
break;
case 'settings':
renderSavedUpiIds()