Merge pull request #17 from ranchimall/ui-work
Added filtering option for payments history
This commit is contained in:
commit
0abd0e8589
68
css/main.css
68
css/main.css
@ -123,7 +123,7 @@ button:not(:disabled) {
|
|||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
letter-spacing: 0.05em;
|
letter-spacing: 0.05em;
|
||||||
padding: 1rem;
|
padding: 0.8rem 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-only {
|
.icon-only {
|
||||||
@ -341,6 +341,10 @@ ul {
|
|||||||
align-self: center;
|
align-self: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.align-self-end {
|
||||||
|
align-self: end;
|
||||||
|
}
|
||||||
|
|
||||||
.justify-self-center {
|
.justify-self-center {
|
||||||
justify-self: center;
|
justify-self: center;
|
||||||
}
|
}
|
||||||
@ -906,6 +910,68 @@ ul {
|
|||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#history .page__header {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#history_applied_filters_wrapper {
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
background-color: rgba(var(--background-color), 1);
|
||||||
|
z-index: 1;
|
||||||
|
position: -webkit-sticky;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.applied-filter {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding-left: 0.8rem;
|
||||||
|
border-radius: 0.3rem;
|
||||||
|
border: solid thin rgba(var(--text-color), 0.2);
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
.applied-filter button {
|
||||||
|
padding: 0.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-chip {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0.3rem 0.5rem;
|
||||||
|
border-radius: 0.3rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
border: solid thin rgba(var(--text-color), 0.2);
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
.category-chip:focus {
|
||||||
|
outline: solid var(--accent-color);
|
||||||
|
}
|
||||||
|
.category-chip input {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.category-chip span {
|
||||||
|
transition: transform 0.2s;
|
||||||
|
transform: translateX(-0.8rem);
|
||||||
|
}
|
||||||
|
.category-chip .icon {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s, transform 0.2s;
|
||||||
|
margin-right: 0.3rem;
|
||||||
|
fill: var(--accent-color);
|
||||||
|
transform: translateX(0.5rem);
|
||||||
|
}
|
||||||
|
.category-chip input:checked ~ .icon {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
.category-chip input:checked ~ span {
|
||||||
|
color: var(--accent-color);
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
|
||||||
#wallet_history_wrapper {
|
#wallet_history_wrapper {
|
||||||
margin-top: 1.5rem;
|
margin-top: 1.5rem;
|
||||||
padding-bottom: 3rem;
|
padding-bottom: 3rem;
|
||||||
|
|||||||
2
css/main.min.css
vendored
2
css/main.min.css
vendored
File diff suppressed because one or more lines are too long
@ -117,7 +117,7 @@ button {
|
|||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
letter-spacing: 0.05em;
|
letter-spacing: 0.05em;
|
||||||
padding: 1rem;
|
padding: 0.8rem 1rem;
|
||||||
}
|
}
|
||||||
.icon-only {
|
.icon-only {
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
@ -310,6 +310,9 @@ ul {
|
|||||||
.align-self-center {
|
.align-self-center {
|
||||||
align-self: center;
|
align-self: center;
|
||||||
}
|
}
|
||||||
|
.align-self-end {
|
||||||
|
align-self: end;
|
||||||
|
}
|
||||||
|
|
||||||
.justify-self-center {
|
.justify-self-center {
|
||||||
justify-self: center;
|
justify-self: center;
|
||||||
@ -855,6 +858,66 @@ ul {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#history {
|
||||||
|
.page__header {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#history_applied_filters_wrapper {
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
background-color: rgba(var(--background-color), 1);
|
||||||
|
z-index: 1;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
.applied-filter {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding-left: 0.8rem;
|
||||||
|
border-radius: 0.3rem;
|
||||||
|
border: solid thin rgba(var(--text-color), 0.2);
|
||||||
|
text-transform: capitalize;
|
||||||
|
button {
|
||||||
|
padding: 0.6rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.category-chip {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0.3rem 0.5rem;
|
||||||
|
border-radius: 0.3rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
border: solid thin rgba(var(--text-color), 0.2);
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
&:focus {
|
||||||
|
outline: solid var(--accent-color);
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
transition: transform 0.2s;
|
||||||
|
transform: translateX(-0.8rem);
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s, transform 0.2s;
|
||||||
|
margin-right: 0.3rem;
|
||||||
|
fill: var(--accent-color);
|
||||||
|
transform: translateX(0.5rem);
|
||||||
|
}
|
||||||
|
input:checked ~ .icon {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
input:checked ~ span {
|
||||||
|
color: var(--accent-color);
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#wallet_history_wrapper {
|
#wallet_history_wrapper {
|
||||||
margin-top: 1.5rem;
|
margin-top: 1.5rem;
|
||||||
padding-bottom: 3rem;
|
padding-bottom: 3rem;
|
||||||
|
|||||||
69
index.html
69
index.html
@ -288,12 +288,24 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
<section id="history" class="inner-page hide grid gap-1">
|
<section id="history" class="inner-page hide grid gap-1-5">
|
||||||
<div class="page__header">
|
<div class="page__header">
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<h4>Payments</h4>
|
<h4>Payments</h4>
|
||||||
<h1>history</h1>
|
<h1>history</h1>
|
||||||
</div>
|
</div>
|
||||||
|
<button class="button button--small align-self-end" onclick="showPopup('payments_filters_popup')">
|
||||||
|
<svg class="icon margin-right-0-5" 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="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" />
|
||||||
|
</svg>
|
||||||
|
Filters
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div id="history_applied_filters_wrapper" class="flex align-center hide gap-1">
|
||||||
|
<h5>Applied filters</h5>
|
||||||
|
<div id="history_applied_filters" class="flex gap-0-5"></div>
|
||||||
</div>
|
</div>
|
||||||
<ul id="payments_history" class="observe-empty-state"></ul>
|
<ul id="payments_history" class="observe-empty-state"></ul>
|
||||||
<div class=" empty-state gap-1 justify-center text-center">
|
<div class=" empty-state gap-1 justify-center text-center">
|
||||||
@ -664,6 +676,61 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</sm-popup>
|
</sm-popup>
|
||||||
|
<sm-popup id="payments_filters_popup">
|
||||||
|
<header slot="header" class="popup__header">
|
||||||
|
<div class="grid gap-1">
|
||||||
|
<button class="popup__header__close justify-self-start" onclick="hidePopup()">
|
||||||
|
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"
|
||||||
|
fill="#000000">
|
||||||
|
<path d="M0 0h24v24H0V0z" fill="none" />
|
||||||
|
<path
|
||||||
|
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<h3>Filters</h3>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<div id="history_filters_container" class="grid gap-2">
|
||||||
|
<div class="grid gap-1" id="payments_type_filter">
|
||||||
|
<h5>
|
||||||
|
Payments type
|
||||||
|
</h5>
|
||||||
|
<div class="flex gap-0-5">
|
||||||
|
<label class="category-chip interact">
|
||||||
|
<input type="radio" name="category" value="all" checked autocomplete="off" />
|
||||||
|
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24"
|
||||||
|
width="24px" fill="#000000">
|
||||||
|
<path d="M0 0h24v24H0V0z" fill="none" />
|
||||||
|
<path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z" />
|
||||||
|
</svg>
|
||||||
|
<span class="checkmark">All</span>
|
||||||
|
</label>
|
||||||
|
<label class="category-chip interact">
|
||||||
|
<input type="radio" name="category" value="sent" autocomplete="off" />
|
||||||
|
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24"
|
||||||
|
width="24px" fill="#000000">
|
||||||
|
<path d="M0 0h24v24H0V0z" fill="none" />
|
||||||
|
<path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z" />
|
||||||
|
</svg>
|
||||||
|
<span class="checkmark">Sent</span>
|
||||||
|
</label>
|
||||||
|
<label class="category-chip interact">
|
||||||
|
<input type="radio" name="category" value="received" autocomplete="off" />
|
||||||
|
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24"
|
||||||
|
width="24px" fill="#000000">
|
||||||
|
<path d="M0 0h24v24H0V0z" fill="none" />
|
||||||
|
<path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z" />
|
||||||
|
</svg>
|
||||||
|
<span class="checkmark">Received</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex align-center space-between">
|
||||||
|
<button class="button" onclick="resetPaymentsFilters()">Reset</button>
|
||||||
|
<button class="button button--primary cta" onclick="applyPaymentsFilters()">Filter</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</sm-popup>
|
||||||
<sm-popup id="topup_wallet_popup">
|
<sm-popup id="topup_wallet_popup">
|
||||||
<header slot="header" class="popup__header">
|
<header slot="header" class="popup__header">
|
||||||
<button class="popup__header__close justify-self-start" onclick="hidePopup()">
|
<button class="popup__header__close justify-self-start" onclick="hidePopup()">
|
||||||
|
|||||||
114
scripts/fn_ui.js
114
scripts/fn_ui.js
@ -504,6 +504,33 @@ const render = {
|
|||||||
`
|
`
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
paymentsHistory() {
|
||||||
|
let paymentTransactions = []
|
||||||
|
if (paymentsHistoryLoader)
|
||||||
|
paymentsHistoryLoader.clear()
|
||||||
|
getRef('payments_history').innerHTML = '<sm-spinner></sm-spinner>';
|
||||||
|
tokenAPI.getAllTxs(myFloID).then(({ transactions }) => {
|
||||||
|
for (const transactionId in transactions) {
|
||||||
|
paymentTransactions.push({
|
||||||
|
...tokenAPI.util.parseTxData(transactions[transactionId]),
|
||||||
|
txid: transactionId
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const filter = getRef('payments_type_filter').querySelector('input:checked').value;
|
||||||
|
if (filter !== 'all') {
|
||||||
|
let propToCheck = filter === 'sent' ? 'sender' : 'receiver';
|
||||||
|
paymentTransactions = paymentTransactions.filter(v => v[propToCheck] === myFloID)
|
||||||
|
}
|
||||||
|
if (paymentsHistoryLoader) {
|
||||||
|
paymentsHistoryLoader.update(paymentTransactions);
|
||||||
|
} else {
|
||||||
|
paymentsHistoryLoader = new LazyLoader('#payments_history', paymentTransactions, render.transactionCard);
|
||||||
|
}
|
||||||
|
paymentsHistoryLoader.init();
|
||||||
|
}).catch(e => {
|
||||||
|
console.error(e)
|
||||||
|
})
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function buttonLoader(id, show) {
|
function buttonLoader(id, show) {
|
||||||
@ -749,6 +776,93 @@ function executeUserAction() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleFilters() {
|
||||||
|
const animOptions = {
|
||||||
|
duration: 200,
|
||||||
|
easing: 'ease',
|
||||||
|
fill: 'forwards',
|
||||||
|
}
|
||||||
|
if (getRef('history_applied_filters_wrapper').classList.contains('hide') && getRef('history_applied_filters').children.length > 0) {
|
||||||
|
getRef('history_applied_filters_wrapper').classList.remove('hide')
|
||||||
|
const filtersContainerDimensions = getRef('history_applied_filters_wrapper').getBoundingClientRect();
|
||||||
|
getRef('history_applied_filters_wrapper').animate([
|
||||||
|
{
|
||||||
|
transform: `translateY(-1.5rem)`,
|
||||||
|
opacity: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
transform: `translateY(0)`,
|
||||||
|
opacity: 1
|
||||||
|
},
|
||||||
|
], animOptions)
|
||||||
|
getRef('payments_history').animate([
|
||||||
|
{ transform: `translateY(-${filtersContainerDimensions.height}px)` },
|
||||||
|
{ transform: `translateY(0)` },
|
||||||
|
], animOptions)
|
||||||
|
} else if (!getRef('history_applied_filters_wrapper').classList.contains('hide') && getRef('history_applied_filters').children.length === 0) {
|
||||||
|
getRef('history_applied_filters_wrapper').animate([
|
||||||
|
{
|
||||||
|
transform: `translateY(0)`,
|
||||||
|
opacity: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
transform: `translateY(-1.5rem)`,
|
||||||
|
opacity: 0
|
||||||
|
},
|
||||||
|
], animOptions)
|
||||||
|
.onfinish = () => {
|
||||||
|
getRef('history_applied_filters_wrapper').classList.add('hide')
|
||||||
|
}
|
||||||
|
const filtersContainerDimensions = getRef('history_applied_filters_wrapper').getBoundingClientRect();
|
||||||
|
const historyDimensions = getRef('payments_history').getBoundingClientRect();
|
||||||
|
getRef('payments_history').animate([
|
||||||
|
{ transform: `translateY(0)` },
|
||||||
|
{ transform: `translateY(-${historyDimensions.top - filtersContainerDimensions.top}px)` },
|
||||||
|
], animOptions).onfinish = (e) => {
|
||||||
|
e.target.commitStyles()
|
||||||
|
e.target.cancel()
|
||||||
|
getRef('payments_history').style.transform = '';
|
||||||
|
}
|
||||||
|
getRef('payments_type_filter').querySelector('input[value="all"]').checked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyPaymentsFilters() {
|
||||||
|
const filter = getRef('payments_type_filter').querySelector('input:checked').value;
|
||||||
|
getRef('history_applied_filters').innerHTML = ``;
|
||||||
|
if (filter !== 'all') {
|
||||||
|
getRef('history_applied_filters').append(
|
||||||
|
createElement('span', {
|
||||||
|
attributes: { 'data-filter': 'type', 'data-value': filter },
|
||||||
|
className: 'applied-filter',
|
||||||
|
innerHTML: `
|
||||||
|
<span class="applied-filter__title">${filter}</span>
|
||||||
|
<button class="remove-filter">
|
||||||
|
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>
|
||||||
|
</button>
|
||||||
|
`
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
toggleFilters()
|
||||||
|
render.paymentsHistory()
|
||||||
|
hidePopup()
|
||||||
|
}
|
||||||
|
function resetPaymentsFilters() {
|
||||||
|
getRef('payments_type_filter').querySelector('input[value="all"]').checked = true;
|
||||||
|
render.paymentsHistory()
|
||||||
|
hidePopup()
|
||||||
|
toggleFilters()
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate(getRef('history_applied_filters'), 'click', '.remove-filter', e => {
|
||||||
|
const filter = e.delegateTarget.parentNode.dataset.filter
|
||||||
|
const filterValue = e.delegateTarget.parentNode.dataset.value
|
||||||
|
e.delegateTarget.parentNode.remove()
|
||||||
|
render.paymentsHistory()
|
||||||
|
toggleFilters()
|
||||||
|
})
|
||||||
|
|
||||||
function changeUpi() {
|
function changeUpi() {
|
||||||
const upiId = getRef('upi_id').value.trim();
|
const upiId = getRef('upi_id').value.trim();
|
||||||
Cashier.updateUPI(upiId).then(() => {
|
Cashier.updateUPI(upiId).then(() => {
|
||||||
|
|||||||
@ -341,26 +341,7 @@ async function showPage(targetPage, options = {}) {
|
|||||||
})
|
})
|
||||||
break;
|
break;
|
||||||
case 'history':
|
case 'history':
|
||||||
const paymentTransactions = []
|
render.paymentsHistory()
|
||||||
if (paymentsHistoryLoader)
|
|
||||||
paymentsHistoryLoader.clear()
|
|
||||||
getRef('payments_history').innerHTML = '<sm-spinner></sm-spinner>';
|
|
||||||
tokenAPI.getAllTxs(myFloID).then(({ transactions }) => {
|
|
||||||
for (const transactionId in transactions) {
|
|
||||||
paymentTransactions.push({
|
|
||||||
...tokenAPI.util.parseTxData(transactions[transactionId]),
|
|
||||||
txid: transactionId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (paymentsHistoryLoader) {
|
|
||||||
paymentsHistoryLoader.update(paymentTransactions);
|
|
||||||
} else {
|
|
||||||
paymentsHistoryLoader = new LazyLoader('#payments_history', paymentTransactions, render.transactionCard);
|
|
||||||
}
|
|
||||||
paymentsHistoryLoader.init();
|
|
||||||
}).catch(e => {
|
|
||||||
console.error(e)
|
|
||||||
})
|
|
||||||
break;
|
break;
|
||||||
case 'requests':
|
case 'requests':
|
||||||
const paymentRequests = [];
|
const paymentRequests = [];
|
||||||
@ -644,6 +625,9 @@ class LazyLoader {
|
|||||||
this.init = this.init.bind(this)
|
this.init = this.init.bind(this)
|
||||||
this.clear = this.clear.bind(this)
|
this.clear = this.clear.bind(this)
|
||||||
}
|
}
|
||||||
|
get elements() {
|
||||||
|
return this.arrayOfElements
|
||||||
|
}
|
||||||
init() {
|
init() {
|
||||||
this.intersectionObserver = new IntersectionObserver((entries, observer) => {
|
this.intersectionObserver = new IntersectionObserver((entries, observer) => {
|
||||||
entries.forEach(entry => {
|
entries.forEach(entry => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user