Added closed investment rendering
This commit is contained in:
parent
4ad8fdbc2f
commit
1ffb70858c
214
css/main.css
214
css/main.css
@ -18,30 +18,41 @@ body {
|
||||
body {
|
||||
--accent-color: #2353ff;
|
||||
--light-shade: rgba(var(--text-color), 0.06);
|
||||
--text-color: 17, 17, 17;
|
||||
--text-color-light: 100, 100, 100;
|
||||
--foreground-color: 255, 255, 255;
|
||||
--background-color: #f6f6f6;
|
||||
--error-color: red;
|
||||
--green: #00843b;
|
||||
--text-color: 20, 20, 20;
|
||||
--foreground-color: 252, 253, 255;
|
||||
--background-color: 241, 243, 248;
|
||||
--danger-color: rgb(255, 75, 75);
|
||||
--green: #1cad59;
|
||||
--yellow: rgb(220, 165, 0);
|
||||
color: rgba(var(--text-color), 1);
|
||||
background: var(--background-color);
|
||||
background: rgba(var(--background-color), 1);
|
||||
}
|
||||
|
||||
body[data-theme=dark] {
|
||||
--accent-color: #2353ff;
|
||||
--green: #13ff5a;
|
||||
--text-color: 240, 240, 240;
|
||||
--text-color-light: 170, 170, 170;
|
||||
--foreground-color: 20, 20, 20;
|
||||
--background-color: #0a0a0a;
|
||||
--error-color: rgb(255, 106, 106);
|
||||
--text-color: 200, 200, 200;
|
||||
--foreground-color: 27, 28, 29;
|
||||
--background-color: 21, 22, 22;
|
||||
--danger-color: rgb(255, 106, 106);
|
||||
--green: #00e676;
|
||||
--yellow: rgb(255, 213, 5);
|
||||
}
|
||||
body[data-theme=dark] ::-webkit-calendar-picker-indicator {
|
||||
filter: invert(1);
|
||||
}
|
||||
body[data-theme=dark] sm-input.outlined {
|
||||
--active-placeholder-color: rgba(var(--text-color), 1);
|
||||
body[data-theme=dark] a:-webkit-any-link {
|
||||
filter: saturate(0.5) brightness(2);
|
||||
}
|
||||
body[data-theme=dark] a:-moz-any-link {
|
||||
filter: saturate(0.5) brightness(2);
|
||||
}
|
||||
body[data-theme=dark] a:any-link {
|
||||
filter: saturate(0.5) brightness(2);
|
||||
}
|
||||
|
||||
.overpass {
|
||||
font-family: "Overpass", sans-serif;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.h1 {
|
||||
@ -54,6 +65,8 @@ body[data-theme=dark] sm-input.outlined {
|
||||
|
||||
.h3 {
|
||||
font-size: 3rem;
|
||||
line-height: 1.1;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.h4 {
|
||||
@ -185,6 +198,13 @@ button:disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.cta {
|
||||
text-transform: uppercase;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.05em;
|
||||
padding: 0.8rem 1rem;
|
||||
}
|
||||
|
||||
a:-webkit-any-link {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
@ -257,6 +277,37 @@ a:any-link:focus-visible {
|
||||
fill: rgba(var(--text-color), 1);
|
||||
}
|
||||
|
||||
.multi-state-button {
|
||||
display: grid;
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
.multi-state-button > * {
|
||||
grid-area: 1/1/2/2;
|
||||
}
|
||||
.multi-state-button button {
|
||||
z-index: 1;
|
||||
}
|
||||
.multi-state-button sm-spinner {
|
||||
justify-self: center;
|
||||
}
|
||||
|
||||
sm-spinner {
|
||||
--size: 1.5rem;
|
||||
--stroke-width: 0.1rem;
|
||||
}
|
||||
|
||||
.password-field label {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.password-field label input:checked ~ .visible {
|
||||
display: none;
|
||||
}
|
||||
.password-field label input:not(:checked) ~ .invisible {
|
||||
display: none;
|
||||
}
|
||||
|
||||
sm-input,
|
||||
sm-textarea {
|
||||
--border-radius: 0.5rem;
|
||||
@ -452,14 +503,10 @@ ul {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.hide-completely {
|
||||
.hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.no-transformations {
|
||||
transform: none !important;
|
||||
}
|
||||
|
||||
.overflow-ellipsis {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
@ -501,6 +548,15 @@ ul {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.popup__header {
|
||||
display: grid;
|
||||
gap: 0.5rem;
|
||||
width: 100%;
|
||||
padding: 0 1.5rem 0 0.5rem;
|
||||
align-items: center;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
}
|
||||
|
||||
#loading_page,
|
||||
#error_page {
|
||||
position: relative;
|
||||
@ -677,20 +733,15 @@ ul {
|
||||
|
||||
#main_header__logo {
|
||||
fill: white;
|
||||
height: 2.4rem;
|
||||
width: 2.4rem;
|
||||
margin-left: -0.3rem;
|
||||
height: 1.5rem;
|
||||
width: 1.5rem;
|
||||
}
|
||||
|
||||
.header__company-name {
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.header__app-name {
|
||||
font-weight: 700;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
#current_price {
|
||||
justify-self: flex-start;
|
||||
}
|
||||
@ -760,7 +811,7 @@ ul {
|
||||
}
|
||||
|
||||
#home_page {
|
||||
--side-padding: 5vw;
|
||||
--side-padding: 1rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 max(1rem, var(--side-padding));
|
||||
@ -769,7 +820,7 @@ ul {
|
||||
|
||||
#homepage__hero-section {
|
||||
color: white;
|
||||
padding: 2rem 0 12rem 0;
|
||||
padding: 2rem var(--side-padding) 9rem var(--side-padding);
|
||||
margin: 0 calc(-1 * max(1rem, var(--side-padding))) -5.5rem calc(-1 * max(1rem, var(--side-padding)));
|
||||
background-image: url(../assets/bg-1.svg);
|
||||
background-color: var(--accent-color);
|
||||
@ -779,6 +830,12 @@ ul {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
#refresh_button {
|
||||
color: var(--accent-color);
|
||||
background-color: white;
|
||||
border: solid thin rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.fund-list__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -834,7 +891,7 @@ ul {
|
||||
#fund_list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.5rem;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
#fund_list__empty-state {
|
||||
@ -952,6 +1009,9 @@ form select option {
|
||||
border-radius: 0.5rem;
|
||||
border: solid thin rgba(var(--text-color), 0.2);
|
||||
}
|
||||
.fund-investor > .grid:first-of-type {
|
||||
width: min(40ch, 100%);
|
||||
}
|
||||
.fund-investor__redeem {
|
||||
background-color: var(--accent-color);
|
||||
border-radius: 3rem;
|
||||
@ -960,6 +1020,15 @@ form select option {
|
||||
filter: saturate(0.8);
|
||||
align-self: flex-start;
|
||||
}
|
||||
.fund-investor .tag {
|
||||
display: inline-flex;
|
||||
padding: 0.4rem 0.8rem;
|
||||
border-radius: 0.5rem;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 500;
|
||||
color: var(--danger-color);
|
||||
border: solid 0.1rem var(--danger-color);
|
||||
}
|
||||
|
||||
.transaction-column {
|
||||
display: flex;
|
||||
@ -982,7 +1051,7 @@ form select option {
|
||||
.start-date {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 3rem;
|
||||
margin-bottom: 2rem;
|
||||
background-color: rgba(var(--text-color), 0.06);
|
||||
padding: 0.8rem 1rem;
|
||||
border-radius: 0.5rem;
|
||||
@ -1001,10 +1070,9 @@ form select option {
|
||||
}
|
||||
|
||||
.tapout-list {
|
||||
display: grid;
|
||||
gap: 1.5rem;
|
||||
overflow-x: auto;
|
||||
grid-auto-flow: column;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem 1.5rem;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
@ -1016,6 +1084,64 @@ form select option {
|
||||
justify-self: flex-end;
|
||||
}
|
||||
|
||||
.user-action-result__icon {
|
||||
justify-self: center;
|
||||
height: 4rem;
|
||||
width: 4rem;
|
||||
border-radius: 5rem;
|
||||
margin-bottom: 2rem;
|
||||
-webkit-animation: popup 1s;
|
||||
animation: popup 1s;
|
||||
}
|
||||
.user-action-result__icon.success {
|
||||
fill: rgba(var(--background-color), 1);
|
||||
padding: 1rem;
|
||||
background-color: #0bbe56;
|
||||
}
|
||||
.user-action-result__icon.failed {
|
||||
background-color: rgba(var(--text-color), 0.03);
|
||||
fill: var(--danger-color);
|
||||
}
|
||||
|
||||
@-webkit-keyframes popup {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0.2) translateY(600%);
|
||||
}
|
||||
10% {
|
||||
transform: scale(0.2) translateY(5rem);
|
||||
opacity: 1;
|
||||
}
|
||||
40% {
|
||||
transform: scale(0.2) translateY(0);
|
||||
}
|
||||
80% {
|
||||
transform: scale(1.1) translateY(0);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1) translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes popup {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0.2) translateY(600%);
|
||||
}
|
||||
10% {
|
||||
transform: scale(0.2) translateY(5rem);
|
||||
opacity: 1;
|
||||
}
|
||||
40% {
|
||||
transform: scale(0.2) translateY(0);
|
||||
}
|
||||
80% {
|
||||
transform: scale(1.1) translateY(0);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1) translateY(0);
|
||||
}
|
||||
}
|
||||
@media only screen and (max-width: 640px) {
|
||||
#main_header {
|
||||
grid-template-areas: ". profile-button";
|
||||
@ -1023,19 +1149,27 @@ form select option {
|
||||
#main_header .dropdown {
|
||||
grid-area: profile-button;
|
||||
}
|
||||
#homepage__hero-section {
|
||||
padding: 2rem 0 20rem 0;
|
||||
margin-bottom: -16rem;
|
||||
}
|
||||
.investor-input {
|
||||
grid-template-columns: 1fr auto;
|
||||
grid-template-areas: ". close" ". close";
|
||||
}
|
||||
.fund-block {
|
||||
margin: 0 -1rem;
|
||||
}
|
||||
.fund-link {
|
||||
grid-column: 2/3;
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: 640px) {
|
||||
sm-popup {
|
||||
--width: 26rem;
|
||||
}
|
||||
.popup__header {
|
||||
padding: 1.5rem 1.5rem 0 0.75rem;
|
||||
}
|
||||
#home_page {
|
||||
--side-padding: 8vw;
|
||||
}
|
||||
#main_header {
|
||||
padding: 2rem calc(5vw - 0.4rem);
|
||||
grid-template-columns: auto 1fr auto;
|
||||
|
||||
2
css/main.min.css
vendored
2
css/main.min.css
vendored
File diff suppressed because one or more lines are too long
182
css/main.scss
182
css/main.scss
@ -15,30 +15,34 @@ body {
|
||||
body {
|
||||
--accent-color: #2353ff;
|
||||
--light-shade: rgba(var(--text-color), 0.06);
|
||||
--text-color: 17, 17, 17;
|
||||
--text-color-light: 100, 100, 100;
|
||||
--foreground-color: 255, 255, 255;
|
||||
--background-color: #f6f6f6;
|
||||
--error-color: red;
|
||||
--green: #00843b;
|
||||
--text-color: 20, 20, 20;
|
||||
--foreground-color: 252, 253, 255;
|
||||
--background-color: 241, 243, 248;
|
||||
--danger-color: rgb(255, 75, 75);
|
||||
--green: #1cad59;
|
||||
--yellow: rgb(220, 165, 0);
|
||||
color: rgba(var(--text-color), 1);
|
||||
background: var(--background-color);
|
||||
background: rgba(var(--background-color), 1);
|
||||
}
|
||||
body[data-theme="dark"] {
|
||||
--accent-color: #2353ff;
|
||||
--green: #13ff5a;
|
||||
--text-color: 240, 240, 240;
|
||||
--text-color-light: 170, 170, 170;
|
||||
--foreground-color: 20, 20, 20;
|
||||
--background-color: #0a0a0a;
|
||||
--error-color: rgb(255, 106, 106);
|
||||
--text-color: 200, 200, 200;
|
||||
--foreground-color: 27, 28, 29;
|
||||
--background-color: 21, 22, 22;
|
||||
--danger-color: rgb(255, 106, 106);
|
||||
--green: #00e676;
|
||||
--yellow: rgb(255, 213, 5);
|
||||
::-webkit-calendar-picker-indicator {
|
||||
filter: invert(1);
|
||||
}
|
||||
sm-input.outlined {
|
||||
--active-placeholder-color: rgba(var(--text-color), 1);
|
||||
a:any-link {
|
||||
filter: saturate(0.5) brightness(2);
|
||||
}
|
||||
}
|
||||
.overpass {
|
||||
font-family: "Overpass", sans-serif;
|
||||
font-weight: 700;
|
||||
}
|
||||
.h1 {
|
||||
font-size: 6rem;
|
||||
}
|
||||
@ -47,6 +51,8 @@ body[data-theme="dark"] {
|
||||
}
|
||||
.h3 {
|
||||
font-size: 3rem;
|
||||
line-height: 1.1;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
.h4 {
|
||||
font-size: 2rem;
|
||||
@ -163,6 +169,12 @@ button,
|
||||
button:disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
.cta {
|
||||
text-transform: uppercase;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.05em;
|
||||
padding: 0.8rem 1rem;
|
||||
}
|
||||
a:any-link {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
@ -188,6 +200,38 @@ a:any-link:focus-visible {
|
||||
width: 1.2rem;
|
||||
fill: rgba(var(--text-color), 1);
|
||||
}
|
||||
.multi-state-button {
|
||||
display: grid;
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
|
||||
& > * {
|
||||
grid-area: 1/1/2/2;
|
||||
}
|
||||
|
||||
button {
|
||||
z-index: 1;
|
||||
}
|
||||
sm-spinner {
|
||||
justify-self: center;
|
||||
}
|
||||
}
|
||||
sm-spinner {
|
||||
--size: 1.5rem;
|
||||
--stroke-width: 0.1rem;
|
||||
}
|
||||
.password-field {
|
||||
label {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
input:checked ~ .visible {
|
||||
display: none;
|
||||
}
|
||||
input:not(:checked) ~ .invisible {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sm-input,
|
||||
sm-textarea {
|
||||
@ -337,12 +381,9 @@ ul {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
.hide-completely {
|
||||
.hidden {
|
||||
display: none !important;
|
||||
}
|
||||
.no-transformations {
|
||||
transform: none !important;
|
||||
}
|
||||
.overflow-ellipsis {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
@ -384,6 +425,14 @@ ul {
|
||||
.observe-empty-state:not(:empty) ~ .empty-state {
|
||||
display: none;
|
||||
}
|
||||
.popup__header {
|
||||
display: grid;
|
||||
gap: 0.5rem;
|
||||
width: 100%;
|
||||
padding: 0 1.5rem 0 0.5rem;
|
||||
align-items: center;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
}
|
||||
|
||||
#loading_page,
|
||||
#error_page {
|
||||
@ -499,17 +548,13 @@ ul {
|
||||
}
|
||||
#main_header__logo {
|
||||
fill: white;
|
||||
height: 2.4rem;
|
||||
width: 2.4rem;
|
||||
margin-left: -0.3rem;
|
||||
height: 1.5rem;
|
||||
width: 1.5rem;
|
||||
}
|
||||
.header__company-name {
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
}
|
||||
.header__app-name {
|
||||
font-weight: 700;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
#current_price {
|
||||
justify-self: flex-start;
|
||||
}
|
||||
@ -577,7 +622,7 @@ ul {
|
||||
}
|
||||
|
||||
#home_page {
|
||||
--side-padding: 5vw;
|
||||
--side-padding: 1rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 max(1rem, var(--side-padding));
|
||||
@ -585,7 +630,7 @@ ul {
|
||||
}
|
||||
#homepage__hero-section {
|
||||
color: white;
|
||||
padding: 2rem 0 12rem 0;
|
||||
padding: 2rem var(--side-padding) 9rem var(--side-padding);
|
||||
margin: 0 calc(-1 * max(1rem, var(--side-padding))) -5.5rem calc(-1 * max(1rem, var(--side-padding)));
|
||||
background-image: url(../assets/bg-1.svg);
|
||||
background-color: var(--accent-color);
|
||||
@ -594,6 +639,11 @@ ul {
|
||||
color: rgba($color: #fff, $alpha: 0.8);
|
||||
}
|
||||
}
|
||||
#refresh_button {
|
||||
color: var(--accent-color);
|
||||
background-color: white;
|
||||
border: solid thin rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.fund-list__header {
|
||||
display: flex;
|
||||
@ -650,7 +700,7 @@ ul {
|
||||
#fund_list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.5rem;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
#fund_list__empty-state {
|
||||
@ -749,6 +799,9 @@ form {
|
||||
padding: 1rem;
|
||||
border-radius: 0.5rem;
|
||||
border: solid thin rgba(var(--text-color), 0.2);
|
||||
& > .grid:first-of-type {
|
||||
width: min(40ch, 100%);
|
||||
}
|
||||
&__redeem {
|
||||
background-color: var(--accent-color);
|
||||
border-radius: 3rem;
|
||||
@ -757,6 +810,15 @@ form {
|
||||
filter: saturate(0.8);
|
||||
align-self: flex-start;
|
||||
}
|
||||
.tag {
|
||||
display: inline-flex;
|
||||
padding: 0.4rem 0.8rem;
|
||||
border-radius: 0.5rem;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 500;
|
||||
color: var(--danger-color);
|
||||
border: solid 0.1rem var(--danger-color);
|
||||
}
|
||||
}
|
||||
.transaction-column {
|
||||
display: flex;
|
||||
@ -777,7 +839,7 @@ form {
|
||||
.start-date {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 3rem;
|
||||
margin-bottom: 2rem;
|
||||
background-color: rgba(var(--text-color), 0.06);
|
||||
padding: 0.8rem 1rem;
|
||||
border-radius: 0.5rem;
|
||||
@ -793,10 +855,9 @@ form {
|
||||
}
|
||||
}
|
||||
.tapout-list {
|
||||
display: grid;
|
||||
gap: 1.5rem;
|
||||
overflow-x: auto;
|
||||
grid-auto-flow: column;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem 1.5rem;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.tapout-list li {
|
||||
@ -805,6 +866,42 @@ form {
|
||||
.fund-link {
|
||||
justify-self: flex-end;
|
||||
}
|
||||
.user-action-result__icon {
|
||||
justify-self: center;
|
||||
height: 4rem;
|
||||
width: 4rem;
|
||||
border-radius: 5rem;
|
||||
margin-bottom: 2rem;
|
||||
animation: popup 1s;
|
||||
&.success {
|
||||
fill: rgba(var(--background-color), 1);
|
||||
padding: 1rem;
|
||||
background-color: #0bbe56;
|
||||
}
|
||||
&.failed {
|
||||
background-color: rgba(var(--text-color), 0.03);
|
||||
fill: var(--danger-color);
|
||||
}
|
||||
}
|
||||
@keyframes popup {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0.2) translateY(600%);
|
||||
}
|
||||
10% {
|
||||
transform: scale(0.2) translateY(5rem);
|
||||
opacity: 1;
|
||||
}
|
||||
40% {
|
||||
transform: scale(0.2) translateY(0);
|
||||
}
|
||||
80% {
|
||||
transform: scale(1.1) translateY(0);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1) translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 640px) {
|
||||
#main_header {
|
||||
@ -813,19 +910,28 @@ form {
|
||||
grid-area: profile-button;
|
||||
}
|
||||
}
|
||||
#homepage__hero-section {
|
||||
padding: 2rem 0 20rem 0;
|
||||
margin-bottom: -16rem;
|
||||
}
|
||||
.investor-input {
|
||||
grid-template-columns: 1fr auto;
|
||||
grid-template-areas: ". close" ". close";
|
||||
}
|
||||
.fund-block {
|
||||
margin: 0 -1rem;
|
||||
}
|
||||
.fund-link {
|
||||
grid-column: 2/3;
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: 640px) {
|
||||
sm-popup {
|
||||
--width: 26rem;
|
||||
}
|
||||
|
||||
.popup__header {
|
||||
padding: 1.5rem 1.5rem 0 0.75rem;
|
||||
}
|
||||
#home_page {
|
||||
--side-padding: 8vw;
|
||||
}
|
||||
#main_header {
|
||||
padding: 2rem calc((10vw / 2) - 0.4rem);
|
||||
grid-template-columns: auto 1fr auto;
|
||||
|
||||
755
index.html
755
index.html
@ -10,13 +10,13 @@
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&display=swap"
|
||||
href="https://fonts.googleapis.com/css2?family=Overpass:wght@700&family=Roboto:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&display=swap"
|
||||
rel="stylesheet">
|
||||
<script id="floGlobals">
|
||||
/* Constants for FLO blockchain operations !!Make sure to add this at begining!! */
|
||||
const floGlobals = {
|
||||
blockchain: "FLO",
|
||||
adminID: "FFXy5pJnfzu2fCDLhpUremyXQjGtFpgCDN",
|
||||
adminID: "FT9qkvuWXWBDRhHd42tDr5nMYFSx7bEhV7",
|
||||
application: "BobsFund"
|
||||
}
|
||||
</script>
|
||||
@ -44,7 +44,7 @@
|
||||
<body onload="onLoadStartUp()" data-theme="light">
|
||||
<sm-notifications id="notification_drawer"></sm-notifications>
|
||||
<article id="loading_page" class="page">
|
||||
<h2 class="h2">Bob's Fund</h2>
|
||||
<h3 class="h3 overpass">Bob's Fund</h3>
|
||||
<svg id="loader" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<polygon points="17.76 23.78 17.76 40.22 32 48.44 46.24 40.22 46.24 23.78 32 15.56 17.76 23.78" />
|
||||
<polyline points="17.76 23.78 32 32 46.24 23.78" />
|
||||
@ -62,8 +62,8 @@
|
||||
<h4 class="h4 color-0-8 weight-500">RanchiMall</h4>
|
||||
</footer>
|
||||
</article>
|
||||
<article id="error_page" class="page hide-completely">
|
||||
<h2 class="h2">Bob's Fund</h2>
|
||||
<article id="error_page" class="page hidden">
|
||||
<h3 class="h3 overpass">Bob's Fund</h3>
|
||||
<svg class="sad-face" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
|
||||
<g class="face">
|
||||
<g class="eyes">
|
||||
@ -89,7 +89,7 @@
|
||||
<h4 class="h4 color-0-8 weight-500">RanchiMall</h4>
|
||||
</footer>
|
||||
</article>
|
||||
<header id="main_header" class="hide-completely">
|
||||
<header id="main_header" class="hidden">
|
||||
<div class="flex align-items-center">
|
||||
<svg id="main_header__logo" class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path
|
||||
@ -97,7 +97,6 @@
|
||||
</svg>
|
||||
<div class="grid">
|
||||
<h5 class="header__company-name">RanchiMall</h5>
|
||||
<h3 class="header__app-name">Bob's Fund</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div id="current_price" class="grid gap-1 flow-column align-items-center">
|
||||
@ -115,7 +114,7 @@
|
||||
</g>
|
||||
</svg>
|
||||
</button>
|
||||
<ul id="profile_dropdown" class="dropdown__panel hide-completely">
|
||||
<ul id="profile_dropdown" class="dropdown__panel hidden">
|
||||
<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>
|
||||
@ -134,9 +133,9 @@
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
<main id="home_page" class="page hide-completely">
|
||||
<section id="homepage__hero-section" class="full-bleed page-layout">
|
||||
<h3 class="h3 margin-bottom-1r">Bob's Fund<br>on FLO Blockchain</h3>
|
||||
<main id="home_page" class="page hidden">
|
||||
<section id="homepage__hero-section">
|
||||
<h3 class="h3 overpass margin-bottom-1r">Bob's Fund<br>on FLO Blockchain</h3>
|
||||
<p>
|
||||
Bob's Fund is a 20 year long term Bitcoin price linked product. Investors are entitled to 100%
|
||||
of Bitcoin price gains, but they must hold for 20 years. Over a very long time period, investor returns
|
||||
@ -147,9 +146,9 @@
|
||||
</section>
|
||||
<header class="fund-list__header">
|
||||
<h4 class="h4">Funds</h4>
|
||||
<button id="refresh_button" class="justify-right button--primary">Refresh</button>
|
||||
<button id="refresh_button" class="button justify-right">Refresh</button>
|
||||
</header>
|
||||
<sm-input id="search_investor" type="search" placeholder="Search investor with FLO ID">
|
||||
<sm-input id="search_investor" type="search" placeholder="Search investor with FLO address">
|
||||
<svg class="icon" slot="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" />
|
||||
@ -162,7 +161,7 @@
|
||||
</div> -->
|
||||
<section>
|
||||
<ul id="fund_list"></ul>
|
||||
<div id="fund_list__empty-state" class="grid hide-completely">
|
||||
<div id="fund_list__empty-state" class="grid hidden">
|
||||
<svg class="icon icon--big" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24"
|
||||
height="24">
|
||||
<path fill="none" d="M0 0h24v24H0z" />
|
||||
@ -172,7 +171,7 @@
|
||||
<h4>No Funds found</h4>
|
||||
</div>
|
||||
</main>
|
||||
<article id="admin_page" class="page page-layout hide-completely">
|
||||
<article id="admin_page" class="page page-layout hidden">
|
||||
<header class="flex margin-top-1-5 align-items-center margin-bottom-1-5r">
|
||||
<button onclick="showPage('home_page')">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
|
||||
@ -218,7 +217,7 @@
|
||||
Tapout
|
||||
</div>
|
||||
</sm-switch>
|
||||
<section id="tapout_container" class="grid gap-1-5 hide-completely">
|
||||
<section id="tapout_container" class="grid gap-1-5 hidden">
|
||||
<div class="grid gap-0-5">
|
||||
Tapout window
|
||||
<div class="flex">
|
||||
@ -248,14 +247,14 @@
|
||||
</label>
|
||||
</section>
|
||||
|
||||
<div id="fund_selector_container" class="grid margin-bottom-0-5r hide-completely">
|
||||
<div id="fund_selector_container" class="grid margin-bottom-0-5r hidden">
|
||||
<span class="margin-bottom-0-5r">Select Fund</span>
|
||||
<sm-select id="fund_selector"></sm-select>
|
||||
</div>
|
||||
<h4>Add Investors</h4>
|
||||
<ul id="investors_input_list" class="grid gap-1">
|
||||
<li class="investor-input grid">
|
||||
<sm-input placeholder="FLO ID" class="outlined" animate></sm-input>
|
||||
<sm-input placeholder="FLO address" class="outlined" animate></sm-input>
|
||||
<sm-input placeholder="Amount(₹)" type="number" min=0 class="outlined" animate></sm-input>
|
||||
<button class="remove-investor" title="Remove this investor">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
|
||||
@ -274,13 +273,13 @@
|
||||
</svg>
|
||||
Add new
|
||||
</button>
|
||||
<button id="add_investors_button" type="submit"
|
||||
class="button--primary justify-self-start hide-completely">Add Investors</button>
|
||||
<button id="add_investors_button" type="submit" class="button--primary justify-self-start hidden">Add
|
||||
Investors</button>
|
||||
<button id="create_fund_button" type="submit" class="button--primary justify-self-start">Create
|
||||
Fund</button>
|
||||
</form>
|
||||
</article>
|
||||
<article id="confirm_term_page" class="page page-layout hide-completely">
|
||||
<article id="confirm_term_page" class="page page-layout hidden">
|
||||
<header class="flex margin-top-1-5 align-items-center margin-bottom-1-5r">
|
||||
<button class="back-button" onclick="showPage('admin_page')">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
|
||||
@ -300,7 +299,7 @@
|
||||
term</button>
|
||||
</form>
|
||||
</article>
|
||||
<article id="confirm_fund_page" class="page page-layout hide-completely">
|
||||
<article id="confirm_fund_page" class="page page-layout hidden">
|
||||
<header class="flex margin-top-1-5 align-items-center margin-bottom-1-5r">
|
||||
<button class="back-button" onclick="showPage('admin_page')">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
|
||||
@ -320,147 +319,73 @@
|
||||
Fund</button>
|
||||
</form>
|
||||
</article>
|
||||
<sm-popup id="redeem_popup">
|
||||
<header slot="header" class="popup__header">
|
||||
<button class="popup__header__close" onclick="closePopup()">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
|
||||
<path fill="none" d="M0 0h24v24H0z" />
|
||||
<path
|
||||
d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z" />
|
||||
</svg>
|
||||
</button>
|
||||
<h3>Redeem fund</h3>
|
||||
</header>
|
||||
<div id="redeem_process">
|
||||
<div id="redeem_precess__get_priv_key">
|
||||
<sm-form class="grid gap-1-5">
|
||||
<div id="redeem__id"></div>
|
||||
<sm-input id="redeem_private_key" class="password-field" type="password"
|
||||
placeholder="FLO private key" error-text="Private key is invalid" autofocus data-private-key
|
||||
required>
|
||||
<label slot="right" class="interact">
|
||||
<input type="checkbox" class="hidden" autocomplete="off" readonly
|
||||
onchange="togglePrivateKeyVisibility(this)">
|
||||
<svg class="icon invisible" xmlns="http://www.w3.org/2000/svg" height="24px"
|
||||
viewBox="0 0 24 24" width="24px" fill="#000000">
|
||||
<title>Hide password</title>
|
||||
<path d="M0 0h24v24H0zm0 0h24v24H0zm0 0h24v24H0zm0 0h24v24H0z" fill="none" />
|
||||
<path
|
||||
d="M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z" />
|
||||
</svg>
|
||||
<svg class="icon visible" xmlns="http://www.w3.org/2000/svg" height="24px"
|
||||
viewBox="0 0 24 24" width="24px" fill="#000000">
|
||||
<title>Show password</title>
|
||||
<path d="M0 0h24v24H0z" fill="none" />
|
||||
<path
|
||||
d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z" />
|
||||
</svg>
|
||||
</label>
|
||||
</sm-input>
|
||||
<div class="multi-state-button">
|
||||
<button id="redeem_private_key_button" type="submit"
|
||||
class="button button--primary cta">Redeem</button>
|
||||
</div>
|
||||
</sm-form>
|
||||
</div>
|
||||
<div class="grid gap-0-5 hidden justify-center text-center">
|
||||
<svg class="icon user-action-result__icon success" 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>
|
||||
<h4>Redeem request sent</h4>
|
||||
<p>Balance may take upto 30mins to reflect in your FLO address</p>
|
||||
</div>
|
||||
<div class="grid gap-0-5 hidden justify-center text-center">
|
||||
<svg class="icon user-action-result__icon failed" 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="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z" />
|
||||
</svg>
|
||||
<h3>Failed</h3>
|
||||
<p id="redeem_failed_message"></p>
|
||||
</div>
|
||||
</div>
|
||||
</sm-popup>
|
||||
|
||||
|
||||
<script id="ui">
|
||||
function formatAmount(amount = 0, currency = 'inr') {
|
||||
amount = parseFloat(amount);
|
||||
if (!amount)
|
||||
return '₹0';
|
||||
return amount.toLocaleString(currency === 'inr' ? `en-IN` : 'en-US', { style: 'currency', currency })
|
||||
}
|
||||
const render = {
|
||||
investorInput() {
|
||||
const investorInput = document.createElement('li')
|
||||
investorInput.classList.add('investor-input', 'grid')
|
||||
investorInput.innerHTML = `
|
||||
<sm-input placeholder="FLO ID" class="outlined" animate></sm-input>
|
||||
<sm-input placeholder="Amount(₹)" type="number" min=0 class="outlined" animate></sm-input>
|
||||
<button class="remove-investor" title="Remove this investor">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></svg>
|
||||
</button>
|
||||
`
|
||||
return investorInput
|
||||
},
|
||||
fundPlaceholder() {
|
||||
const fund_ph = document.createElement('li')
|
||||
fund_ph.classList.add('fund-placeholder', 'grid')
|
||||
fund_ph.innerHTML = `
|
||||
<div class="flex-grid justify-start">
|
||||
<div class="placeholder__block"></div>
|
||||
<div class="placeholder__block"></div>
|
||||
<div class="placeholder__block"></div>
|
||||
<div class="placeholder__block"></div>
|
||||
</div>
|
||||
<div class="grid flow-column gap-1">
|
||||
<div class="placeholder__block"></div>
|
||||
<div class="placeholder__block"></div>
|
||||
</div>
|
||||
<div class="placeholder__block justify-self-end"></div>
|
||||
`
|
||||
return fund_ph
|
||||
},
|
||||
investorCard(details) {
|
||||
const {
|
||||
floId,
|
||||
amountInvested,
|
||||
netValue,
|
||||
fundId,
|
||||
isRedeemable = false,
|
||||
} = details
|
||||
return html`
|
||||
<li class="fund-investor" id=${`${fundId}_${floId}`} data-flo-id=${floId}>
|
||||
<div class="grid">
|
||||
<span class="label">FLO ID</span>
|
||||
<span class="value flo-id">${floId}</span>
|
||||
</div>
|
||||
<div class="flex gap-1-5">
|
||||
<div class="transaction-column">
|
||||
<span class="label">Invested</span>
|
||||
<span class="value amount-invested">${formatAmount(amountInvested[preferredCurrency], preferredCurrency)}</span>
|
||||
</div>
|
||||
<div class="transaction-column">
|
||||
<span class="label">Present value</span>
|
||||
<span class="value net-value" style="color: var(--green)">${formatAmount(netValue[preferredCurrency], preferredCurrency)}</span>
|
||||
</div>
|
||||
</div>
|
||||
<button class="button fund-investor__redeem" ?disabled=${!isRedeemable}>Redeem</button>
|
||||
</li>
|
||||
`
|
||||
},
|
||||
fundBlock(details) {
|
||||
let {
|
||||
fundTxs,
|
||||
startDate,
|
||||
endDate,
|
||||
baseUsd,
|
||||
baseBtc,
|
||||
tapouts,
|
||||
totalInvestment,
|
||||
totalNet,
|
||||
investorsFrag
|
||||
} = details
|
||||
const tapoutsFrag = []
|
||||
for (let tapout in tapouts) {
|
||||
const tapoutPoint = html`
|
||||
<li class="tapout-point grid">
|
||||
<span class="label">${tapout}</span>
|
||||
<span class="value">${tapouts[tapout]}</span>
|
||||
</li>`;
|
||||
tapoutsFrag.push(tapoutPoint)
|
||||
}
|
||||
const renderedFundTxs = fundTxs.map((tx, index) => {
|
||||
return html`<a href=${`${floBlockchainAPI.current_server}tx/${tx.txid}`}>Transaction ${index + 1}</a>`
|
||||
})
|
||||
|
||||
return html.node`
|
||||
<li class="fund-block">
|
||||
<h3 class="start-date">${startDate} Fund</h3>
|
||||
<div class="fund-block__details margin-bottom-3r">
|
||||
<div class="grid">
|
||||
<span class="label">End date</span>
|
||||
<span class="value end-date">${bobsFund.dateFormat(endDate)}</span>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-1">
|
||||
<div class="grid">
|
||||
<span class="label">Initial BTC value</span>
|
||||
<span class="value base-btc">${formatAmount(baseBtc[preferredCurrency], preferredCurrency)}</span>
|
||||
</div>
|
||||
<div class="grid">
|
||||
<span class="label">Base USD rate</span>
|
||||
<span class="value base-usd">${baseUsd.toLocaleString(`en-US`, { style: 'currency', currency: 'INR' })}</span>
|
||||
</div>
|
||||
</div>
|
||||
${tapoutsFrag.length ? html`
|
||||
<div class="tapout-container grid">
|
||||
<span class="value margin-bottom-0-5r">Tapouts</span>
|
||||
<ul class="tapout-list">${tapoutsFrag}</ul>
|
||||
</div>` : ''}
|
||||
<div class="flex flex-wrap gap-1">
|
||||
<div class="grid">
|
||||
<span class="label">Total investment</span>
|
||||
<span class="value total-investment">${formatAmount(totalInvestment[preferredCurrency], preferredCurrency)}</span>
|
||||
</div>
|
||||
<div class="grid">
|
||||
<span class="label">Total present value</span>
|
||||
<span class="value net-value" style="color: var(--green)">${formatAmount(totalNet[preferredCurrency], preferredCurrency)}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid">
|
||||
<span class="label">Fund transactions</span>
|
||||
<div class="flex gap-0-5">${renderedFundTxs}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid">
|
||||
<h4 class="margin-bottom-0-5r">Investors</h4>
|
||||
<ul class="investors-list grid">${investorsFrag}</ul>
|
||||
</div>
|
||||
</li>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const { html, render: renderElem } = uhtml;
|
||||
const domRefs = {}
|
||||
//Checks for internet connection status
|
||||
@ -512,6 +437,22 @@
|
||||
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
document.querySelectorAll('sm-input[data-flo-id]').forEach(input => input.customValidation = floCrypto.validateAddr)
|
||||
document.querySelectorAll('sm-input[data-private-key]').forEach(input => input.customValidation = floCrypto.getPubKeyHex)
|
||||
document.addEventListener('keyup', (e) => {
|
||||
if (e.code === 'Escape') {
|
||||
closePopup()
|
||||
}
|
||||
})
|
||||
document.addEventListener('keydown', e => {
|
||||
if (e.key === '/') {
|
||||
e.preventDefault();
|
||||
getRef('search_investor').focusIn()
|
||||
}
|
||||
})
|
||||
document.addEventListener('copy', () => {
|
||||
notify('copied', 'success')
|
||||
})
|
||||
document.addEventListener("pointerdown", (e) => {
|
||||
if (e.target.closest("button:not([disabled]), .interact")) {
|
||||
createRipple(e, e.target.closest("button, .interact"));
|
||||
@ -569,6 +510,387 @@
|
||||
}, wait);
|
||||
};
|
||||
}
|
||||
let zIndex = 50
|
||||
// function required for popups or modals to appear
|
||||
function openPopup(popupId, pinned) {
|
||||
zIndex++
|
||||
getRef(popupId).setAttribute('style', `z-index: ${zIndex}`)
|
||||
getRef(popupId).show({ pinned })
|
||||
return getRef(popupId);
|
||||
}
|
||||
|
||||
// hides the popup or modal
|
||||
function closePopup() {
|
||||
if (popupStack.peek() === undefined)
|
||||
return;
|
||||
popupStack.peek().popup.hide()
|
||||
}
|
||||
function buttonLoader(id, show) {
|
||||
const button = typeof id === 'string' ? getRef(id) : id;
|
||||
button.disabled = show;
|
||||
const animOptions = {
|
||||
duration: floGlobals.prefersReducedMotion ? 0 : 200,
|
||||
fill: 'forwards',
|
||||
easing: 'ease'
|
||||
}
|
||||
if (show) {
|
||||
button.animate([
|
||||
{
|
||||
clipPath: 'circle(100%)',
|
||||
},
|
||||
{
|
||||
clipPath: 'circle(0)',
|
||||
},
|
||||
], animOptions)
|
||||
button.parentNode.append(document.createElement('sm-spinner'))
|
||||
} else {
|
||||
button.getAnimations().forEach(anim => anim.cancel())
|
||||
const potentialTarget = button.parentNode.querySelector('sm-spinner')
|
||||
if (potentialTarget) potentialTarget.remove();
|
||||
}
|
||||
}
|
||||
document.addEventListener('popupopened', e => {
|
||||
getRef('home_page').setAttribute('inert', '')
|
||||
})
|
||||
document.addEventListener('popupclosed', e => {
|
||||
switch (e.detail.popup.id) {
|
||||
case 'redeem_popup':
|
||||
showChildElement(getRef('redeem_process'), 0);
|
||||
buttonLoader('redeem_private_key_button', false)
|
||||
getRef('redeem_private_key_button').disabled = true;
|
||||
break;
|
||||
}
|
||||
if (popupStack.items.length === 0) {
|
||||
getRef('home_page').removeAttribute('inert')
|
||||
}
|
||||
})
|
||||
const slideInLeft = [
|
||||
{
|
||||
opacity: 0,
|
||||
transform: 'translateX(1rem)'
|
||||
},
|
||||
{
|
||||
opacity: 1,
|
||||
transform: 'translateX(0)'
|
||||
}
|
||||
]
|
||||
const slideOutLeft = [
|
||||
{
|
||||
opacity: 1,
|
||||
transform: 'translateX(0)'
|
||||
},
|
||||
{
|
||||
opacity: 0,
|
||||
transform: 'translateX(-1rem)'
|
||||
},
|
||||
]
|
||||
const slideInRight = [
|
||||
{
|
||||
opacity: 0,
|
||||
transform: 'translateX(-1rem)'
|
||||
},
|
||||
{
|
||||
opacity: 1,
|
||||
transform: 'translateX(0)'
|
||||
}
|
||||
]
|
||||
const slideOutRight = [
|
||||
{
|
||||
opacity: 1,
|
||||
transform: 'translateX(0)'
|
||||
},
|
||||
{
|
||||
opacity: 0,
|
||||
transform: 'translateX(1rem)'
|
||||
},
|
||||
]
|
||||
const slideInDown = [
|
||||
{
|
||||
opacity: 0,
|
||||
transform: 'translateY(-1rem)'
|
||||
},
|
||||
{
|
||||
opacity: 1,
|
||||
transform: 'translateY(0)'
|
||||
},
|
||||
]
|
||||
const slideOutDown = [
|
||||
{
|
||||
opacity: 1,
|
||||
transform: 'translateY(0)'
|
||||
},
|
||||
{
|
||||
opacity: 0,
|
||||
transform: 'translateY(1rem)'
|
||||
},
|
||||
]
|
||||
const slideInUp = [
|
||||
{
|
||||
opacity: 0,
|
||||
transform: 'translateY(1rem)'
|
||||
},
|
||||
{
|
||||
opacity: 1,
|
||||
transform: 'translateY(0)'
|
||||
},
|
||||
]
|
||||
const slideOutUp = [
|
||||
{
|
||||
opacity: 1,
|
||||
transform: 'translateY(0)'
|
||||
},
|
||||
{
|
||||
opacity: 0,
|
||||
transform: 'translateY(-1rem)'
|
||||
},
|
||||
]
|
||||
|
||||
function showChildElement(id, index, options = {}) {
|
||||
return new Promise((resolve) => {
|
||||
const { mobileView = false, entry, exit } = options
|
||||
const animOptions = {
|
||||
duration: floGlobals.prefersReducedMotion ? 0 : 150,
|
||||
easing: 'ease',
|
||||
fill: 'forwards'
|
||||
}
|
||||
const parent = typeof id === 'string' ? document.getElementById(id) : id;
|
||||
const visibleElement = [...parent.children].find(elem => !elem.classList.contains(mobileView ? 'hide-on-mobile' : 'hidden'));
|
||||
if (visibleElement === parent.children[index]) return;
|
||||
visibleElement.getAnimations().forEach(anim => anim.cancel())
|
||||
parent.children[index].getAnimations().forEach(anim => anim.cancel())
|
||||
if (visibleElement) {
|
||||
if (exit) {
|
||||
parent.style.overflow = 'hidden'
|
||||
visibleElement.animate(exit, animOptions).onfinish = () => {
|
||||
visibleElement.classList.add(mobileView ? 'hide-on-mobile' : 'hidden')
|
||||
parent.style.overflow = ''
|
||||
}
|
||||
parent.children[index].classList.remove(mobileView ? 'hide-on-mobile' : 'hidden')
|
||||
if (entry)
|
||||
parent.children[index].animate(entry, animOptions).onfinish = () => resolve()
|
||||
} else {
|
||||
visibleElement.classList.add(mobileView ? 'hide-on-mobile' : 'hidden')
|
||||
parent.children[index].classList.remove(mobileView ? 'hide-on-mobile' : 'hidden')
|
||||
resolve()
|
||||
}
|
||||
} else {
|
||||
parent.children[index].classList.remove(mobileView ? 'hide-on-mobile' : 'hidden')
|
||||
parent.children[index].animate(entry, animOptions).onfinish = () => resolve()
|
||||
}
|
||||
})
|
||||
}
|
||||
function togglePrivateKeyVisibility(input) {
|
||||
const target = input.closest('sm-input')
|
||||
target.type = target.type === 'password' ? 'text' : 'password';
|
||||
target.focusIn()
|
||||
}
|
||||
|
||||
function formatAmount(amount = 0, currency = 'inr') {
|
||||
amount = parseFloat(amount);
|
||||
if (!amount)
|
||||
return '₹0';
|
||||
return amount.toLocaleString(currency === 'inr' ? `en-IN` : 'en-US', { style: 'currency', currency })
|
||||
}
|
||||
const render = {
|
||||
investorInput() {
|
||||
const investorInput = document.createElement('li')
|
||||
investorInput.classList.add('investor-input', 'grid')
|
||||
investorInput.innerHTML = `
|
||||
<sm-input placeholder="FLO address" class="outlined" animate></sm-input>
|
||||
<sm-input placeholder="Amount(₹)" type="number" min=0 class="outlined" animate></sm-input>
|
||||
<button class="remove-investor" title="Remove this investor">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></svg>
|
||||
</button>
|
||||
`
|
||||
return investorInput
|
||||
},
|
||||
fundPlaceholder() {
|
||||
const fund_ph = document.createElement('li')
|
||||
fund_ph.classList.add('fund-placeholder', 'grid')
|
||||
fund_ph.innerHTML = `
|
||||
<div class="flex-grid justify-start">
|
||||
<div class="placeholder__block"></div>
|
||||
<div class="placeholder__block"></div>
|
||||
<div class="placeholder__block"></div>
|
||||
<div class="placeholder__block"></div>
|
||||
</div>
|
||||
<div class="grid flow-column gap-1">
|
||||
<div class="placeholder__block"></div>
|
||||
<div class="placeholder__block"></div>
|
||||
</div>
|
||||
<div class="placeholder__block justify-self-end"></div>
|
||||
`
|
||||
return fund_ph
|
||||
},
|
||||
investmentCard(details) {
|
||||
const {
|
||||
floId,
|
||||
amountInvested,
|
||||
netValue,
|
||||
fundId,
|
||||
hasMatured = false,
|
||||
allowsEarlyWithdrawal = false,
|
||||
} = details
|
||||
const isRedeemable = hasMatured || allowsEarlyWithdrawal
|
||||
return html`
|
||||
<li class="fund-investor" id=${`${fundId}_${floId}`}>
|
||||
<div class="grid">
|
||||
<span class="label">FLO address</span>
|
||||
<span class="value flo-id">${floId}</span>
|
||||
</div>
|
||||
<div class="flex gap-1-5">
|
||||
<div class="transaction-column">
|
||||
<span class="label">Invested</span>
|
||||
<span class="value amount-invested">${formatAmount(amountInvested[preferredCurrency], preferredCurrency)}</span>
|
||||
</div>
|
||||
<div class="transaction-column">
|
||||
<span class="label">Present value</span>
|
||||
<span class="value net-value" style="color: var(--green)">${formatAmount(netValue[preferredCurrency], preferredCurrency)}</span>
|
||||
</div>
|
||||
</div>
|
||||
<button class="button fund-investor__redeem" ?disabled=${!isRedeemable}>Redeem</button>
|
||||
</li>
|
||||
`
|
||||
},
|
||||
closedInvestmentCard(details) {
|
||||
const {
|
||||
floId,
|
||||
amountInvested,
|
||||
fundId,
|
||||
BTC_net,
|
||||
endDate,
|
||||
finalAmount,
|
||||
USD_net,
|
||||
payment_refRef
|
||||
} = details
|
||||
return html`
|
||||
<li class="fund-investor" id=${`${fundId}_${floId}`}>
|
||||
<div class="flex align-items-center space-between w-100">
|
||||
<span class="tag">Closed: ${bobsFund.dateFormat(endDate)}</span>
|
||||
</div>
|
||||
<div class="grid">
|
||||
<span class="label">FLO address</span>
|
||||
<span class="value flo-id">${floId}</span>
|
||||
</div>
|
||||
<div class="flex gap-1-5">
|
||||
<div class="transaction-column">
|
||||
<span class="label">Invested</span>
|
||||
<span class="value amount-invested">${formatAmount(amountInvested[preferredCurrency], preferredCurrency)}</span>
|
||||
</div>
|
||||
<div class="transaction-column">
|
||||
<span class="label">Withdrawn amount</span>
|
||||
<span class="value net-value" style="color: var(--green)">${formatAmount(finalAmount[preferredCurrency], preferredCurrency)}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-1-5 align-center space-between w-100">
|
||||
<div class="transaction-column">
|
||||
<a href=${`${floBlockchainAPI.current_server}tx/${payment_refRef}`} target="_blank">See withdrawal transaction</a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
`
|
||||
},
|
||||
investmentCard(details) {
|
||||
const {
|
||||
floId,
|
||||
amountInvested,
|
||||
netValue,
|
||||
fundId,
|
||||
hasMatured = false,
|
||||
allowsEarlyWithdrawal = false,
|
||||
} = details
|
||||
const isRedeemable = hasMatured || allowsEarlyWithdrawal
|
||||
return html`
|
||||
<li class="fund-investor" id=${`${fundId}_${floId}`}>
|
||||
<div class="grid">
|
||||
<span class="label">FLO address</span>
|
||||
<span class="value flo-id">${floId}</span>
|
||||
</div>
|
||||
<div class="flex gap-1-5">
|
||||
<div class="transaction-column">
|
||||
<span class="label">Invested</span>
|
||||
<span class="value amount-invested">${formatAmount(amountInvested[preferredCurrency], preferredCurrency)}</span>
|
||||
</div>
|
||||
<div class="transaction-column">
|
||||
<span class="label">Present value</span>
|
||||
<span class="value net-value" style="color: var(--green)">${formatAmount(netValue[preferredCurrency], preferredCurrency)}</span>
|
||||
</div>
|
||||
</div>
|
||||
<button class="button fund-investor__redeem" ?disabled=${!isRedeemable}>Redeem</button>
|
||||
</li>
|
||||
`
|
||||
},
|
||||
fundBlock(details) {
|
||||
let {
|
||||
fundTxs,
|
||||
startDate,
|
||||
endDate,
|
||||
baseUsd,
|
||||
baseBtc,
|
||||
tapouts,
|
||||
totalInvestment,
|
||||
totalNet,
|
||||
investorsFrag
|
||||
} = details
|
||||
const tapoutsPoints = tapouts.map((tapout, index) => {
|
||||
const duration = `${bobsFund.dateFormat(tapout.start)} to ${bobsFund.dateFormat(tapout.end)}`
|
||||
return html`
|
||||
<li class="tapout-point grid">
|
||||
<span class="label">Tapout ${index + 1}</span>
|
||||
<span class="value">${duration}</span>
|
||||
</li>`;
|
||||
})
|
||||
const renderedFundTxs = fundTxs.map((tx, index) => {
|
||||
return html`<a href=${`${floBlockchainAPI.current_server}tx/${tx.txid}`} target="_blank">Transaction ${index + 1}</a>`
|
||||
})
|
||||
|
||||
return html.node`
|
||||
<li class="fund-block">
|
||||
<h4 class="start-date">${startDate} Fund</h4>
|
||||
<div class="fund-block__details margin-bottom-3r">
|
||||
<div class="grid">
|
||||
<span class="label">End date</span>
|
||||
<span class="value end-date">${bobsFund.dateFormat(endDate)}</span>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-1">
|
||||
<div class="grid">
|
||||
<span class="label">Initial BTC value</span>
|
||||
<span class="value base-btc">${formatAmount(baseBtc[preferredCurrency], preferredCurrency)}</span>
|
||||
</div>
|
||||
<div class="grid">
|
||||
<span class="label">Base USD rate</span>
|
||||
<span class="value base-usd">${baseUsd.toLocaleString(`en-US`, { style: 'currency', currency: 'INR' })}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-1">
|
||||
<div class="grid">
|
||||
<span class="label">Total investment</span>
|
||||
<span class="value total-investment">${formatAmount(totalInvestment[preferredCurrency], preferredCurrency)}</span>
|
||||
</div>
|
||||
<div class="grid">
|
||||
<span class="label">Total present value</span>
|
||||
<span class="value net-value" style="color: var(--green)">${formatAmount(totalNet[preferredCurrency], preferredCurrency)}</span>
|
||||
</div>
|
||||
</div>
|
||||
${tapoutsPoints.length ? html`
|
||||
<div class="grid">
|
||||
<span class="value margin-bottom-0-5r">Tapouts</span>
|
||||
<ul class="tapout-list">${tapoutsPoints}</ul>
|
||||
</div>` : ''}
|
||||
<div class="grid">
|
||||
<span class="label">Fund transactions</span>
|
||||
<div class="flex gap-0-5 flex-wrap">${renderedFundTxs}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid">
|
||||
<h4 class="margin-bottom-0-5r">Investors</h4>
|
||||
<ul class="investors-list grid">${investorsFrag}</ul>
|
||||
</div>
|
||||
</li>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let preferredCurrency
|
||||
|
||||
@ -618,7 +940,7 @@
|
||||
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).classList.remove('hidden')
|
||||
getRef(target).animate([
|
||||
{ transform: 'translateY(-1rem)', opacity: 0 },
|
||||
{ transform: 'translateY(0)', opacity: 1 },
|
||||
@ -636,13 +958,13 @@
|
||||
], options)
|
||||
.onfinish = () => {
|
||||
isDropdownOpen = false
|
||||
getRef(target).classList.add('hide-completely')
|
||||
getRef(target).classList.add('hidden')
|
||||
}
|
||||
}
|
||||
|
||||
function showPage(target) {
|
||||
document.querySelector('.page:not(.hide-completely)')?.classList.add('hide-completely')
|
||||
getRef(target).classList.remove('hide-completely')
|
||||
document.querySelector('.page:not(.hidden)')?.classList.add('hidden')
|
||||
getRef(target).classList.remove('hidden')
|
||||
if (target === 'home_page') {
|
||||
clearAddedInvestors()
|
||||
getRef("create_fund_form").reset()
|
||||
@ -655,32 +977,32 @@
|
||||
getRef('get_fund_private_key').value = ''
|
||||
}
|
||||
if (target === 'loading_page' || target === 'error_page') {
|
||||
getRef('main_header').classList.add('hide-completely')
|
||||
getRef('main_header').classList.add('hidden')
|
||||
}
|
||||
else {
|
||||
getRef('main_header').classList.remove('hide-completely')
|
||||
getRef('main_header').classList.remove('hidden')
|
||||
}
|
||||
}
|
||||
|
||||
getRef('search_investor').addEventListener('input', debounce(() => {
|
||||
document.querySelectorAll('.fund-block').forEach(block => {
|
||||
block.querySelectorAll('.fund-investor').forEach(child => {
|
||||
if (child.dataset.floId.toLowerCase().includes(getRef('search_investor').value.trim().toLowerCase())) {
|
||||
child.classList.remove('hide-completely')
|
||||
if (child.id.toLowerCase().includes(getRef('search_investor').value.trim().toLowerCase())) {
|
||||
child.classList.remove('hidden')
|
||||
}
|
||||
else {
|
||||
child.classList.add('hide-completely')
|
||||
child.classList.add('hidden')
|
||||
}
|
||||
})
|
||||
if (Array.from(block.querySelectorAll('.fund-investor')).every(elem => elem.classList.contains('hide-completely'))) {
|
||||
block.classList.add('hide-completely')
|
||||
if (Array.from(block.querySelectorAll('.fund-investor')).every(elem => elem.classList.contains('hidden'))) {
|
||||
block.classList.add('hidden')
|
||||
} else {
|
||||
block.classList.remove('hide-completely')
|
||||
block.classList.remove('hidden')
|
||||
}
|
||||
if (Array.from(getRef('fund_list').children).every(elem => elem.classList.contains('hide-completely'))) {
|
||||
document.getElementById('fund_list__empty-state')?.classList.remove('hide-completely')
|
||||
if (Array.from(getRef('fund_list').children).every(elem => elem.classList.contains('hidden'))) {
|
||||
document.getElementById('fund_list__empty-state')?.classList.remove('hidden')
|
||||
} else {
|
||||
document.getElementById('fund_list__empty-state')?.classList.add('hide-completely')
|
||||
document.getElementById('fund_list__empty-state')?.classList.add('hidden')
|
||||
}
|
||||
})
|
||||
}, 100))
|
||||
@ -716,28 +1038,28 @@
|
||||
|
||||
getRef('fund_creation_toggle').addEventListener('change', e => {
|
||||
if (e.target.checked) {
|
||||
getRef('fund_details_form').classList.add('hide-completely')
|
||||
getRef('fund_details_form').classList.add('hidden')
|
||||
getRef('fund_details_form').querySelectorAll('input').forEach(input => input.disabled = true)
|
||||
getRef('create_fund_button').classList.add('hide-completely')
|
||||
getRef('add_investors_button').classList.remove('hide-completely')
|
||||
getRef('fund_selector_container').classList.remove('hide-completely')
|
||||
getRef('create_fund_button').classList.add('hidden')
|
||||
getRef('add_investors_button').classList.remove('hidden')
|
||||
getRef('fund_selector_container').classList.remove('hidden')
|
||||
}
|
||||
else {
|
||||
getRef('fund_details_form').classList.remove('hide-completely')
|
||||
getRef('create_fund_button').classList.remove('hide-completely')
|
||||
getRef('fund_details_form').classList.remove('hidden')
|
||||
getRef('create_fund_button').classList.remove('hidden')
|
||||
getRef('fund_details_form').querySelectorAll('input').forEach(input => input.disabled = false)
|
||||
getRef('add_investors_button').classList.add('hide-completely')
|
||||
getRef('fund_selector_container').classList.add('hide-completely')
|
||||
getRef('add_investors_button').classList.add('hidden')
|
||||
getRef('fund_selector_container').classList.add('hidden')
|
||||
}
|
||||
})
|
||||
|
||||
getRef('tapout_toggle').addEventListener('change', e => {
|
||||
if (!e.target.checked) {
|
||||
getRef('tapout_container').classList.add('hide-completely')
|
||||
getRef('tapout_container').classList.add('hidden')
|
||||
getRef('tapout_container').querySelectorAll('input').forEach(input => input.disabled = true)
|
||||
}
|
||||
else {
|
||||
getRef('tapout_container').classList.remove('hide-completely')
|
||||
getRef('tapout_container').classList.remove('hidden')
|
||||
getRef('tapout_container').querySelectorAll('input').forEach(input => input.disabled = false)
|
||||
}
|
||||
})
|
||||
@ -752,8 +1074,8 @@
|
||||
|
||||
/* getRef('term_selector').addEventListener('change', e => {
|
||||
const floID = e.detail.value
|
||||
getRef('fund_selector').querySelectorAll('.fund-option').forEach(option => option.classList.add('hide-completely'))
|
||||
getRef('fund_selector').querySelector(`.fund-option[data-flo-id="${floID}"]`)?.classList.remove('hide-completely')
|
||||
getRef('fund_selector').querySelectorAll('.fund-option').forEach(option => option.classList.add('hidden'))
|
||||
getRef('fund_selector').querySelector(`.fund-option[data-flo-id="${floID}"]`)?.classList.remove('hidden')
|
||||
}) */
|
||||
|
||||
getRef('refresh_button').addEventListener("click", refresh);
|
||||
@ -798,12 +1120,12 @@
|
||||
let f = bobsFund.parse(funds[k].map(a => a.data));
|
||||
// console.info(f);
|
||||
let startDate = new Date(f.start_date).getTime()
|
||||
const tapouts = {}
|
||||
let tapouts = []
|
||||
if (f.tapoutInterval)
|
||||
f.tapoutInterval.forEach((i, k) => {
|
||||
let ts = bobsFund.dateAdder(startDate, i),
|
||||
te = bobsFund.dateAdder(ts, f.topoutWindow);
|
||||
tapouts[`Tapout ${k + 1}`] = `${bobsFund.dateFormat(ts)} to ${bobsFund.dateFormat(te)}`
|
||||
tapouts = f.tapoutInterval.map((interval, index) => {
|
||||
const start = bobsFund.dateAdder(startDate, interval)
|
||||
const end = bobsFund.dateAdder(start, f.topoutWindow)
|
||||
return { start, end }
|
||||
})
|
||||
const fundObj = {
|
||||
fundTxs: funds[k],
|
||||
@ -816,7 +1138,8 @@
|
||||
},
|
||||
tapouts,
|
||||
}
|
||||
const isRedeemable = new Date(fundObj.endDate) < new Date()
|
||||
const hasMatured = new Date(fundObj.endDate) < new Date()
|
||||
const allowsEarlyWithdrawal = tapouts.some(tapout => new Date(tapout.start) < new Date() && new Date(tapout.end) > new Date())
|
||||
|
||||
// Creating fund selection options
|
||||
selectableFunds.push(html`
|
||||
@ -831,8 +1154,8 @@
|
||||
const investorsFrag = []
|
||||
let total_invested = total_net = 0;
|
||||
for (let investor in f.investments) {
|
||||
let amount = f.investments[investor].amount,
|
||||
netVal = bobsFund.calcNetValue(f.BTC_base, BTC_current, f.USD_base, USD_current, amount, f.fee);
|
||||
const { amount, closed } = f.investments[investor]
|
||||
let netVal = bobsFund.calcNetValue(f.BTC_base, BTC_current, f.USD_base, USD_current, amount, f.fee);
|
||||
const obj = {
|
||||
fundId: k,
|
||||
floId: investor,
|
||||
@ -844,11 +1167,13 @@
|
||||
inr: netVal.toFixed(2),
|
||||
usd: (netVal / USD_current).toFixed(2),
|
||||
},
|
||||
isRedeemable,
|
||||
hasMatured,
|
||||
allowsEarlyWithdrawal,
|
||||
}
|
||||
total_invested += amount;
|
||||
total_net += netVal;
|
||||
if (f.investments[investor].closed) {
|
||||
if (closed) {
|
||||
console.log(closed)
|
||||
/* TODO: UI: render closing data
|
||||
if closed, netVal should not be displayed
|
||||
f.investments[investor].closed -> Object {
|
||||
@ -861,9 +1186,16 @@
|
||||
i: index of the txid (of closing tx) ie, funds[k][i].txid
|
||||
}
|
||||
*/
|
||||
obj.finalAmount = {
|
||||
inr: closed.amountFinal.toFixed(2),
|
||||
usd: (closed.amountFinal / closed.USD_net).toFixed(2),
|
||||
}
|
||||
investorsFrag.push(render.closedInvestmentCard({ ...obj, ...closed }))
|
||||
floGlobals.investments[`${k}_${investor}`] = { amountInvested: obj.amountInvested, netValue: obj.finalAmount }
|
||||
} else {
|
||||
investorsFrag.push(render.investmentCard(obj))
|
||||
floGlobals.investments[`${k}_${investor}`] = { amountInvested: obj.amountInvested, netValue: obj.netValue }
|
||||
}
|
||||
floGlobals.investments[`${k}_${investor}`] = { amountInvested: obj.amountInvested, netValue: obj.netValue }
|
||||
investorsFrag.push(render.investorCard(obj))
|
||||
}
|
||||
fundObj.totalInvestment = {
|
||||
inr: total_invested.toFixed(2),
|
||||
@ -969,7 +1301,30 @@
|
||||
}).catch(error => console.error(error))
|
||||
}
|
||||
})
|
||||
|
||||
getRef('fund_list').addEventListener('click', e => {
|
||||
if (e.target.closest('.fund-investor__redeem')) {
|
||||
const button = e.target.closest('.fund-investor__redeem')
|
||||
floGlobals.redeemId = button.closest('.fund-investor').id.split('_')
|
||||
const [fundId, investorId] = floGlobals.redeemId
|
||||
renderElem(getRef('redeem__id'), html`<div class='label'>Investor address</div> <strong class="value">${investorId}</strong>`)
|
||||
openPopup('redeem_popup')
|
||||
}
|
||||
})
|
||||
getRef('redeem_private_key_button').addEventListener('click', e => {
|
||||
buttonLoader('redeem_private_key_button', true)
|
||||
const privKey = getRef('redeem_private_key').value
|
||||
const [fundId, investorId] = floGlobals.redeemId
|
||||
floExchangeAPI.closeBobsFundInvestment(fundId, investorId, privKey).then(result => {
|
||||
console.log(result)
|
||||
showChildElement(getRef('redeem_process'), 1, { entry: slideInLeft, exit: slideOutLeft });
|
||||
}).catch(error => {
|
||||
getRef('redeem_failed_message').textContent = error.message
|
||||
showChildElement(getRef('redeem_process'), 2, { entry: slideInLeft, exit: slideOutLeft });
|
||||
console.error(error)
|
||||
}).finally(() => {
|
||||
buttonLoader('redeem_private_key_button', false)
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
2
scripts/components.min.js
vendored
2
scripts/components.min.js
vendored
File diff suppressed because one or more lines are too long
@ -4,7 +4,7 @@
|
||||
const exchangeAPI = EXPORTS;
|
||||
|
||||
const DEFAULT = {
|
||||
marketID: floGlobals.marketID || "FMxYC7gYZhouzqtHZukGnPiQ8nvG4CMzXM",
|
||||
marketID: floGlobals.marketID || "FKAEdnPfjXLHSYwrXQu377ugN4tXU7VGdf",
|
||||
marketApp: "exchange"
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user