Added filtering option for payments history
This commit is contained in:
parent
9d6b52fc8b
commit
a137d0a237
68
css/main.css
68
css/main.css
@ -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
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-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;
|
||||
|
||||
69
index.html
69
index.html
@ -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()">
|
||||
|
||||
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) {
|
||||
@ -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(() => {
|
||||
|
||||
@ -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 => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user