Added filtering option for payments history

This commit is contained in:
sairaj mote 2022-04-30 00:14:18 +05:30
parent 9d6b52fc8b
commit a137d0a237
6 changed files with 318 additions and 24 deletions

View File

@ -124,7 +124,7 @@ button:not(:disabled) {
font-size: 0.8rem;
font-weight: 700;
letter-spacing: 0.05em;
padding: 1rem;
padding: 0.8rem 1rem;
}
.icon-only {
@ -342,6 +342,10 @@ ul {
align-self: center;
}
.align-self-end {
align-self: end;
}
.justify-self-center {
justify-self: center;
}
@ -907,6 +911,68 @@ ul {
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 {
margin-top: 1.5rem;
padding-bottom: 3rem;

2
css/main.min.css vendored

File diff suppressed because one or more lines are too long

View File

@ -117,7 +117,7 @@ button {
font-size: 0.8rem;
font-weight: 700;
letter-spacing: 0.05em;
padding: 1rem;
padding: 0.8rem 1rem;
}
.icon-only {
padding: 0.5rem;
@ -310,6 +310,9 @@ ul {
.align-self-center {
align-self: center;
}
.align-self-end {
align-self: end;
}
.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 {
margin-top: 1.5rem;
padding-bottom: 3rem;

View File

@ -288,12 +288,24 @@
</div>
</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="grid">
<h4>Payments</h4>
<h1>history</h1>
</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>
<ul id="payments_history" class="observe-empty-state"></ul>
<div class=" empty-state gap-1 justify-center text-center">
@ -664,6 +676,61 @@
</div>
</section>
</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">
<header slot="header" class="popup__header">
<button class="popup__header__close justify-self-start" onclick="hidePopup()">

View File

@ -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) {
@ -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() {
const upiId = getRef('upi_id').value.trim();
Cashier.updateUPI(upiId).then(() => {

View File

@ -341,26 +341,7 @@ async function showPage(targetPage, options = {}) {
})
break;
case 'history':
const 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
})
}
if (paymentsHistoryLoader) {
paymentsHistoryLoader.update(paymentTransactions);
} else {
paymentsHistoryLoader = new LazyLoader('#payments_history', paymentTransactions, render.transactionCard);
}
paymentsHistoryLoader.init();
}).catch(e => {
console.error(e)
})
render.paymentsHistory()
break;
case 'requests':
const paymentRequests = [];
@ -644,6 +625,9 @@ class LazyLoader {
this.init = this.init.bind(this)
this.clear = this.clear.bind(this)
}
get elements() {
return this.arrayOfElements
}
init() {
this.intersectionObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {