Added account withdrawal and repayment steps in UI

This commit is contained in:
sairaj mote 2021-09-04 17:05:44 +05:30
parent 7e7032e7cd
commit 611f59b9ce
5 changed files with 462 additions and 169 deletions

View File

@ -1342,10 +1342,12 @@ spinner.innerHTML = `
}
:host{
--accent-color: #4d2588;
--height: 1.6rem;
--width: 1.6rem;
}
.loader {
height: 1.6rem;
width: 1.6rem;
height: var(--height);
width: var(--weight);
stroke-width: 8;
overflow: visible;
stroke: var(--accent-color);

View File

@ -655,11 +655,11 @@ details[open] > summary .icon {
}
#notifications,
#transactions {
#history {
padding-bottom: 5rem;
}
#notifications .activity-card,
#transactions .activity-card {
#history .activity-card {
padding: 1rem 1.5rem;
}
@ -720,6 +720,9 @@ details[open] > summary .icon {
font-weight: 500;
color: rgba(0, 0, 0, 0.7);
}
.status-tag:not(:empty) .icon {
margin-right: 0.3rem;
}
.status-tag:not(:empty).success, .status-tag:not(:empty).active {
color: var(--green);
background-color: rgba(0, 230, 118, 0.1);
@ -871,42 +874,68 @@ details[open] > summary .icon {
font-weight: 700;
}
#transaction {
#transaction,
#account {
grid-template-rows: auto 1fr;
gap: 1.5rem 0;
padding: 1.5rem 0;
-ms-flex-line-pack: start;
align-content: flex-start;
}
#transaction_top {
position: relative;
-ms-flex-line-pack: start;
align-content: flex-start;
#transaction section,
#account_details {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
}
#transaction_detail__icon {
#transaction_top,
#account_top {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
justify-items: flex-start;
position: relative;
}
#transaction_detail__icon,
#account_detail__icon {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
background-color: var(--accent-color);
border-radius: 40%;
padding: 1rem;
aspect-ratio: 1/1;
padding: 0.8rem;
justify-self: flex-start;
-ms-flex-item-align: start;
align-self: flex-start;
}
#transaction_detail__icon .icon {
height: 2rem;
width: 2rem;
#transaction_detail__icon .icon,
#account_detail__icon .icon {
height: 1.5rem;
width: 1.5rem;
fill: rgba(var(--background-color), 1);
}
#transaction_detail__amount {
#transaction_detail__amount,
#account_detail__amount {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
font-size: 1.8rem;
font-weight: 700;
}
#transaction_detail__amount::before {
#transaction_detail__amount::before,
#account_detail__amount::before {
font-weight: 500;
font-size: 1rem;
-ms-flex-item-align: start;
@ -914,12 +943,92 @@ details[open] > summary .icon {
content: "₹";
}
#transaction_detail__time {
#transaction_detail__time,
#account_detail__time {
font-size: 0.8rem;
color: rgba(var(--text-color), 0.8);
margin-right: 1rem;
}
#account_process {
display: grid;
-ms-flex-line-pack: start;
align-content: flex-start;
gap: 2rem;
}
#account_process__type {
margin-top: 1.5rem;
font-size: 0.9rem;
font-weight: 500;
color: rgba(var(--text-color), 0.8);
}
#account_process__amount {
font-size: 1.5rem;
}
.account-step {
grid-template-columns: auto minmax(0, 1fr);
grid-template-areas: "step-icon step-title" "step-icon step-description";
gap: 0.3rem 0.8rem;
}
.account-step sm-spinner {
--height: 1rem;
--width: 1rem;
}
.account-step:not(:last-of-type)::after {
position: relative;
content: "";
height: 3rem;
width: 0.1rem;
margin: 0.5rem 0 1rem 0;
margin-left: 0.7rem;
background-color: var(--green);
}
.account-step .step__icon {
grid-area: step-icon;
}
.account-step .icon {
height: 1.5rem;
width: 1.5rem;
}
.account-step:not(.loading) .step__title {
grid-area: step-title;
font-weight: 500;
font-size: 0.9rem;
padding: 0.2rem 0;
}
.account-step .step__description {
grid-area: step-description;
font-size: 0.8rem;
}
@-webkit-keyframes slide-down {
from {
opacity: 0;
-webkit-transform: translateY(-1rem);
transform: translateY(-1rem);
}
to {
opacity: 1;
-webkit-transform: none;
transform: none;
}
}
@keyframes slide-down {
from {
opacity: 0;
-webkit-transform: translateY(-1rem);
transform: translateY(-1rem);
}
to {
opacity: 1;
-webkit-transform: none;
transform: none;
}
}
@media screen and (max-width: 640px) {
sm-button {
--padding: 1rem;
@ -953,22 +1062,9 @@ details[open] > summary .icon {
margin-top: 0.3rem;
}
#transaction_top {
text-align: center;
}
#transaction_detail__status {
justify-self: center;
}
#transaction_detail__icon {
justify-self: center;
}
#transaction_detail__amount {
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
#transaction_action_button,
#account_action_button {
margin-top: auto;
}
}
@media screen and (min-width: 640px) {
@ -978,7 +1074,7 @@ details[open] > summary .icon {
}
.page-layout {
grid-template-columns: 1fr 80vw 1fr;
grid-template-columns: 1fr 90vw 1fr;
}
#homepage {
@ -1023,13 +1119,12 @@ details[open] > summary .icon {
background-color: rgba(var(--background-color), 1);
}
#transaction_top {
#transaction_top,
#account_top {
overflow: hidden;
padding: 1.8rem;
border-radius: 0.5rem;
background-color: var(--foreground-color);
-webkit-box-shadow: 0 1rem 1.5rem -0.8rem rgba(0, 0, 0, 0.1);
box-shadow: 0 1rem 1.5rem -0.8rem rgba(0, 0, 0, 0.1);
border: solid thin rgba(var(--text-color), 0.2);
}
#transaction_detail__status {
@ -1050,6 +1145,10 @@ details[open] > summary .icon {
}
}
@media screen and (min-width: 1024px) {
.page-layout {
grid-template-columns: 1fr 80vw 1fr;
}
.card {
padding: 2rem;
}
@ -1068,11 +1167,17 @@ details[open] > summary .icon {
margin-left: 0.5rem;
}
#transaction section {
#transaction section,
#account_details {
display: grid;
grid-template-columns: 18rem minmax(0, 1fr);
}
}
@media screen and (min-width: 1920px) {
.page-layout {
grid-template-columns: 1fr 70vw 1fr;
}
}
@media (any-hover: hover) {
::-webkit-scrollbar {
width: 0.5rem;

2
css/main.min.css vendored

File diff suppressed because one or more lines are too long

View File

@ -573,7 +573,7 @@ details {
}
}
#notifications,
#transactions{
#history{
padding-bottom: 5rem;
.activity-card{
padding: 1rem 1.5rem;
@ -629,6 +629,9 @@ details {
padding: 0.3rem 0.4rem;
font-weight: 500;
color: rgba($color: #000000, $alpha: 0.7);
.icon{
margin-right: 0.3rem;
}
&.success,
&.active{
color: var(--green);
@ -757,28 +760,41 @@ details {
font-weight: 700;
}
}
#transaction{
#transaction,
#account{
grid-template-rows: auto 1fr;
gap: 1.5rem 0;
padding: 1.5rem 0;
align-content: flex-start;
}
#transaction_top{
position: relative;
align-content: flex-start;
#transaction section,
#account_details{
display: flex;
flex-direction: column;
}
#transaction_detail__icon{
#transaction_top,
#account_top{
display: flex;
flex-direction: column;
justify-items: flex-start;
position: relative;
}
#transaction_detail__icon,
#account_detail__icon{
display: flex;
background-color: var(--accent-color);
border-radius: 40%;
padding: 1rem;
aspect-ratio: 1/1;
padding: 0.8rem;
justify-self: flex-start;
align-self: flex-start;
.icon{
height: 2rem;
width: 2rem;
height: 1.5rem;
width: 1.5rem;
fill: rgba(var(--background-color), 1);
}
}
#transaction_detail__amount{
#transaction_detail__amount,
#account_detail__amount{
display: flex;
font-size: 1.8rem;
font-weight: 700;
@ -789,11 +805,74 @@ details {
content: '';
}
}
#transaction_detail__time{
#transaction_detail__time,
#account_detail__time{
font-size: 0.8rem;
color: rgba(var(--text-color), 0.8);
margin-right: 1rem;
}
#account_process{
display: grid;
align-content: flex-start;
gap: 2rem;
}
#account_process__type{
margin-top: 1.5rem;
font-size: 0.9rem;
font-weight: 500;
color: rgba(var(--text-color), 0.8);
}
#account_process__amount{
font-size: 1.5rem;
}
.account-step{
grid-template-columns: auto minmax(0, 1fr);
grid-template-areas: 'step-icon step-title' 'step-icon step-description';
gap: 0.3rem 0.8rem;
sm-spinner{
--height: 1rem;
--width: 1rem;
}
&:not(:last-of-type)::after{
position: relative;
content: '';
height: 3rem;
width: 0.1rem;
margin: 0.5rem 0 1rem 0;
margin-left: 0.7rem;
background-color: var(--green);
}
.step__icon{
grid-area: step-icon;
}
.icon{
height: 1.5rem;
width: 1.5rem;
}
&:not(.loading){
.step__title{
grid-area: step-title;
font-weight: 500;
font-size: 0.9rem;
padding: 0.2rem 0;
}
}
.step__description{
grid-area: step-description;
font-size: 0.8rem;
}
}
@keyframes slide-down {
from{
opacity: 0;
transform: translateY(-1rem);
}
to{
opacity: 1;
transform: none;
}
}
@media screen and (max-width: 640px) {
sm-button{
--padding: 1rem;
@ -816,17 +895,9 @@ details {
margin-top: 0.3rem;
}
}
#transaction_top{
text-align: center;
}
#transaction_detail__status{
justify-self: center;
}
#transaction_detail__icon{
justify-self: center;
}
#transaction_detail__amount{
justify-content: center;
#transaction_action_button,
#account_action_button{
margin-top: auto;
}
}
@media screen and (min-width: 640px) {
@ -835,7 +906,7 @@ details {
--width: 24rem;
}
.page-layout{
grid-template-columns: 1fr 80vw 1fr;
grid-template-columns: 1fr 90vw 1fr;
}
#homepage{
background-color: var(--foreground-color);
@ -875,13 +946,14 @@ details {
grid-area: user-section;
background-color: rgba(var(--background-color), 1);
}
#transaction_top{
#transaction_top,
#account_top{
overflow: hidden;
padding: 1.8rem;
border-radius: 0.5rem;
// border: solid thin rgba(var(--text-color), 0.16);
background-color: var(--foreground-color);
box-shadow: 0 1rem 1.5rem -0.8rem rgba(0, 0, 0, 0.1);
border: solid thin rgba(var(--text-color), 0.2);
// background-color: var(--foreground-color);
// box-shadow: 0 0 0.1rem rgba(0, 0, 0, 0.1), 0 1rem 1.5rem -0.8rem rgba(0, 0, 0, 0.1);
}
#transaction_detail__status{
justify-self: flex-start;
@ -899,6 +971,9 @@ details {
}
}
@media screen and (min-width: 1024px) {
.page-layout{
grid-template-columns: 1fr 80vw 1fr;
}
.card{
padding: 2rem;
}
@ -914,11 +989,15 @@ details {
margin-left: 0.5rem;
}
}
#transaction{
section{
display: grid;
grid-template-columns: 18rem minmax(0, 1fr);
}
#transaction section,
#account_details{
display: grid;
grid-template-columns: 18rem minmax(0, 1fr);
}
}
@media screen and (min-width: 1920px) {
.page-layout{
grid-template-columns: 1fr 70vw 1fr;
}
}
@media (any-hover: hover) {

View File

@ -134,12 +134,12 @@
Notifications
</span>
</a>
<a href="#/homepage/transactions" class="nav-item">
<a href="#/homepage/history" class="nav-item">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 20 20" fill="currentColor">
<path d="M5 12a1 1 0 102 0V6.414l1.293 1.293a1 1 0 001.414-1.414l-3-3a1 1 0 00-1.414 0l-3 3a1 1 0 001.414 1.414L5 6.414V12zM15 8a1 1 0 10-2 0v5.586l-1.293-1.293a1 1 0 00-1.414 1.414l3 3a1 1 0 001.414 0l3-3a1 1 0 00-1.414-1.414L15 13.586V8z" />
</svg>
<span class="nav-item__title">
Transactions
History
</span>
</a>
<a href="#/homepage/settings" class="nav-item">
@ -192,7 +192,7 @@
<div id="all_responses_list" class="observe-empty-state grid"></div>
<p class="empty-state">No notifications so far.</p>
</div>
<div id="transactions" class="sub-page hide-completely">
<div id="history" class="sub-page hide-completely">
<div id="all_requests_list" class="observe-empty-state grid"></div>
<p class="empty-state">No notifications so far.</p>
</div>
@ -281,6 +281,34 @@
</div>
</section>
</article>
<article id="account" class="page hide-completely page-layout">
<button class="icon-button justify-self-start" onclick="history.back()">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z" clip-rule="evenodd" />
</svg>
</button>
<section id="account_details">
<div id="account_top" class="grid gap-1-5">
<div class="flex align-center space-between">
<div id="account_detail__icon"></div>
<div id="account_detail__status"></div>
</div>
<div class="grid gap-0-5">
<div id="account_detail__type"></div>
<h3 id="account_detail__amount"></h3>
</div>
<time id="account_detail__time"></time>
<sm-button id="account_action_button" onclick="processAccount()" variant="primary"></sm-button>
</div>
</section>
<section id="account_process" class="hide-completely">
<div class="grid gap-0-5">
<div id="account_process__type"></div>
<h4 id="account_process__amount"></h4>
</div>
<div id="account_process__steps"></div>
</section>
</article>
<template id="request_template">
<a class="activity-card activity-card--request interact">
<div class="activity-card__icon"></div>
@ -311,10 +339,15 @@
<time class="activity-card__time"></time>
</a>
</template>
<template id="account_step_template">
<div class="account-step grid">
<div class="step__icon"></div>
<span class="step__title"></span>
<p class="step__description"></p>
</div>
</template>
<script id="ui_utils">
// Global variables
const appPages = ['sign_in', 'sign_up', 'homepage', 'transaction'];
const appSubPages = ['dashboard', 'notifications', 'transactions', 'settings']
const domRefs = {};
let timerId;
const currentYear = new Date().getFullYear();
@ -575,6 +608,7 @@
const pagesData = {
openedPages: [],
openedSubPages: [],
params: {}
}
let responseLoader
@ -611,6 +645,7 @@
if (searchParams) {
const urlSearchParams = new URLSearchParams('?' + searchParams);
params = Object.fromEntries(urlSearchParams.entries());
pagesData.params = params
}
if(pagesData.lastPage !== pageId){
switch (pageId) {
@ -627,6 +662,9 @@
case 'transaction':
showTransactionDetails(params)
break;
case 'account':
showAccountDetails(params)
break;
}
document.querySelector('.page:not(.hide-completely)')?.classList.add('hide-completely')
getRef(pageId)?.classList.remove('hide-completely')
@ -655,17 +693,16 @@
accountLoader = new LazyLoader('#user_accounts', bank_app.accounts.reverse(), render.accountCard, {batchSize: 10})
accountLoader.init()
}
refreshBalance()
break;
case 'notifications':
if(pagesData.openedSubPages.includes(subPageId)){
responseLoader.reset()
}else{
responseLoader = new LazyLoader('#all_responses_list', getArrayOfObj(bank_app.viewAllResponses()).reverse(), render.responseCard, {batchSize: 10})
responseLoader = new LazyLoader('#all_responses_list', utils.getArrayOfObj(bank_app.viewAllResponses()).reverse(), render.responseCard, {batchSize: 10})
responseLoader.init()
}
break;
case 'transactions':
case 'history':
if(pagesData.openedSubPages.includes(subPageId)){
requestLoader.reset()
}else{
@ -756,7 +793,7 @@
this.updateEndIndex = this.arrayOfElements.length > this.batchSize ? this.batchSize : this.arrayOfElements.length
}
for (let index = this.updateStartIndex; index < this.updateEndIndex; index++) {
frag.append(this.renderFn(this.arrayOfElements[index]))
frag.append(this.renderFn(this.arrayOfElements[index], index))
}
this.lazyContainer.append(frag)
}
@ -771,35 +808,81 @@
}
</script>
<script id="ui_functions">
const render = {
requestCard(activityDetails = {}){
const {requestID, amount, rtype, timestamp, status} = activityDetails
const card = getRef('request_template').content.cloneNode(true).firstElementChild
let icon
let action = ''
switch(rtype){
const utils = {
getArrayOfObj(obj) {
const arrayOfObj = []
for (key in obj) {
arrayOfObj.push({id: key, ...obj[key]});
}
return arrayOfObj
},
getRelatedIcon(type){
let icon
switch(type){
case 'openDeposit':
case 'deposit':
icon = `
<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"><rect fill="none" height="24" width="24"/><g><path d="M19.83,7.5l-2.27-2.27c0.07-0.42,0.18-0.81,0.32-1.15C17.96,3.9,18,3.71,18,3.5C18,2.67,17.33,2,16.5,2 c-1.64,0-3.09,0.79-4,2l-5,0C4.46,4,2,6.46,2,9.5S4.5,21,4.5,21l5.5,0v-2h2v2l5.5,0l1.68-5.59L22,14.47V7.5H19.83z M13,9H8V7h5V9z M16,11c-0.55,0-1-0.45-1-1c0-0.55,0.45-1,1-1s1,0.45,1,1C17,10.55,16.55,11,16,11z"/></g></svg>
`
action = 'deposit'
break
case 'closeDeposit':
icon = `
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19.08,2.5H4.92A1.5,1.5,0,0,0,3.42,4V9.62a1.5,1.5,0,0,0,1.5,1.5H7v9a.87.87,0,0,0,.86.87h8.26a.87.87,0,0,0,.86-.87v-9h2.09a1.5,1.5,0,0,0,1.5-1.5V4A1.5,1.5,0,0,0,19.08,2.5ZM12,17.68a2.18,2.18,0,1,1,2.18-2.17A2.18,2.18,0,0,1,12,17.68Zm7.58-8.06a.5.5,0,0,1-.5.5H17V7.24h.76a.43.43,0,0,0,0-.86H6.25a.43.43,0,0,0,0,.86H7v2.88H4.92a.5.5,0,0,1-.5-.5V4a.5.5,0,0,1,.5-.5H19.08a.5.5,0,0,1,.5.5Z"/></svg>
`
action = 'withdraw'
break
case 'openLoan':
case 'loan':
icon = `
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12.65,8.5H10.42a5.18,5.18,0,0,0-4,1.95L3.75,13.74a5,5,0,0,0-.68,5.31l0,0h0a5.07,5.07,0,0,0,4.5,2.73h7.88A5.08,5.08,0,0,0,20,19.05h0a5.39,5.39,0,0,0,.43-1.2,4.91,4.91,0,0,0-1-4.06l-2.66-3.34A5.17,5.17,0,0,0,12.65,8.5Z"/><path d="M9.71,6.59h3.94A2.94,2.94,0,0,0,16,5.39h0a1.13,1.13,0,0,0-.23-1.57,1.11,1.11,0,0,0-.95-.18h0a1.2,1.2,0,0,1-.92-.18l-.28-.21a3.64,3.64,0,0,0-4.22,0h0a1.18,1.18,0,0,1-1,.16L8.2,3.35a1.13,1.13,0,0,0-1.36.84A1.17,1.17,0,0,0,7,5H7A3.18,3.18,0,0,0,9.71,6.59Z"/></svg>
`
action = 'Get loan'
break
case 'closeLoan':
icon = `
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6.42,9.17h0a1,1,0,0,0-1.57.2A7.54,7.54,0,0,0,4.19,11a1,1,0,0,0,1,1.24h0a1,1,0,0,0,.94-.7,5.61,5.61,0,0,1,.49-1.16A1,1,0,0,0,6.42,9.17Zm-1.26,5h0a1,1,0,0,0-1,1.25A8,8,0,0,0,4.84,17a1,1,0,0,0,1.57.19h0a1,1,0,0,0,.17-1.15A6.17,6.17,0,0,1,6.1,14.9,1,1,0,0,0,5.16,14.19Zm2.86,6a7.85,7.85,0,0,0,1.59.66,1,1,0,0,0,1.25-1v0a1,1,0,0,0-.7-.94A6.08,6.08,0,0,1,9,18.45a1,1,0,0,0-1.17.17l0,0A1,1,0,0,0,8,20.21ZM12.86,5V3.73a.64.64,0,0,0-1.09-.45l-3,3a.63.63,0,0,0,0,.9l3,3a.64.64,0,0,0,1.08-.46v-2a.36.36,0,0,1,.43-.35A6,6,0,0,1,13.54,19a1,1,0,0,0-.68.94h0a1,1,0,0,0,1.24,1,8,8,0,0,0-.95-15.56A.34.34,0,0,1,12.86,5Z"/></svg>
`
break
case 'success':
icon = `
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M6.267 3.455a3.066 3.066 0 001.745-.723 3.066 3.066 0 013.976 0 3.066 3.066 0 001.745.723 3.066 3.066 0 012.812 2.812c.051.643.304 1.254.723 1.745a3.066 3.066 0 010 3.976 3.066 3.066 0 00-.723 1.745 3.066 3.066 0 01-2.812 2.812 3.066 3.066 0 00-1.745.723 3.066 3.066 0 01-3.976 0 3.066 3.066 0 00-1.745-.723 3.066 3.066 0 01-2.812-2.812 3.066 3.066 0 00-.723-1.745 3.066 3.066 0 010-3.976 3.066 3.066 0 00.723-1.745 3.066 3.066 0 012.812-2.812zm7.44 5.252a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />
</svg>
`
break;
case 'pending':
icon = `
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clip-rule="evenodd" />
</svg>
`
break;
case 'failed':
icon = `
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
</svg>
`
break;
}
return icon
}
}
const render = {
requestCard(activityDetails = {}){
const {requestID, amount, rtype, timestamp, status} = activityDetails
const card = getRef('request_template').content.cloneNode(true).firstElementChild
const icon = utils.getRelatedIcon(rtype)
let action = ''
switch(rtype){
case 'openDeposit':
action = 'deposit'
break
case 'closeDeposit':
action = 'withdraw'
break
case 'openLoan':
action = 'Get loan'
break
case 'closeLoan':
action = 'Repay loan'
break
}
@ -820,7 +903,7 @@
}
const timestamp = id.split('_')[0]
const card = getRef('response_template').content.cloneNode(true).firstElementChild
let icon
const icon = utils.getRelatedIcon(status)
let action = ''
switch(rtype){
case 'openDeposit':
@ -836,19 +919,6 @@
action = 'loan repayment'
break
}
if(status === 'success'){
icon = `
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M6.267 3.455a3.066 3.066 0 001.745-.723 3.066 3.066 0 013.976 0 3.066 3.066 0 001.745.723 3.066 3.066 0 012.812 2.812c.051.643.304 1.254.723 1.745a3.066 3.066 0 010 3.976 3.066 3.066 0 00-.723 1.745 3.066 3.066 0 01-2.812 2.812 3.066 3.066 0 00-1.745.723 3.066 3.066 0 01-3.976 0 3.066 3.066 0 00-1.745-.723 3.066 3.066 0 01-2.812-2.812 3.066 3.066 0 00-.723-1.745 3.066 3.066 0 010-3.976 3.066 3.066 0 00.723-1.745 3.066 3.066 0 012.812-2.812zm7.44 5.252a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />
</svg>
`
}else{
icon = `
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
</svg>
`
}
card.querySelector('.activity-card__icon').innerHTML = icon
card.querySelector('.activity-card__icon').classList.add(status)
card.querySelector('.activity-card__title').textContent = `${action} ${status === 'success' ? 'approved': 'failed'}`
@ -856,22 +926,11 @@
card.querySelector('.activity-card__time').textContent = getFormatedTime(timestamp, true)
return card
},
accountCard(accountDetails = {}){
accountCard(accountDetails = {}, index){
const {type, status, openTime, closeTime = 0, amount, netAmt} = accountDetails
const card = getRef('account_template').content.cloneNode(true).firstElementChild
let icon
switch(type){
case 'deposit':
icon = `
<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"><rect fill="none" height="24" width="24"/><g><path d="M19.83,7.5l-2.27-2.27c0.07-0.42,0.18-0.81,0.32-1.15C17.96,3.9,18,3.71,18,3.5C18,2.67,17.33,2,16.5,2 c-1.64,0-3.09,0.79-4,2l-5,0C4.46,4,2,6.46,2,9.5S4.5,21,4.5,21l5.5,0v-2h2v2l5.5,0l1.68-5.59L22,14.47V7.5H19.83z M13,9H8V7h5V9z M16,11c-0.55,0-1-0.45-1-1c0-0.55,0.45-1,1-1s1,0.45,1,1C17,10.55,16.55,11,16,11z"/></g></svg>
`
break
case 'loan':
icon = `
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12.65,8.5H10.42a5.18,5.18,0,0,0-4,1.95L3.75,13.74a5,5,0,0,0-.68,5.31l0,0h0a5.07,5.07,0,0,0,4.5,2.73h7.88A5.08,5.08,0,0,0,20,19.05h0a5.39,5.39,0,0,0,.43-1.2,4.91,4.91,0,0,0-1-4.06l-2.66-3.34A5.17,5.17,0,0,0,12.65,8.5Z"/><path d="M9.71,6.59h3.94A2.94,2.94,0,0,0,16,5.39h0a1.13,1.13,0,0,0-.23-1.57,1.11,1.11,0,0,0-.95-.18h0a1.2,1.2,0,0,1-.92-.18l-.28-.21a3.64,3.64,0,0,0-4.22,0h0a1.18,1.18,0,0,1-1,.16L8.2,3.35a1.13,1.13,0,0,0-1.36.84A1.17,1.17,0,0,0,7,5H7A3.18,3.18,0,0,0,9.71,6.59Z"/></svg>
`
break
}
const icon = utils.getRelatedIcon(type)
card.setAttribute('href', `#/account?index=${index}`)
card.querySelector('.activity-card__icon').innerHTML = icon
card.querySelector('.activity-card__type').textContent = type
card.querySelector('.activity-card__time').textContent = getFormatedTime(parseInt(openTime))
@ -879,6 +938,14 @@
card.querySelector('.activity-card__status').classList.add(status)
card.querySelector('.activity-card__status').textContent = status
return card
},
accountProgressStep(type, title, description = ''){
const elem = getRef('account_step_template').content.cloneNode(true).firstElementChild
elem.classList.add(type)
elem.querySelector('.step__icon').innerHTML = type === 'loading' ? '<sm-spinner></sm-spinner>' : utils.getRelatedIcon(type)
elem.querySelector('.step__title').textContent = title
elem.querySelector('.step__description').innerHTML = description
return elem
}
}
function getSignedIn(){
@ -916,16 +983,7 @@
getRef('flo_balance').textContent = floBalance
})
.catch(error => notify(error, 'error'))
const {depositTotal, loanTotal} = bank_app.getUserDetails(myFloID)
getRef('total_deposit').textContent = depositTotal
getRef('total_loan').textContent = loanTotal
}
function getArrayOfObj(obj) {
const arrayOfObj = []
for (key in obj) {
arrayOfObj.push({id: key, ...obj[key]});
}
return arrayOfObj
updateChart()
}
function getRequestDetails(requestID) {
let {amount, rtype, index} = bank_app.viewAllRequests()[requestID]
@ -965,43 +1023,9 @@
const {amount, rtype, timestamp, status, index} = getRequestDetails(requestID)
const {status: accountStatus} = bank_app.accounts[index]
let type = ''
let icon = ''
if(rtype === 'openDeposit' || rtype === 'closeDeposit'){
type = 'deposit'
icon = `
<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"><rect fill="none" height="24" width="24"/><g><path d="M19.83,7.5l-2.27-2.27c0.07-0.42,0.18-0.81,0.32-1.15C17.96,3.9,18,3.71,18,3.5C18,2.67,17.33,2,16.5,2 c-1.64,0-3.09,0.79-4,2l-5,0C4.46,4,2,6.46,2,9.5S4.5,21,4.5,21l5.5,0v-2h2v2l5.5,0l1.68-5.59L22,14.47V7.5H19.83z M13,9H8V7h5V9z M16,11c-0.55,0-1-0.45-1-1c0-0.55,0.45-1,1-1s1,0.45,1,1C17,10.55,16.55,11,16,11z"/></g></svg>
`
}else{
type = 'Loan'
icon = `
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12.65,8.5H10.42a5.18,5.18,0,0,0-4,1.95L3.75,13.74a5,5,0,0,0-.68,5.31l0,0h0a5.07,5.07,0,0,0,4.5,2.73h7.88A5.08,5.08,0,0,0,20,19.05h0a5.39,5.39,0,0,0,.43-1.2,4.91,4.91,0,0,0-1-4.06l-2.66-3.34A5.17,5.17,0,0,0,12.65,8.5Z"/><path d="M9.71,6.59h3.94A2.94,2.94,0,0,0,16,5.39h0a1.13,1.13,0,0,0-.23-1.57,1.11,1.11,0,0,0-.95-.18h0a1.2,1.2,0,0,1-.92-.18l-.28-.21a3.64,3.64,0,0,0-4.22,0h0a1.18,1.18,0,0,1-1,.16L8.2,3.35a1.13,1.13,0,0,0-1.36.84A1.17,1.17,0,0,0,7,5H7A3.18,3.18,0,0,0,9.71,6.59Z"/></svg>
`
}
let statusIcon = ''
switch(status){
case 'success':
statusIcon = `
<svg xmlns="http://www.w3.org/2000/svg" class="icon button__icon--left" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M6.267 3.455a3.066 3.066 0 001.745-.723 3.066 3.066 0 013.976 0 3.066 3.066 0 001.745.723 3.066 3.066 0 012.812 2.812c.051.643.304 1.254.723 1.745a3.066 3.066 0 010 3.976 3.066 3.066 0 00-.723 1.745 3.066 3.066 0 01-2.812 2.812 3.066 3.066 0 00-1.745.723 3.066 3.066 0 01-3.976 0 3.066 3.066 0 00-1.745-.723 3.066 3.066 0 01-2.812-2.812 3.066 3.066 0 00-.723-1.745 3.066 3.066 0 010-3.976 3.066 3.066 0 00.723-1.745 3.066 3.066 0 012.812-2.812zm7.44 5.252a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />
</svg>
`
break;
case 'pending':
statusIcon = `
<svg xmlns="http://www.w3.org/2000/svg" class="icon button__icon--left" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clip-rule="evenodd" />
</svg>
`
break;
case 'failed':
statusIcon = `
<svg xmlns="http://www.w3.org/2000/svg" class="icon button__icon--left" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
</svg>
`
break;
}
let type = (rtype === 'openDeposit' || rtype === 'closeDeposit') ? 'deposit' : 'loan'
const icon = utils.getRelatedIcon(rtype)
const statusIcon = utils.getRelatedIcon(status)
getRef('transaction_detail__icon').innerHTML = icon
getRef('transaction_detail__status').innerHTML = `${statusIcon} ${status === 'success' ? 'completed' : status}`
getRef('transaction_detail__status').className = `status-tag flex align-center ${status}`
@ -1025,6 +1049,26 @@
break
}
}
function showAccountDetails(params){
const {index} = params
const {type, status, openTime, closeTime = 0, amount, netAmt} = bank_app.accounts[index]
const icon = utils.getRelatedIcon(type)
getRef('account_detail__icon').innerHTML = icon
getRef('account_detail__status').textContent = status
getRef('account_detail__status').className = `status-tag flex align-center ${status}`
getRef('account_detail__type').textContent = type
getRef('account_detail__amount').textContent = amount
getRef('account_detail__time').textContent = getFormatedTime(openTime)
getRef('account_action_button').classList.remove('hide-completely')
if(status === 'active'){
getRef('account_action_button').classList.remove('hide-completely')
}else{
getRef('account_action_button').classList.add('hide-completely')
}
getRef('account_action_button').textContent = type ==='deposit' ? 'Withdraw' : 'Repay'
}
function selectGraphColors(){
const colors = []
@ -1033,6 +1077,16 @@
return [green, yellow]
}
function updateChart() {
const {depositTotal, loanTotal} = bank_app.getUserDetails(myFloID)
if(accountChart){
accountChart.data.datasets[0].data = [depositTotal, loanTotal]
accountChart.update()
}
getRef('total_deposit').textContent = depositTotal
getRef('total_loan').textContent = loanTotal
}
document.querySelector('theme-toggle').addEventListener('themechange', e => {
if(accountChart){
accountChart.data.datasets[0].backgroundColor = selectGraphColors()
@ -1079,11 +1133,64 @@
entries.forEach(entry => {
if(entry.isIntersecting){
accountChart = renderChart()
refreshBalance()
}else if(!entry.isIntersecting && accountChart){
accountChart.destroy()
}
})
})
async function processAccount() {
const {index} = pagesData.params
const {type, netAmt} = bank_app.accounts[index]
if(type === 'deposit'){
const ans = await getConfirmation('Withdraw deposit?', 'Are you sure to withdraw this deposit now?')
if(ans){
getRef('account_process__type').textContent = 'Withdraw'
getRef('account_process__amount').textContent = `₹${netAmt}`
getRef('account_process__steps').innerHTML = ''
getRef('account_process__steps').append(render.accountProgressStep('loading', 'Sending withdraw request'))
getRef('account_process').classList.remove('hide-completely')
getRef('account_details').classList.add('hide-completely')
bank_app.withdrawDeposit(index)
.then(res => {
getRef('account_process__steps').innerHTML = ''
getRef('account_process__steps').append(render.accountProgressStep('success', 'Sent withdraw request'))
getRef('account_process__steps').append(render.accountProgressStep('pending', 'Waiting for confirmation', `Once your request is processed, your withdrawn amount will reflect in your balance.<br>meanwhile you can go back and continue using the app.`))
})
.catch(err => {
getRef('account_process__steps').innerHTML = ''
getRef('account_process__steps')
.append(
render.accountProgressStep('failed', 'Failed withdrawal', `Can't withdraw deposit as loan amount exceeds total deposit amount.`)
)
})
}
}else{
const ans = await getConfirmation('Repay loan?', 'Make sure you have required amount to repay the loan!')
if(ans){
getRef('account_process__type').textContent = 'Repay'
getRef('account_process__amount').textContent = `₹${netAmt}`
getRef('account_process__steps').innerHTML = ''
getRef('account_process__steps').append(render.accountProgressStep('loading', 'Sending repay request'))
getRef('account_process').classList.remove('hide-completely')
getRef('account_details').classList.add('hide-completely')
bank_app.repayLoan(index)
.then(res => {
getRef('account_process__steps').innerHTML = ''
getRef('account_process__steps').append(render.accountProgressStep('success', 'Sent repay request'))
getRef('account_process__steps').append(render.accountProgressStep('pending', 'Waiting for confirmation', `Once your request is processed, your loan will be closed,`))
})
.catch(err => {
getRef('account_process__steps').innerHTML = ''
getRef('account_process__steps')
.append(
render.accountProgressStep('failed', 'Failed repayment', err)
)
})
}
}
}
</script>
<script id="onLoadStartUp">
const requestResponsePairs = {}
@ -1107,7 +1214,6 @@
bank_app.launchApp(DummyCallBack, DummyCallBack)
.then(result => {
console.log(result)
chartObserver.observe(getRef('account_chart_container'))
// create pairs of requestIDs and their respective responses for efficient lookup
const allResponses = bank_app.viewAllResponses()
for(const key in allResponses){
@ -1119,6 +1225,7 @@
}else{
showPage(window.location.hash)
}
chartObserver.observe(getRef('account_chart_container'))
})
.catch(error => console.error(error))
}).catch(error => console.error(error));