UI update
Added -- dark mode -- profile dropdown
This commit is contained in:
parent
7bd6f75ee7
commit
21fc1f9139
77
css/main.css
77
css/main.css
@ -64,8 +64,10 @@ body[data-theme=dark] {
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 0.8;
|
||||
max-width: 60ch;
|
||||
line-height: 1.7;
|
||||
line-height: 1.5;
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
}
|
||||
|
||||
img {
|
||||
@ -83,6 +85,7 @@ a:focus-visible {
|
||||
button {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
overflow: hidden;
|
||||
align-items: center;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
@ -360,15 +363,20 @@ ul {
|
||||
|
||||
#main_header__logo {
|
||||
fill: white;
|
||||
height: 2.6rem;
|
||||
width: 2.6rem;
|
||||
margin-left: -0.5rem;
|
||||
height: 2.4rem;
|
||||
width: 2.4rem;
|
||||
margin-left: -0.3rem;
|
||||
}
|
||||
|
||||
.header__company-name {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.header__app-name {
|
||||
font-weight: 700;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
#usd-rate {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -382,15 +390,58 @@ ul {
|
||||
}
|
||||
|
||||
sm-select {
|
||||
min-width: 6rem;
|
||||
--selection-font-size: 0.9rem;
|
||||
--arrow-fill: white;
|
||||
--border: 1px solid white;
|
||||
}
|
||||
|
||||
sm-option {
|
||||
--color: rgba(var(--text-color), 1);
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.dropdown__panel {
|
||||
position: absolute;
|
||||
display: grid;
|
||||
gap: 2rem;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 100%;
|
||||
padding: 1rem;
|
||||
margin: 0 1rem;
|
||||
margin-top: 0.5rem;
|
||||
border-radius: 0.3rem;
|
||||
grid-template-columns: 1fr;
|
||||
justify-content: flex-start;
|
||||
color: rgba(var(--text-color), 1);
|
||||
width: min(24rem, calc(100vw - 2rem));
|
||||
background-color: rgba(var(--foreground-color), 1);
|
||||
box-shadow: 0 2rem 2rem -0.5rem rgba(0, 0, 0, 0.16);
|
||||
}
|
||||
|
||||
#profile_button {
|
||||
border: none;
|
||||
height: 2.4rem;
|
||||
width: 2.4rem;
|
||||
justify-self: flex-end;
|
||||
border-radius: 50%;
|
||||
background-color: rgba(0, 0, 0, 0.16);
|
||||
}
|
||||
#profile_button .icon {
|
||||
height: 1.2rem;
|
||||
width: 1.2rem;
|
||||
fill: white;
|
||||
}
|
||||
|
||||
#theme_switcher {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.page {
|
||||
display: grid;
|
||||
grid-template-columns: 1rem 1fr 1rem;
|
||||
@ -414,10 +465,18 @@ bond-transaction {
|
||||
box-shadow: 0 1rem 2rem -1rem rgba(0, 0, 0, 0.16);
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 640px) {
|
||||
#main_header {
|
||||
grid-template-areas: ". profile-button";
|
||||
}
|
||||
#main_header .dropdown {
|
||||
grid-area: profile-button;
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: 640px) {
|
||||
#main_header {
|
||||
padding: 2rem calc((10vw / 2) - 0.4rem);
|
||||
grid-template-columns: 1fr auto auto auto;
|
||||
grid-template-columns: 1fr auto auto;
|
||||
}
|
||||
#main_header::after {
|
||||
height: 5rem;
|
||||
@ -426,6 +485,10 @@ bond-transaction {
|
||||
.page {
|
||||
grid-template-columns: 1fr 90vw 1fr;
|
||||
}
|
||||
|
||||
.dropdown__panel {
|
||||
left: auto;
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: 1280px) {
|
||||
.page {
|
||||
|
||||
2
css/main.min.css
vendored
2
css/main.min.css
vendored
File diff suppressed because one or more lines are too long
@ -56,8 +56,10 @@ body[data-theme='dark']{
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 0.8;
|
||||
max-width: 60ch;
|
||||
line-height: 1.7;
|
||||
line-height: 1.5;
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
}
|
||||
|
||||
img{
|
||||
@ -75,6 +77,7 @@ a{
|
||||
button{
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
overflow: hidden;
|
||||
align-items: center;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
@ -296,13 +299,17 @@ ul{
|
||||
}
|
||||
#main_header__logo{
|
||||
fill: white;
|
||||
height: 2.6rem;
|
||||
width: 2.6rem;
|
||||
margin-left: -0.5rem;
|
||||
height: 2.4rem;
|
||||
width: 2.4rem;
|
||||
margin-left: -0.3rem;
|
||||
}
|
||||
.header__company-name{
|
||||
font-weight: 500;
|
||||
}
|
||||
.header__app-name{
|
||||
font-weight: 700;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
#usd-rate{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -316,14 +323,56 @@ ul{
|
||||
}
|
||||
|
||||
sm-select{
|
||||
min-width: 6rem;
|
||||
--selection-font-size: 0.9rem;
|
||||
--arrow-fill: white;
|
||||
--border: 1px solid white;
|
||||
}
|
||||
sm-option{
|
||||
--color: rgba(var(--text-color), 1);
|
||||
}
|
||||
|
||||
.dropdown{
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
z-index: 5;
|
||||
}
|
||||
.dropdown__panel{
|
||||
position: absolute;
|
||||
display: grid;
|
||||
gap: 2rem;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 100%;
|
||||
padding: 1rem;
|
||||
margin: 0 1rem;
|
||||
margin-top: 0.5rem;
|
||||
border-radius: 0.3rem;
|
||||
grid-template-columns: 1fr;
|
||||
justify-content: flex-start;
|
||||
color: rgba(var(--text-color), 1);
|
||||
width: min(24rem, calc(100vw - 2rem));
|
||||
background-color: rgba(var(--foreground-color), 1);
|
||||
box-shadow: 0 2rem 2rem -0.5rem rgba($color: #000000, $alpha: 0.16);
|
||||
}
|
||||
|
||||
#profile_button{
|
||||
border: none;
|
||||
height: 2.4rem;
|
||||
width: 2.4rem;
|
||||
justify-self: flex-end;
|
||||
border-radius: 50%;
|
||||
background-color: rgba($color: #000000, $alpha: 0.16);
|
||||
.icon{
|
||||
height: 1.2rem;
|
||||
width: 1.2rem;
|
||||
fill: white;
|
||||
}
|
||||
}
|
||||
|
||||
#theme_switcher{
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.page{
|
||||
display: grid;
|
||||
grid-template-columns: 1rem 1fr 1rem;
|
||||
@ -348,10 +397,20 @@ bond-transaction{
|
||||
}
|
||||
|
||||
|
||||
@media only screen and (max-width: 640px) {
|
||||
#main_header{
|
||||
grid-template-areas: '. profile-button';
|
||||
.dropdown{
|
||||
grid-area: profile-button;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media only screen and (min-width: 640px) {
|
||||
#main_header{
|
||||
padding: 2rem calc((10vw / 2) - 0.4rem);
|
||||
grid-template-columns: 1fr auto auto auto;
|
||||
grid-template-columns: 1fr auto auto;
|
||||
&::after{
|
||||
height: 5rem;
|
||||
}
|
||||
@ -359,6 +418,9 @@ bond-transaction{
|
||||
.page{
|
||||
grid-template-columns: 1fr 90vw 1fr;
|
||||
}
|
||||
.dropdown__panel{
|
||||
left: auto;
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: 1280px) {
|
||||
.page{
|
||||
|
||||
919
index.html
919
index.html
@ -29,60 +29,73 @@
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400..900&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
<body onload="onLoadStartUp()" data-theme="light">
|
||||
<header id="main_header">
|
||||
<div class="flex align-center">
|
||||
<svg id="main_header__logo" class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.46,21.32C20,19.78,18.6,18.59,15.3,17a12.67,12.67,0,0,1-2.64-1.56,4.27,4.27,0,0,1-.79-1,2.6,2.6,0,0,1,0-1.41c.24-.68.49-1,2.43-2.85a7.18,7.18,0,0,0,2.09-2.92,4.25,4.25,0,0,0,0-1.77,6.52,6.52,0,0,0-2.85-3.11c-.56-.36-.81-.4-.81-.15a2.33,2.33,0,0,1-.18.45L12.4,3l-.53-.36c-.28-.21-.64-.41-.77-.49s-.46-.11-.46,0a6.21,6.21,0,0,1-.37.83s-.08,0-.17-.08c-1.15-.83-1.64-1-1.64-.73A7.33,7.33,0,0,1,7.7,3.65C6.48,5.68,5.24,6.7,4,6.7c-.56,0-.54,0-.37.64s.2.58.68.43a3.37,3.37,0,0,0,1.09-.54.86.86,0,0,1,.3-.17,1.34,1.34,0,0,1,.13.39.79.79,0,0,0,.17.4A3.5,3.5,0,0,0,7.37,7.3L7.8,7l.09.34c.12.45.19.51.62.39a4.25,4.25,0,0,0,2.17-1.54l.38-.45,0,.39A5.92,5.92,0,0,1,8.89,9.54L7.67,10.71c-2,1.93-1.89,3.51.37,5a27.41,27.41,0,0,0,2.89,1.51c.17.07.62.32,1,.54C14,19,15,20.23,15,21.48a2,2,0,0,0,0,.49h0c0,.05,0,.05.56-.1a1.89,1.89,0,0,0,.53-.21,2.41,2.41,0,0,0-.34-1.15,7.05,7.05,0,0,0-1.68-1.77,21.91,21.91,0,0,0-3.2-1.83A9.53,9.53,0,0,1,8.16,15.2a2.18,2.18,0,0,1-.74-1.55C7.42,12.79,7.86,12,9,11c1.77-1.64,2.45-2.45,2.92-3.55a2.28,2.28,0,0,0,.26-1.26A2,2,0,0,0,12,5.06l-.2-.45L12,4.3l.28-.49.09-.18L12.6,4a3.69,3.69,0,0,1,.61,1.76A3.47,3.47,0,0,1,12.94,7l-.09.25s-.21.37-.41.69A17.78,17.78,0,0,1,9.91,10.6c-1.07,1-1.43,1.62-1.47,2.47a2.05,2.05,0,0,0,.7,1.73,10.47,10.47,0,0,0,3.28,2.08c2.28,1.13,3.26,1.81,4,2.73a2.94,2.94,0,0,1,.74,1.75,1.26,1.26,0,0,0,.09.57.48.48,0,0,0,.26,0l.51-.13.29-.08,0-.28c-.13-1-1-2-2.47-3a25.52,25.52,0,0,0-3.26-1.77,8.59,8.59,0,0,1-2.23-1.43,2.09,2.09,0,0,1-.5-2.62c.26-.53.5-.83,2.35-2.6,1.51-1.45,2.15-2.58,2.15-3.79A3.67,3.67,0,0,0,13,3.48a3,3,0,0,1-.4-.42A1.85,1.85,0,0,1,13,2.33a6.74,6.74,0,0,1,1.83,1.73,2.62,2.62,0,0,1,.47,1.68,3,3,0,0,1-.55,1.84c-.45.78-.79,1.14-2.67,2.93a5.56,5.56,0,0,0-1.3,1.64,1.77,1.77,0,0,0-.21,1,1.76,1.76,0,0,0,.19.92,6.28,6.28,0,0,0,2.9,2.34,21.6,21.6,0,0,1,3.66,2c1.35,1,2,2,2,3a1.06,1.06,0,0,0,.05.47,2.83,2.83,0,0,0,1-.24C20.56,21.68,20.56,21.66,20.46,21.32ZM7.29,6.4h0a2.23,2.23,0,0,1-.9.28L6,6.72l.43-.53a15.22,15.22,0,0,0,1.89-3,3.52,3.52,0,0,1,.38-.67c.07-.08.49.2,1,.64l.39.35L9.66,4A6.7,6.7,0,0,1,7.29,6.4Zm3.58-1.11A5.8,5.8,0,0,1,9.25,6.51h0a3.3,3.3,0,0,1-.74.17l-.35,0,.39-.49a15.64,15.64,0,0,0,1.32-2,4.63,4.63,0,0,1,.28-.49c.06-.08.33.26.57.77l.28.57Zm1-1.4a1.63,1.63,0,0,1-.28.4A6.63,6.63,0,0,1,11,3.72l-.53-.56.12-.29c.2-.49.24-.51.64-.19a5.57,5.57,0,0,1,.85.78A2.78,2.78,0,0,1,11.87,3.89Z"/></svg>
|
||||
<div class="grid">
|
||||
<h5 class="header__company-name">RanchiMall</h5>
|
||||
<h3 class="h3">Bitcoin Bonds</h3>
|
||||
<sm-notifications id="notification_drawer"></sm-notifications>
|
||||
<header id="main_header">
|
||||
<div class="flex align-center">
|
||||
<svg id="main_header__logo" class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.46,21.32C20,19.78,18.6,18.59,15.3,17a12.67,12.67,0,0,1-2.64-1.56,4.27,4.27,0,0,1-.79-1,2.6,2.6,0,0,1,0-1.41c.24-.68.49-1,2.43-2.85a7.18,7.18,0,0,0,2.09-2.92,4.25,4.25,0,0,0,0-1.77,6.52,6.52,0,0,0-2.85-3.11c-.56-.36-.81-.4-.81-.15a2.33,2.33,0,0,1-.18.45L12.4,3l-.53-.36c-.28-.21-.64-.41-.77-.49s-.46-.11-.46,0a6.21,6.21,0,0,1-.37.83s-.08,0-.17-.08c-1.15-.83-1.64-1-1.64-.73A7.33,7.33,0,0,1,7.7,3.65C6.48,5.68,5.24,6.7,4,6.7c-.56,0-.54,0-.37.64s.2.58.68.43a3.37,3.37,0,0,0,1.09-.54.86.86,0,0,1,.3-.17,1.34,1.34,0,0,1,.13.39.79.79,0,0,0,.17.4A3.5,3.5,0,0,0,7.37,7.3L7.8,7l.09.34c.12.45.19.51.62.39a4.25,4.25,0,0,0,2.17-1.54l.38-.45,0,.39A5.92,5.92,0,0,1,8.89,9.54L7.67,10.71c-2,1.93-1.89,3.51.37,5a27.41,27.41,0,0,0,2.89,1.51c.17.07.62.32,1,.54C14,19,15,20.23,15,21.48a2,2,0,0,0,0,.49h0c0,.05,0,.05.56-.1a1.89,1.89,0,0,0,.53-.21,2.41,2.41,0,0,0-.34-1.15,7.05,7.05,0,0,0-1.68-1.77,21.91,21.91,0,0,0-3.2-1.83A9.53,9.53,0,0,1,8.16,15.2a2.18,2.18,0,0,1-.74-1.55C7.42,12.79,7.86,12,9,11c1.77-1.64,2.45-2.45,2.92-3.55a2.28,2.28,0,0,0,.26-1.26A2,2,0,0,0,12,5.06l-.2-.45L12,4.3l.28-.49.09-.18L12.6,4a3.69,3.69,0,0,1,.61,1.76A3.47,3.47,0,0,1,12.94,7l-.09.25s-.21.37-.41.69A17.78,17.78,0,0,1,9.91,10.6c-1.07,1-1.43,1.62-1.47,2.47a2.05,2.05,0,0,0,.7,1.73,10.47,10.47,0,0,0,3.28,2.08c2.28,1.13,3.26,1.81,4,2.73a2.94,2.94,0,0,1,.74,1.75,1.26,1.26,0,0,0,.09.57.48.48,0,0,0,.26,0l.51-.13.29-.08,0-.28c-.13-1-1-2-2.47-3a25.52,25.52,0,0,0-3.26-1.77,8.59,8.59,0,0,1-2.23-1.43,2.09,2.09,0,0,1-.5-2.62c.26-.53.5-.83,2.35-2.6,1.51-1.45,2.15-2.58,2.15-3.79A3.67,3.67,0,0,0,13,3.48a3,3,0,0,1-.4-.42A1.85,1.85,0,0,1,13,2.33a6.74,6.74,0,0,1,1.83,1.73,2.62,2.62,0,0,1,.47,1.68,3,3,0,0,1-.55,1.84c-.45.78-.79,1.14-2.67,2.93a5.56,5.56,0,0,0-1.3,1.64,1.77,1.77,0,0,0-.21,1,1.76,1.76,0,0,0,.19.92,6.28,6.28,0,0,0,2.9,2.34,21.6,21.6,0,0,1,3.66,2c1.35,1,2,2,2,3a1.06,1.06,0,0,0,.05.47,2.83,2.83,0,0,0,1-.24C20.56,21.68,20.56,21.66,20.46,21.32ZM7.29,6.4h0a2.23,2.23,0,0,1-.9.28L6,6.72l.43-.53a15.22,15.22,0,0,0,1.89-3,3.52,3.52,0,0,1,.38-.67c.07-.08.49.2,1,.64l.39.35L9.66,4A6.7,6.7,0,0,1,7.29,6.4Zm3.58-1.11A5.8,5.8,0,0,1,9.25,6.51h0a3.3,3.3,0,0,1-.74.17l-.35,0,.39-.49a15.64,15.64,0,0,0,1.32-2,4.63,4.63,0,0,1,.28-.49c.06-.08.33.26.57.77l.28.57Zm1-1.4a1.63,1.63,0,0,1-.28.4A6.63,6.63,0,0,1,11,3.72l-.53-.56.12-.29c.2-.49.24-.51.64-.19a5.57,5.57,0,0,1,.85.78A2.78,2.78,0,0,1,11.87,3.89Z"/></svg>
|
||||
<div class="grid">
|
||||
<h5 class="header__company-name">RanchiMall</h5>
|
||||
<h3 class="header__app-name">Bitcoin Bonds</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid gap-1 flow-column justify-start align-center">
|
||||
<span id="btc-usd-rate" class="weight-700 hide-completely"></span>
|
||||
<span id="btc-inr-rate" class="weight-700"></span>
|
||||
<span id="usd-rate" class="weight-700"></span>
|
||||
</div>
|
||||
<div class="dropdown">
|
||||
<button id="profile_button" onclick="changeDropdownState('profile_dropdown', 'toggle', this)">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11.93,0a4.8,4.8,0,0,0-4.8,4.8s.13,3.74.54,4.53c.5,1,3,3,4.26,3s3.72-2,4.22-3c.41-.79.58-4.53.58-4.53A4.8,4.8,0,0,0,11.93,0Z"/><path d="M14.47,12.59a4.38,4.38,0,0,1-2.54,1,4.38,4.38,0,0,1-2.53-1c-1,1.78-4,2.69-6.21,3.68-.91.37-1.67,5.3-.61,5.3A18.4,18.4,0,0,0,12.12,24a16.76,16.76,0,0,0,9.17-2.42c1.06,0,.3-4.89-.61-5.3C18.45,15.28,15.42,14.37,14.47,12.59Z"/></svg>
|
||||
</button>
|
||||
<ul id="profile_dropdown" class="dropdown__panel hide-completely">
|
||||
<li class="grid gap-0-5">
|
||||
<h4 class="weight-700 margin-bottom-0-5r">Preferred currency</h4>
|
||||
<p>This will convert all amounts to preferred currency.</p>
|
||||
<sm-select id="currency_selector" align-select="right" class="justify-self-start">
|
||||
<sm-option value="inr">INR</sm-option>
|
||||
<sm-option value="usd">USD</sm-option>
|
||||
</sm-select>
|
||||
</li>
|
||||
<li>
|
||||
<sm-switch id="theme_switcher">
|
||||
<div slot="left" class="flex weight-700">Dark theme</div>
|
||||
</sm-switch>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid gap-1 flow-column justify-start align-center">
|
||||
<span id="btc-usd-rate" class="weight-700"></span>
|
||||
<span id="btc-inr-rate" class="weight-700"></span>
|
||||
<span id="usd-rate" class="weight-700"></span>
|
||||
</div>
|
||||
<div class="grid justify-start">
|
||||
<h5 class="h5 margin-bottom-0-5r">Preferred currency</h5>
|
||||
<sm-select id="currency_selector" align-select="right" class="justify-self-end">
|
||||
<sm-option value="inr">INR</sm-option>
|
||||
<sm-option value="usd">USD</sm-option>
|
||||
</sm-select>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<form id="add-bond-form" class="hide-completely">
|
||||
FLO ID: <input type="text" name="floid" pattern="[0-9a-zA-Z]{34}"><br />
|
||||
Amount: <input type="text" name="amount" pattern="\d.+">INR<br />
|
||||
Bond start date: <input type="date" name="start_date"><br />
|
||||
Base BTC value: <input type="text" name="base" pattern="^[\d,]+.?\d$">USD<br />
|
||||
Base USD rate: <input type="number" name="usd_rate" step="0.01">INR<br />
|
||||
Guaranteed interest rate: <input type="number" name="gi_r" min=0 max=100 step="0.01">%<br />
|
||||
Guaranteed interest period: <input type="number" name="gi_pv">
|
||||
<select name="gi_pt">
|
||||
<option value="year(s)">year(s)</option>
|
||||
<option value="month(s)">month(s)</option>
|
||||
<option value="week(s)">week(s)</option>
|
||||
<option value="day(s)">day(s)</option>
|
||||
</select><br />
|
||||
Gain share: <input type="number" name="cut" min=0 max=100>%<br />
|
||||
Lock-in period: <input type="number" name="lockin_v">
|
||||
<select name="lockin_t">
|
||||
<option value="year(s)">year(s)</option>
|
||||
<option value="month(s)">month(s)</option>
|
||||
<option value="week(s)">week(s)</option>
|
||||
<option value="day(s)">day(s)</option>
|
||||
</select><br />
|
||||
<input type="submit" value="Add Bond" /><input type="reset" value="Clear">
|
||||
</form>
|
||||
<main class="page">
|
||||
<header class="bond-list__header flex align-center">
|
||||
<h4 class="h4">Recent</h4>
|
||||
<button id="refresh-btn" class="justify-right">Refresh</button>
|
||||
</header>
|
||||
<ul id="bond_list"></ul>
|
||||
</main>
|
||||
|
||||
<form id="add-bond-form" class="hide-completely">
|
||||
FLO ID: <input type="text" name="floid" pattern="[0-9a-zA-Z]{34}"><br />
|
||||
Amount: <input type="text" name="amount" pattern="\d.+">INR<br />
|
||||
Bond start date: <input type="date" name="start_date"><br />
|
||||
Base BTC value: <input type="text" name="base" pattern="^[\d,]+.?\d$">USD<br />
|
||||
Base USD rate: <input type="number" name="usd_rate" step="0.01">INR<br />
|
||||
Guaranteed interest rate: <input type="number" name="gi_r" min=0 max=100 step="0.01">%<br />
|
||||
Guaranteed interest period: <input type="number" name="gi_pv">
|
||||
<select name="gi_pt">
|
||||
<option value="year(s)">year(s)</option>
|
||||
<option value="month(s)">month(s)</option>
|
||||
<option value="week(s)">week(s)</option>
|
||||
<option value="day(s)">day(s)</option>
|
||||
</select><br />
|
||||
Gain share: <input type="number" name="cut" min=0 max=100>%<br />
|
||||
Lock-in period: <input type="number" name="lockin_v">
|
||||
<select name="lockin_t">
|
||||
<option value="year(s)">year(s)</option>
|
||||
<option value="month(s)">month(s)</option>
|
||||
<option value="week(s)">week(s)</option>
|
||||
<option value="day(s)">day(s)</option>
|
||||
</select><br />
|
||||
<input type="submit" value="Add Bond" /><input type="reset" value="Clear">
|
||||
</form>
|
||||
<main class="page">
|
||||
<header class="bond-list__header flex align-center">
|
||||
<h4 class="h4">Recent</h4>
|
||||
<button id="refresh-btn" class="justify-right">Refresh</button>
|
||||
</header>
|
||||
<ul id="bond_list"></ul>
|
||||
</main>
|
||||
<script id="init_lib" version="1.0.1">
|
||||
//All util libraries required for Standard operations (DO NOT EDIT ANY)
|
||||
|
||||
@ -8097,6 +8110,9 @@ Bitcoin.Util = {
|
||||
.flow-column{
|
||||
grid-auto-flow: column;
|
||||
}
|
||||
.justify-end{
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.hide-completely{
|
||||
display: none !important;
|
||||
}
|
||||
@ -8139,6 +8155,10 @@ Bitcoin.Util = {
|
||||
.bond-transaction{
|
||||
grid-template-columns: 1fr auto;
|
||||
}
|
||||
.justify-self-end{
|
||||
justify-self: flex-end;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<li class="bond-transaction">
|
||||
@ -8146,7 +8166,7 @@ Bitcoin.Util = {
|
||||
<span class="label">FLO ID</span>
|
||||
<span class="value flo-id"></span>
|
||||
</div>
|
||||
<div class="transaction-column">
|
||||
<div class="transaction-column justify-self-end">
|
||||
<span class="label">Bond starting date</span>
|
||||
<span class="value bond-start-date"></span>
|
||||
</div>
|
||||
@ -8164,7 +8184,7 @@ Bitcoin.Util = {
|
||||
<span class="value guaranteed-interest"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid gap-1 flow-column justify-start">
|
||||
<div class="grid gap-1 flow-column justify-end">
|
||||
<a class="link" target="_blank">View on blockchain</a>
|
||||
<button>More details</button>
|
||||
</div>
|
||||
@ -8634,25 +8654,798 @@ Bitcoin.Util = {
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
let prefersInr = true
|
||||
|
||||
const smSwitch = document.createElement('template')
|
||||
smSwitch.innerHTML = `
|
||||
<style>
|
||||
*{
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
:host{
|
||||
display: -webkit-inline-box;
|
||||
display: -ms-inline-flexbox;
|
||||
display: inline-flex;
|
||||
}
|
||||
label{
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
:host(:not([disabled])) label:focus-visible{
|
||||
-webkit-box-shadow: 0 0 0 0.1rem var(--accent-color);
|
||||
box-shadow: 0 0 0 0.1rem var(--accent-color);
|
||||
}
|
||||
:host([disabled]) {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.6;
|
||||
pointer-events: none;
|
||||
}
|
||||
.switch {
|
||||
position: relative;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
width: 2.4rem;
|
||||
flex-shrink: 0;
|
||||
margin-left: auto;
|
||||
padding: 0.2rem;
|
||||
cursor: pointer;
|
||||
border-radius: 2rem;
|
||||
}
|
||||
|
||||
input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.track {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 1.4rem;
|
||||
-webkit-transition: background 0.3s;
|
||||
-o-transition: background 0.3s;
|
||||
transition: background 0.3s;
|
||||
background: rgba(var(--text-color), 0.4);
|
||||
-webkit-box-shadow: 0 0.1rem 0.3rem #00000040 inset;
|
||||
box-shadow: 0 0.1rem 0.3rem #00000040 inset;
|
||||
border-radius: 1rem;
|
||||
}
|
||||
|
||||
.switch:active .button::after,
|
||||
.switch:focus .button::after{
|
||||
opacity: 1
|
||||
}
|
||||
.switch:focus-visible .button::after{
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
.button::after{
|
||||
content: '';
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
position: absolute;
|
||||
height: 2.6rem;
|
||||
width: 2.6rem;
|
||||
background: rgba(var(--text-color), 0.2);
|
||||
border-radius: 2rem;
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.3s;
|
||||
-o-transition: opacity 0.3s;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
|
||||
.button {
|
||||
position: relative;
|
||||
display: -webkit-inline-box;
|
||||
display: -ms-inline-flexbox;
|
||||
display: inline-flex;
|
||||
height: 1rem;
|
||||
width: 1rem;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
border-radius: 1rem;
|
||||
-webkit-box-shadow: 0 0.1rem 0.4rem #00000060;
|
||||
box-shadow: 0 0.1rem 0.4rem #00000060;
|
||||
-webkit-transition: -webkit-transform 0.3s;
|
||||
transition: -webkit-transform 0.3s;
|
||||
-o-transition: transform 0.3s;
|
||||
transition: transform 0.3s;
|
||||
transition: transform 0.3s, -webkit-transform 0.3s;
|
||||
border: solid 0.3rem white;
|
||||
}
|
||||
|
||||
input:checked ~ .button {
|
||||
-webkit-transform: translateX(100%);
|
||||
-ms-transform: translateX(100%);
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
input:checked ~ .track {
|
||||
background: var(--accent-color);
|
||||
}
|
||||
</style>
|
||||
<label tabindex="0">
|
||||
<slot name="left"></slot>
|
||||
<div part="switch" class="switch">
|
||||
<input type="checkbox">
|
||||
<div class="track"></div>
|
||||
<div class="button"></div>
|
||||
</div>
|
||||
</label>`
|
||||
|
||||
customElements.define('sm-switch', class extends HTMLElement {
|
||||
constructor() {
|
||||
super()
|
||||
this.attachShadow({
|
||||
mode: 'open'
|
||||
}).append(smSwitch.content.cloneNode(true))
|
||||
this.switch = this.shadowRoot.querySelector('.switch');
|
||||
this.input = this.shadowRoot.querySelector('input')
|
||||
this.isChecked = false
|
||||
this.isDisabled = false
|
||||
}
|
||||
|
||||
static get observedAttributes() {
|
||||
return ['disabled', 'checked']
|
||||
}
|
||||
|
||||
get disabled() {
|
||||
return this.isDisabled
|
||||
}
|
||||
|
||||
set disabled(val) {
|
||||
if (val) {
|
||||
this.setAttribute('disabled', '')
|
||||
} else {
|
||||
this.removeAttribute('disabled')
|
||||
}
|
||||
}
|
||||
|
||||
get checked() {
|
||||
return this.isChecked
|
||||
}
|
||||
|
||||
set checked(value) {
|
||||
if (value) {
|
||||
this.setAttribute('checked', '')
|
||||
} else {
|
||||
this.removeAttribute('checked')
|
||||
}
|
||||
}
|
||||
|
||||
dispatch = () => {
|
||||
this.dispatchEvent(new CustomEvent('change', {
|
||||
bubbles: true,
|
||||
composed: true
|
||||
}))
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.addEventListener('keyup', e => {
|
||||
if ((e.code === "Enter" || e.code === "Space") && !this.isDisabled) {
|
||||
this.input.click()
|
||||
}
|
||||
})
|
||||
this.input.addEventListener('click', e => {
|
||||
if (this.input.checked)
|
||||
this.checked = true
|
||||
else
|
||||
this.checked = false
|
||||
this.dispatch()
|
||||
})
|
||||
}
|
||||
attributeChangedCallback(name, oldValue, newValue) {
|
||||
if (oldValue !== newValue) {
|
||||
if (name === 'disabled') {
|
||||
if (this.hasAttribute('disabled')) {
|
||||
this.disabled = true
|
||||
}
|
||||
else {
|
||||
this.disabled = false
|
||||
}
|
||||
}
|
||||
else if (name === 'checked') {
|
||||
if (this.hasAttribute('checked')) {
|
||||
this.isChecked = true
|
||||
this.input.checked = true
|
||||
}
|
||||
else {
|
||||
this.isChecked = false
|
||||
this.input.checked = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
//notifications
|
||||
|
||||
const smNotifications = document.createElement('template')
|
||||
smNotifications.innerHTML = `
|
||||
<style>
|
||||
*{
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
:host{
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
.hide{
|
||||
opacity: 0 !important;
|
||||
pointer-events: none !important;
|
||||
}
|
||||
.notification-panel{
|
||||
display: -ms-grid;
|
||||
display: grid;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 100;
|
||||
max-height: 100%;
|
||||
overflow: hidden auto;
|
||||
-ms-scroll-chaining: none;
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
.no-transformations{
|
||||
-webkit-transform: none;
|
||||
-ms-transform: none;
|
||||
transform: none;
|
||||
opacity: 1;
|
||||
}
|
||||
.notification-panel:empty{
|
||||
display:none;
|
||||
}
|
||||
.notification{
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
opacity: 0;
|
||||
padding: 1rem 1.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
-webkit-transform: translateY(-1rem);
|
||||
-ms-transform: translateY(-1rem);
|
||||
transform: translateY(-1rem);
|
||||
position: relative;
|
||||
border-radius: 0.3rem;
|
||||
-webkit-box-shadow: 0 0.1rem 0.2rem rgba(0, 0, 0, 0.1),
|
||||
0.5rem 1rem 2rem rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 0.1rem 0.2rem rgba(0, 0, 0, 0.1),
|
||||
0.5rem 1rem 2rem rgba(0, 0, 0, 0.1);
|
||||
background: rgba(var(--foreground-color), 1);
|
||||
-webkit-transition: height 0.3s, opacity 0.3s, -webkit-transform 0.3s;
|
||||
transition: height 0.3s, opacity 0.3s, -webkit-transform 0.3s;
|
||||
-o-transition: height 0.3s, transform 0.3s, opacity 0.3s;
|
||||
transition: height 0.3s, transform 0.3s, opacity 0.3s;
|
||||
transition: height 0.3s, transform 0.3s, opacity 0.3s, -webkit-transform 0.3s;
|
||||
overflow: hidden;
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
-ms-word-break: break-all;
|
||||
word-break: break-all;
|
||||
word-break: break-word;
|
||||
-ms-hyphens: auto;
|
||||
-webkit-hyphens: auto;
|
||||
hyphens: auto;
|
||||
max-width: 100%;
|
||||
touch-action: none;
|
||||
}
|
||||
h4:first-letter,
|
||||
p:first-letter{
|
||||
text-transform: uppercase;
|
||||
}
|
||||
h4{
|
||||
font-weight: 400;
|
||||
}
|
||||
p{
|
||||
line-height: 1.6;
|
||||
-webkit-box-flex: 1;
|
||||
-ms-flex: 1;
|
||||
flex: 1;
|
||||
color: rgba(var(--text-color), 0.9);
|
||||
overflow-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
-ms-word-break: break-all;
|
||||
word-break: break-all;
|
||||
word-break: break-word;
|
||||
-ms-hyphens: auto;
|
||||
-webkit-hyphens: auto;
|
||||
hyphens: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
.notification:last-of-type{
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.icon {
|
||||
fill: none;
|
||||
height: 1.6rem;
|
||||
width: 1.6rem;
|
||||
stroke: rgba(var(--text-color), 0.7);
|
||||
overflow: visible;
|
||||
stroke-linecap: round;
|
||||
border-radius: 1rem;
|
||||
stroke-linejoin: round;
|
||||
cursor: pointer;
|
||||
}
|
||||
.error-icon{
|
||||
stroke: #E53935;
|
||||
}
|
||||
.success-icon{
|
||||
stroke: #00C853;
|
||||
}
|
||||
.close{
|
||||
margin-left: 1rem;
|
||||
padding: 0.5rem;
|
||||
stroke-width: 10;
|
||||
}
|
||||
.notification-icon{
|
||||
height: 1.4rem;
|
||||
width: 1.4rem;
|
||||
margin: 0.3em 1rem 0 0;
|
||||
stroke-width: 6;
|
||||
}
|
||||
@media screen and (min-width: 640px){
|
||||
.notification-panel{
|
||||
max-width: 28rem;
|
||||
width: max-content;
|
||||
-webkit-box-pack: end;
|
||||
-ms-flex-pack: end;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.notification{
|
||||
-ms-grid-column-align: end;
|
||||
justify-self: end;
|
||||
width: auto;
|
||||
margin-right: 1.5rem;
|
||||
margin-bottom: 1rem;
|
||||
border-bottom: none;
|
||||
border: solid 1px rgba(var(--text-color), 0.2);
|
||||
-webkit-transform: translateX(1rem);
|
||||
-ms-transform: translateX(1rem);
|
||||
transform: translateX(1rem);
|
||||
}
|
||||
}
|
||||
@media screen and (any-hover: none){
|
||||
.close{
|
||||
display: none
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<div class="notification-panel"></div>
|
||||
`
|
||||
|
||||
customElements.define('sm-notifications', class extends HTMLElement {
|
||||
constructor() {
|
||||
super()
|
||||
this.shadow = this.attachShadow({
|
||||
mode: 'open'
|
||||
}).append(smNotifications.content.cloneNode(true))
|
||||
}
|
||||
|
||||
handleTouchStart = (e) => {
|
||||
this.notification = e.target.closest('.notification')
|
||||
this.touchStartX = e.changedTouches[0].clientX
|
||||
this.notification.style.transition = 'initial'
|
||||
this.touchStartTime = e.timeStamp
|
||||
}
|
||||
|
||||
handleTouchMove = (e) => {
|
||||
e.preventDefault()
|
||||
if (this.touchStartX < e.changedTouches[0].clientX) {
|
||||
this.offset = e.changedTouches[0].clientX - this.touchStartX;
|
||||
this.touchEndAnimataion = requestAnimationFrame(this.movePopup)
|
||||
} else {
|
||||
this.offset = -(this.touchStartX - e.changedTouches[0].clientX);
|
||||
this.touchEndAnimataion = requestAnimationFrame(this.movePopup)
|
||||
}
|
||||
}
|
||||
|
||||
handleTouchEnd = (e) => {
|
||||
this.notification.style.transition = 'transform 0.3s, opacity 0.3s'
|
||||
this.touchEndTime = e.timeStamp
|
||||
cancelAnimationFrame(this.touchEndAnimataion)
|
||||
this.touchEndX = e.changedTouches[0].clientX
|
||||
if (this.touchEndTime - this.touchStartTime > 200) {
|
||||
if (this.touchEndX - this.touchStartX > this.threshold) {
|
||||
this.removeNotification(this.notification)
|
||||
} else if (this.touchStartX - this.touchEndX > this.threshold) {
|
||||
this.removeNotification(this.notification, true)
|
||||
} else {
|
||||
this.resetPosition()
|
||||
}
|
||||
} else {
|
||||
if (this.touchEndX > this.touchStartX) {
|
||||
this.removeNotification(this.notification)
|
||||
} else {
|
||||
this.removeNotification(this.notification, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
movePopup = () => {
|
||||
this.notification.style.transform = `translateX(${this.offset}px)`
|
||||
}
|
||||
|
||||
resetPosition = () => {
|
||||
this.notification.style.transform = `translateX(0)`
|
||||
}
|
||||
|
||||
push = (messageBody, type, pinned) => {
|
||||
let notification = document.createElement('div'),
|
||||
composition = ``
|
||||
notification.classList.add('notification')
|
||||
if (pinned)
|
||||
notification.classList.add('pinned')
|
||||
if (type === 'error') {
|
||||
composition += `
|
||||
<svg class="notification-icon icon error-icon" viewBox="0 0 64 64">
|
||||
<path d="M32,4.73a3.17,3.17,0,0,1,2.76,1.59l13.9,24.09L62.57,54.49a3.19,3.19,0,0,1-2.76,4.78H4.19a3.19,3.19,0,0,1-2.76-4.78L15.34,30.41,29.24,6.32A3.17,3.17,0,0,1,32,4.73m0-1a4.14,4.14,0,0,0-3.62,2.09L14.47,29.91.57,54a4.19,4.19,0,0,0,3.62,6.28H59.81A4.19,4.19,0,0,0,63.43,54L49.53,29.91,35.62,5.82A4.14,4.14,0,0,0,32,3.73Z"/>
|
||||
<line x1="32" y1="24" x2="32" y2="36"/>
|
||||
<line x1="32" y1="46" x2="32" y2="48"/>
|
||||
</svg>`
|
||||
} else if (type === 'success') {
|
||||
composition += `
|
||||
<svg class="notification-icon icon success-icon" viewBox="0 0 64 64">
|
||||
<polyline points="0.35 31.82 21.45 52.98 63.65 10.66"/>
|
||||
</svg>`
|
||||
}
|
||||
composition += `
|
||||
<p>${messageBody}</p>
|
||||
<svg class="icon close" viewBox="0 0 64 64">
|
||||
<title>Close</title>
|
||||
<line x1="64" y1="0" x2="0" y2="64"/>
|
||||
<line x1="64" y1="64" x2="0" y2="0"/>
|
||||
</svg>`
|
||||
notification.innerHTML = composition
|
||||
this.notificationPanel.prepend(notification)
|
||||
if (window.innerWidth > 640) {
|
||||
notification.animate([{
|
||||
transform: `translateX(1rem)`,
|
||||
opacity: '0'
|
||||
},
|
||||
{
|
||||
transform: 'translateX(0)',
|
||||
opacity: '1'
|
||||
}
|
||||
], this.animationOptions).onfinish = () => {
|
||||
notification.setAttribute('style', `transform: none;`);
|
||||
}
|
||||
} else {
|
||||
notification.setAttribute('style', `transform: translateY(0); opacity: 1`)
|
||||
}
|
||||
notification.addEventListener('touchstart', this.handleTouchStart)
|
||||
notification.addEventListener('touchmove', this.handleTouchMove)
|
||||
notification.addEventListener('touchend', this.handleTouchEnd)
|
||||
}
|
||||
|
||||
removeNotification = (notification, toLeft) => {
|
||||
if (!this.offset)
|
||||
this.offset = 0;
|
||||
|
||||
if (toLeft)
|
||||
notification.animate([{
|
||||
transform: `translateX(${this.offset}px)`,
|
||||
opacity: '1'
|
||||
},
|
||||
{
|
||||
transform: `translateX(-100%)`,
|
||||
opacity: '0'
|
||||
}
|
||||
], this.animationOptions).onfinish = () => {
|
||||
notification.remove()
|
||||
}
|
||||
else {
|
||||
notification.animate([{
|
||||
transform: `translateX(${this.offset}px)`,
|
||||
opacity: '1'
|
||||
},
|
||||
{
|
||||
transform: `translateX(100%)`,
|
||||
opacity: '0'
|
||||
}
|
||||
], this.animationOptions).onfinish = () => {
|
||||
notification.remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clearAll = () => {
|
||||
Array.from(this.notificationPanel.children).forEach(child => {
|
||||
this.removeNotification(child)
|
||||
})
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.notificationPanel = this.shadowRoot.querySelector('.notification-panel')
|
||||
this.animationOptions = {
|
||||
duration: 300,
|
||||
fill: "forwards",
|
||||
easing: "ease"
|
||||
}
|
||||
this.fontSize = Number(window.getComputedStyle(document.body).getPropertyValue('font-size').match(/\d+/)[0])
|
||||
this.notification
|
||||
this.offset
|
||||
this.touchStartX = 0
|
||||
this.touchEndX = 0
|
||||
this.touchStartTime = 0
|
||||
this.touchEndTime = 0
|
||||
this.threshold = this.notificationPanel.getBoundingClientRect().width * 0.3
|
||||
this.touchEndAnimataion;
|
||||
|
||||
this.notificationPanel.addEventListener('click', e => {
|
||||
if (e.target.closest('.close'))(
|
||||
this.removeNotification(e.target.closest('.notification'))
|
||||
)
|
||||
})
|
||||
|
||||
const observer = new MutationObserver(mutationList => {
|
||||
mutationList.forEach(mutation => {
|
||||
if (mutation.type === 'childList') {
|
||||
if (mutation.addedNodes.length) {
|
||||
if (!mutation.addedNodes[0].classList.contains('pinned'))
|
||||
setTimeout(() => {
|
||||
this.removeNotification(mutation.addedNodes[0])
|
||||
}, 5000);
|
||||
if (window.innerWidth > 640)
|
||||
this.notificationPanel.style.padding = '1.5rem 0 3rem 1.5rem';
|
||||
else
|
||||
this.notificationPanel.style.padding = '1rem 1rem 2rem 1rem';
|
||||
} else if (mutation.removedNodes.length && !this.notificationPanel.children.length) {
|
||||
this.notificationPanel.style.padding = 0;
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
observer.observe(this.notificationPanel, {
|
||||
attributes: true,
|
||||
childList: true,
|
||||
subtree: true
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const domRefs = {};
|
||||
|
||||
function getRef(elementId) {
|
||||
if (!domRefs.hasOwnProperty(elementId)) {
|
||||
domRefs[elementId] = {
|
||||
count: 1,
|
||||
ref: null,
|
||||
};
|
||||
return document.getElementById(elementId);
|
||||
} else {
|
||||
if (domRefs[elementId].count < 3) {
|
||||
domRefs[elementId].count = domRefs[elementId].count + 1;
|
||||
return document.getElementById(elementId);
|
||||
} else {
|
||||
if (!domRefs[elementId].ref)
|
||||
domRefs[elementId].ref = document.getElementById(elementId);
|
||||
return domRefs[elementId].ref;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Checks for internet connection status
|
||||
if (!navigator.onLine)
|
||||
notify(
|
||||
"There seems to be a problem connecting to the internet, Please check you internet connection.",
|
||||
"error",
|
||||
"",
|
||||
true
|
||||
);
|
||||
window.addEventListener("offline", () => {
|
||||
notify(
|
||||
"There seems to be a problem connecting to the internet, Please check you internet connection.",
|
||||
"error",
|
||||
true,
|
||||
true
|
||||
);
|
||||
});
|
||||
window.addEventListener("online", () => {
|
||||
getRef("notification_drawer").clearAll();
|
||||
notify("We are back online.", "success");
|
||||
});
|
||||
|
||||
const themeSwitcher = getRef("theme_switcher");
|
||||
|
||||
if (themeSwitcher) {
|
||||
if (localStorage.theme === "dark") {
|
||||
nightlight();
|
||||
themeSwitcher.checked = true;
|
||||
} else {
|
||||
daylight();
|
||||
themeSwitcher.checked = false;
|
||||
}
|
||||
|
||||
function daylight() {
|
||||
document.body.setAttribute("data-theme", "light");
|
||||
}
|
||||
|
||||
function nightlight() {
|
||||
document.body.setAttribute("data-theme", "dark");
|
||||
}
|
||||
themeSwitcher.addEventListener("change", function (e) {
|
||||
if (this.checked) {
|
||||
nightlight();
|
||||
localStorage.setItem("theme", "dark");
|
||||
} else {
|
||||
daylight();
|
||||
localStorage.setItem("theme", "light");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//Function for displaying toast notifications. pass in error for mode param if you want to show an error.
|
||||
function notify(message, mode, pinned, sound) {
|
||||
if (mode === "error") console.error(message);
|
||||
else console.log(message);
|
||||
getRef("notification_drawer").push(message, mode, pinned);
|
||||
if (navigator.onLine && sound) {
|
||||
getRef("notification_sound").currentTime = 0;
|
||||
getRef("notification_sound").play();
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
document.addEventListener("pointerdown", (e) => {
|
||||
if (e.target.closest("button, sm-button:not([disable]), .interact")) {
|
||||
createRipple(e, e.target.closest("button, sm-button, .interact"));
|
||||
}
|
||||
else if(isDropdownOpen && !e.target.closest('.dropdown')){
|
||||
changeDropdownState('profile_dropdown', 'hide')
|
||||
}
|
||||
});
|
||||
});
|
||||
function createRipple(event, target) {
|
||||
const circle = document.createElement("span");
|
||||
const diameter = Math.max(target.clientWidth, target.clientHeight);
|
||||
const radius = diameter / 2;
|
||||
const targetDimensions = target.getBoundingClientRect();
|
||||
circle.style.width = circle.style.height = `${diameter}px`;
|
||||
circle.style.left = `${event.clientX - (targetDimensions.left + radius)}px`;
|
||||
circle.style.top = `${event.clientY - (targetDimensions.top + radius)}px`;
|
||||
circle.classList.add("ripple");
|
||||
const rippleAnimation = circle.animate(
|
||||
[
|
||||
{
|
||||
transform: "scale(3)",
|
||||
opacity: 0,
|
||||
},
|
||||
],
|
||||
{
|
||||
duration: 1000,
|
||||
fill: "forwards",
|
||||
easing: "ease-out",
|
||||
}
|
||||
);
|
||||
target.append(circle);
|
||||
rippleAnimation.onfinish = () => {
|
||||
circle.remove();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
let prefersInr = true
|
||||
if(localStorage.getItem('preferred-currency')){
|
||||
if(localStorage.getItem('preferred-currency') === 'inr')
|
||||
{
|
||||
prefersInr = true
|
||||
showCurrentPrices()
|
||||
}
|
||||
else{
|
||||
prefersInr = false
|
||||
showCurrentPrices()
|
||||
}
|
||||
document.querySelector(`sm-option[value="${localStorage.getItem('preferred-currency')}"]`).setAttribute('selected', '')
|
||||
}
|
||||
else{
|
||||
localStorage.setItem('preferred-currency', 'inr')
|
||||
getRef('currency_selector').value = 'INR'
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('currency_selector').addEventListener('change', e => {
|
||||
getRef('currency_selector').addEventListener('change', e => {
|
||||
prefersInr = e.detail.value === 'inr' ? true : false
|
||||
localStorage.setItem('preferred-currency', e.detail.value)
|
||||
document.querySelectorAll('bond-transaction').forEach(bond => bond.toggleCurrency())
|
||||
showCurrentPrices()
|
||||
})
|
||||
|
||||
function showCurrentPrices(){
|
||||
if(prefersInr){
|
||||
getRef('usd-rate').classList.remove('hide-completely')
|
||||
getRef('btc-usd-rate').classList.add('hide-completely')
|
||||
getRef('btc-inr-rate').classList.remove('hide-completely')
|
||||
}
|
||||
else{
|
||||
getRef('usd-rate').classList.add('hide-completely')
|
||||
getRef('btc-usd-rate').classList.remove('hide-completely')
|
||||
getRef('btc-inr-rate').classList.add('hide-completely')
|
||||
}
|
||||
}
|
||||
|
||||
let isDropdownOpen = false
|
||||
|
||||
function changeDropdownState(target, mode, trigger){
|
||||
const options = {
|
||||
duration: 300,
|
||||
easing: 'ease',
|
||||
fill: 'both',
|
||||
}
|
||||
if(mode === 'show'){
|
||||
showDropdown(target, options, trigger)
|
||||
}
|
||||
else if(mode === 'toggle'){
|
||||
if(isDropdownOpen){
|
||||
hideDropdown(target, options)
|
||||
}
|
||||
else{
|
||||
showDropdown(target, options, trigger)
|
||||
}
|
||||
}
|
||||
else if (mode === 'hide'){
|
||||
hideDropdown(target, options)
|
||||
}
|
||||
}
|
||||
|
||||
function showDropdown(target, options, trigger){
|
||||
if(isDropdownOpen) return
|
||||
if(trigger){
|
||||
const triggerDimensions = trigger.getBoundingClientRect()
|
||||
getRef(target).setAttribute('style', `top: ${triggerDimensions.top + triggerDimensions.height + document.documentElement.scrollTop}px; right: calc(${window.innerWidth - triggerDimensions.right}px - 1.5rem)`)
|
||||
}
|
||||
getRef(target).classList.remove('hide-completely')
|
||||
getRef(target).animate([
|
||||
{transform: 'translateY(-1rem)', opacity: 0},
|
||||
{transform: 'translateY(0)', opacity: 1},
|
||||
], options)
|
||||
.onfinish = () => {
|
||||
isDropdownOpen = true
|
||||
}
|
||||
}
|
||||
|
||||
function hideDropdown(target, options){
|
||||
if(!isDropdownOpen) return
|
||||
getRef(target).animate([
|
||||
{transform: 'translateY(0)', opacity: 1},
|
||||
{transform: 'translateY(-1rem)', opacity: 0},
|
||||
], options)
|
||||
.onfinish = () => {
|
||||
isDropdownOpen = false
|
||||
getRef(target).classList.add('hide-completely')
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<script>
|
||||
@ -8712,7 +9505,7 @@ Bitcoin.Util = {
|
||||
|
||||
}
|
||||
|
||||
document.getElementById('bond_list').append(frag)
|
||||
getRef('bond_list').append(frag)
|
||||
}
|
||||
|
||||
function parseDetails(data) {
|
||||
@ -8808,16 +9601,16 @@ Bitcoin.Util = {
|
||||
return details;
|
||||
}
|
||||
|
||||
const refreshBtn = document.getElementById('refresh-btn');
|
||||
const refreshBtn = getRef('refresh-btn');
|
||||
refreshBtn.addEventListener("click", evt => {
|
||||
getCurrentRates().then(rates => {
|
||||
USD_current = rates.USD_INR;
|
||||
BTC_current = rates.BTC_USD;
|
||||
console.log(`USD rate: ${USD_current} INR\nBTC rate: ${BTC_current} USD`);
|
||||
document.getElementById("usd-rate").textContent = `USD: ₹${rates.USD_INR.toFixed(2)}`;
|
||||
document.getElementById("btc-usd-rate").textContent = `BTC: $${rates.BTC_USD.toFixed(2)}`;
|
||||
document.getElementById("btc-inr-rate").textContent = `₹${rates.BTC_INR.toFixed(2)}`;
|
||||
document.getElementById("bond_list").innerHTML = '';
|
||||
getRef("usd-rate").textContent = `USD: ₹${rates.USD_INR.toFixed(2)}`;
|
||||
getRef("btc-usd-rate").textContent = `BTC: $${rates.BTC_USD.toFixed(2)}`;
|
||||
getRef("btc-inr-rate").textContent = `BTC: ₹${rates.BTC_INR.toFixed(2)}`;
|
||||
getRef("bond_list").innerHTML = '';
|
||||
compactIDB.readAllData("bonds")
|
||||
.then(result => renderData(result))
|
||||
.catch(error => console.error(error))
|
||||
@ -8912,7 +9705,7 @@ Bitcoin.Util = {
|
||||
].join("|");
|
||||
}
|
||||
|
||||
document.getElementById("add-bond-form").addEventListener("submit", evt => {
|
||||
getRef("add-bond-form").addEventListener("submit", evt => {
|
||||
evt.preventDefault()
|
||||
let f = evt.target;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user