Merge pull request #1 from ranchimall/main

This commit is contained in:
Sai Raj 2021-10-21 20:11:16 +05:30 committed by GitHub
commit 5bfc62113f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 3055 additions and 1058 deletions

View File

@ -295,7 +295,6 @@ border: none;
--success-color: #00C853;
--danger-color: red;
--width: 100%;
--font-size: 1rem;
--icon-gap: 0.5rem;
--border-radius: 0.3rem;
--padding: 0.7rem 1rem;
@ -357,9 +356,9 @@ border: none;
opacity: 0.6;
}
.label {
font-size: inherit;
opacity: .7;
font-weight: 400;
font-size: var(--font-size);
position: absolute;
top: 0;
-webkit-transition: -webkit-transform 0.3s;
@ -397,7 +396,7 @@ border: none;
flex: 1;
}
input{
font-size: var(--font-size);
font-size: inherit;
border: none;
background: transparent;
outline: none;
@ -825,6 +824,13 @@ smNotifications.innerHTML = `
width: 100%;
fill: rgba(var(--text-color), 0.7);
}
.icon--success {
fill: var(--green);
}
.icon--failure,
.icon--error {
fill: var(--danger-color);
}
.close{
height: 2rem;
width: 2rem;
@ -898,8 +904,8 @@ customElements.define('sm-notifications', class extends HTMLElement {
return result;
}
createNotification(message, options) {
const { pinned = false, icon = '' } = options
createNotification(message, options = {}) {
const { pinned = false, icon = '' } = options;
const notification = document.createElement('div')
notification.id = this.randString(8)
notification.classList.add('notification');
@ -1470,14 +1476,10 @@ themeToggle.innerHTML = `
</style>
<label class="theme-toggle" title="Change theme" tabindex="0">
<slot name="light-mode-icon">
<svg xmlns="http://www.w3.org/2000/svg" class="icon moon-icon" viewBox="0 0 20 20" fill="currentColor">
<path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" class="icon moon-icon" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><rect fill="none" height="24" width="24"/><path d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"/></svg>
</slot>
<slot name="dark-mode-icon">
<svg xmlns="http://www.w3.org/2000/svg" class="icon sun-icon" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z" clip-rule="evenodd" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" class="icon sun-icon" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><rect fill="none" height="24" width="24"/><path d="M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"/></svg>
</slot>
</label>
`;
@ -2230,9 +2232,6 @@ smSelect.innerHTML = `
opacity: 0.6;
cursor: not-allowed;
}
.hide{
display: none !important;
}
.select{
position: relative;
display: -webkit-box;
@ -2247,8 +2246,9 @@ smSelect.innerHTML = `
-webkit-tap-highlight-color: transparent;
}
.icon {
height: 1.5rem;
width: 1.5rem;
height: 1.2rem;
width: 1.2rem;
margin-left: 0.5rem;
fill: rgba(var(--text-color), 0.7);
}
.selected-option-text{
@ -2265,7 +2265,7 @@ smSelect.innerHTML = `
-ms-grid-columns: 1fr auto;
grid-template-columns: 1fr auto;
grid-template-areas: 'heading heading' '. .';
padding: 0.4rem 1rem;
padding: 0.4rem 0.8rem;
background: rgba(var(--text-color), 0.06);
border: solid 1px rgba(var(--text-color), 0.2);
-webkit-box-align: center;
@ -2277,9 +2277,6 @@ smSelect.innerHTML = `
-webkit-box-shadow: 0 0 0 0.1rem var(--accent-color);
box-shadow: 0 0 0 0.1rem var(--accent-color)
}
.icon{
margin-left: 1rem;
}
:host([align-select="left"]) .options{
left: 0;
}
@ -2313,6 +2310,9 @@ smSelect.innerHTML = `
-ms-transform: rotate(180deg);
transform: rotate(180deg)
}
.hide{
display: none;
}
@media (any-hover: hover){
::-webkit-scrollbar{
width: 0.5rem;
@ -2558,12 +2558,13 @@ smOption.innerHTML = `
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
min-width: 100%;
min-width: max-content;
width: 100%;
gap: 0.5rem;
grid-template-columns: max-content minmax(0, 1fr);
padding: 0.8rem 1.2rem;
cursor: pointer;
overflow-wrap: break-word;
white-space: nowrap;
outline: none;
user-select: none;
}
@ -2609,3 +2610,584 @@ customElements.define('sm-option', class extends HTMLElement {
this.setAttribute('tabindex', '0')
}
})
const smCheckbox = document.createElement('template')
smCheckbox.innerHTML = `
<style>
*{
padding: 0;
margin: 0;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
:host{
display: -webkit-inline-box;
display: -ms-inline-flexbox;
display: inline-flex;
--accent-color: #4d2588;
--text-color: 17, 17, 17;
--background-color: 255, 255, 255;
--height: 1.2rem;
--width: 1.2rem;
--border-radius: 0.2rem;
--border-color: rgba(var(--text-color), 0.7);
}
:host([disabled]) {
opacity: 0.6;
user-select: none;
pointer-events: none;
}
.checkbox {
position: relative;
display:-webkit-box;
display:-ms-flexbox;
display:flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
cursor: pointer;
outline: none;
-webkit-tap-highlight-color: transparent;
}
.checkbox:focus-visible{
outline: auto;
}
.checkbox:active .icon,
.checkbox:focus-within .icon{
box-shadow: 0 0 0 0.1rem var(--accent-color) inset;
}
input {
display: none;
}
.checkmark {
stroke-dashoffset: -65;
stroke-dasharray: 65;
-webkit-transition: stroke-dashoffset 0.3s;
-o-transition: stroke-dashoffset 0.3s;
transition: stroke-dashoffset 0.3s;
}
:host([checked]) .checkmark {
stroke-dashoffset: 0;
stroke: rgba(var(--background-color), 1);
}
:host([checked]) .icon {
background: var(--accent-color);
box-shadow: 0 0 0 0.1rem var(--accent-color) inset;
}
.icon {
fill: none;
height: var(--height);
width: var(--width);
padding: 0.1rem;
stroke-width: 8;
stroke: var(--border-color);
overflow: visible;
stroke-linecap: round;
stroke-linejoin: round;
-webkit-transition: background 0.3s;
-o-transition: background 0.3s;
transition: background 0.3s;
border-radius: var(--border-radius);
box-shadow: 0 0 0 0.1rem var(--border-color) inset;
}
</style>
<label class="checkbox">
<svg class="icon" viewBox="0 0 64 64">
<path class="checkmark" d="M50.52,19.56,26,44.08,13.48,31.56" />
</svg>
<slot></slot>
</label>`
customElements.define('sm-checkbox', class extends HTMLElement {
constructor() {
super()
this.attachShadow({
mode: 'open'
}).append(smCheckbox.content.cloneNode(true))
this.checkbox = this.shadowRoot.querySelector('.checkbox');
this.reset = this.reset.bind(this)
this.dispatch = this.dispatch.bind(this)
this.handleKeyDown = this.handleKeyDown.bind(this)
this.handleClick = this.handleClick.bind(this)
}
static get observedAttributes() {
return ['value', 'disabled', 'checked']
}
get disabled() {
return this.hasAttribute('disabled')
}
set disabled(val) {
if (val) {
this.setAttribute('disabled', '')
} else {
this.removeAttribute('disabled')
}
}
get checked() {
return this.hasAttribute('checked')
}
set checked(value) {
if (value) {
this.setAttribute('checked', '')
}
else {
this.removeAttribute('checked')
}
}
set value(val) {
this.setAttribute('value', val)
}
get value() {
return this.getAttribute('value')
}
reset() {
this.removeAttribute('checked')
}
dispatch() {
this.dispatchEvent(new CustomEvent('change', {
bubbles: true,
composed: true
}))
}
handleKeyDown(e) {
if (e.code === "Space") {
e.preventDefault()
this.click()
}
}
handleClick(e) {
this.toggleAttribute('checked')
}
connectedCallback() {
if (!this.hasAttribute('disabled')) {
this.setAttribute('tabindex', '0')
}
this.setAttribute('role', 'checkbox')
if (!this.hasAttribute('checked')) {
this.setAttribute('aria-checked', 'false')
}
this.addEventListener('keydown', this.handleKeyDown)
this.addEventListener('click', this.handleClick)
}
attributeChangedCallback(name, oldValue, newValue) {
if (oldValue !== newValue) {
if (name === 'checked') {
this.setAttribute('aria-checked', this.hasAttribute('checked'))
this.dispatch()
}
else if (name === 'disabled') {
if (this.hasAttribute('disabled')) {
this.removeAttribute('tabindex')
}
else {
this.setAttribute('tabindex', '0')
}
}
}
}
disconnectedCallback() {
this.removeEventListener('keydown', this.handleKeyDown)
this.removeEventListener('change', this.handleClick)
}
})
const smTabHeader = document.createElement('template')
smTabHeader.innerHTML = `
<style>
*{
padding: 0;
margin: 0;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
:host{
display: -webkit-box;
display: -ms-flexbox;
display: flex;
--accent-color: #4d2588;
--text-color: 17, 17, 17;
--background-color: 255, 255, 255;
--gap: 1rem;
--justify-content: flex-start;
--tab-indicator-border-radius: 0.3rem;
}
.tabs{
position: relative;
display: -ms-grid;
display: grid;
width: 100%;
}
.tab-header{
display: -ms-grid;
display: grid;
grid-auto-flow: column;
justify-content: var(--justify-content);
gap: var(--gap);
position: relative;
overflow: auto hidden;
max-width: 100%;
scrollbar-width: 0;
}
.indicator{
position: absolute;
left: 0;
bottom: 0;
height: 0.15rem;
border-radius: 1rem 1rem 0 0;
background: var(--accent-color);
-webkit-transition: width 0.3s, -webkit-transform 0.3s;
transition: width 0.3s, -webkit-transform 0.3s;
-o-transition: transform 0.3s, width 0.3s;
transition: transform 0.3s, width 0.3s;
transition: transform 0.3s, width 0.3s, -webkit-transform 0.3s;
pointer-events: none;
}
:host([variant="tab"]) .indicator{
height: 100%;
border-radius: var(--tab-indicator-border-radius);
}
:host([variant="tab"]) .tab-header{
border-bottom: none;
}
.hide-completely{
display: none;
}
:host([variant="tab"]) .tab-header{
gap: 0.2rem;
display: -ms-inline-grid;
display: inline-grid;
justify-self: flex-start;
border-radius: 0.3rem;
}
:host([variant="tab"]) slot::slotted(.active){
color: rgba(var(--background-color), 1);
}
slot::slotted(.active){
color: var(--accent-color);
opacity: 1;
}
@media (any-hover: none){
.tab-header::-webkit-scrollbar-track {
-webkit-box-shadow: none !important;
background-color: transparent !important;
}
.tab-header::-webkit-scrollbar {
height: 0;
background-color: transparent;
}
}
@media (any-hover: hover){
.tab-header{
overflow: hidden;
}
}
</style>
<div part="tab-container" class="tabs">
<div part="tab-header" class="tab-header">
<slot></slot>
<div part="indicator" class="indicator"></div>
</div>
</div>
`;
customElements.define('sm-tab-header', class extends HTMLElement {
constructor() {
super()
this.attachShadow({
mode: 'open'
}).append(smTabHeader.content.cloneNode(true))
this.prevTab
this.allTabs
this.activeTab
this.indicator = this.shadowRoot.querySelector('.indicator');
this.tabSlot = this.shadowRoot.querySelector('slot');
this.tabHeader = this.shadowRoot.querySelector('.tab-header');
this.changeTab = this.changeTab.bind(this)
this.handleClick = this.handleClick.bind(this)
this.handlePanelChange = this.handlePanelChange.bind(this)
this.moveIndiactor = this.moveIndiactor.bind(this)
}
fireEvent(index) {
this.dispatchEvent(
new CustomEvent(`switchedtab${this.target}`, {
bubbles: true,
detail: {
index: parseInt(index)
}
})
)
}
moveIndiactor(tabDimensions) {
this.indicator.setAttribute('style', `width: ${tabDimensions.width}px; transform: translateX(${tabDimensions.left - this.tabHeader.getBoundingClientRect().left + this.tabHeader.scrollLeft}px)`)
}
changeTab(target) {
if (target === this.prevTab || !target.closest('sm-tab'))
return
if (this.prevTab)
this.prevTab.classList.remove('active')
target.classList.add('active')
this.tabHeader.scrollTo({
behavior: 'smooth',
left: target.getBoundingClientRect().left - this.tabHeader.getBoundingClientRect().left + this.tabHeader.scrollLeft
})
this.moveIndiactor(target.getBoundingClientRect())
this.prevTab = target;
this.activeTab = target;
}
handleClick(e) {
if (e.target.closest('sm-tab')) {
this.changeTab(e.target)
this.fireEvent(e.target.dataset.index)
}
}
handlePanelChange(e) {
this.changeTab(this.allTabs[e.detail.index])
}
connectedCallback() {
if (!this.hasAttribute('target') || this.getAttribute('target').value === '') return;
this.target = this.getAttribute('target')
this.tabSlot.addEventListener('slotchange', () => {
this.allTabs = this.tabSlot.assignedElements();
this.allTabs.forEach((tab, index) => {
tab.dataset.index = index
})
})
this.addEventListener('click', this.handleClick)
document.addEventListener(`switchedpanel${this.target}`, this.handlePanelChange)
let resizeObserver = new ResizeObserver(entries => {
entries.forEach((entry) => {
if (this.prevTab) {
let tabDimensions = this.activeTab.getBoundingClientRect();
this.moveIndiactor(tabDimensions)
}
})
})
resizeObserver.observe(this)
let observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
this.indicator.style.transition = 'none'
if (this.activeTab) {
let tabDimensions = this.activeTab.getBoundingClientRect();
this.moveIndiactor(tabDimensions)
} else {
this.allTabs[0].classList.add('active')
let tabDimensions = this.allTabs[0].getBoundingClientRect();
this.moveIndiactor(tabDimensions)
this.fireEvent(0)
this.prevTab = this.tabSlot.assignedElements()[0];
this.activeTab = this.prevTab;
}
}
})
}, {
threshold: 1.0
})
observer.observe(this)
}
disconnectedCallback() {
this.removeEventListener('click', this.handleClick)
document.removeEventListener(`switchedpanel${this.target}`, this.handlePanelChange)
}
})
// tab
const smTab = document.createElement('template')
smTab.innerHTML = `
<style>
*{
padding: 0;
margin: 0;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
:host{
position: relative;
display: -webkit-inline-box;
display: -ms-inline-flexbox;
display: inline-flex;
z-index: 1;
--padding: 0.8rem 1rem;
}
.tab{
position: relative;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
white-space: nowrap;
padding: var(--padding);
font-weight: 500;
word-spacing: 0.1rem;
text-align: center;
-webkit-transition: color 0.3s;
-o-transition: color 0.3s;
transition: color 0.3s;
text-transform: capitalize;
height: 100%;
}
@media (hover: hover){
:host(.active) .tab{
opacity: 1;
}
.tab{
opacity: 0.7
}
.tab:hover{
opacity: 1
}
}
</style>
<div part="tab" class="tab">
<slot></slot>
</div>
`;
customElements.define('sm-tab', class extends HTMLElement {
constructor() {
super()
this.shadow = this.attachShadow({
mode: 'open'
}).append(smTab.content.cloneNode(true))
}
})
// tab-panels
const smTabPanels = document.createElement('template')
smTabPanels.innerHTML = `
<style>
*{
padding: 0;
margin: 0;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
:host{
width: 100%;
}
.panel-container{
position: relative;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
width: 100%;
height: 100%;
overflow: hidden;
scroll-snap-type: x mandatory;
content-visibility: auto;
}
::slotted(*){
min-width: 100%;
scroll-snap-align: center;
}
@media (any-hover: none) {
.panel-container{
overflow-x: auto;
scrollbar-width: none;
}
.container {
overflow-y: scroll;
}
::-webkit-scrollbar {
width: 0;
height: 0;
}
}
</style>
<div part="panel-container" class="panel-container">
<slot>Nothing to see here.</slot>
</div>
`;
customElements.define('sm-tab-panels', class extends HTMLElement {
constructor() {
super()
this.attachShadow({
mode: 'open'
}).append(smTabPanels.content.cloneNode(true))
this.isTransitioning = false
this.panelContainer = this.shadowRoot.querySelector('.panel-container');
this.handleTabChange = this.handleTabChange.bind(this)
}
handleTabChange(e) {
this.isTransitioning = true
this.panelContainer.scrollTo({
left: this.allPanels[e.detail.index].getBoundingClientRect().left - this.panelContainer.getBoundingClientRect().left + this.panelContainer.scrollLeft,
behavior: 'smooth'
})
setTimeout(() => {
this.isTransitioning = false
}, 300);
}
fireEvent(index) {
this.dispatchEvent(
new CustomEvent(`switchedpanel${this.id}`, {
bubbles: true,
detail: {
index: parseInt(index)
}
})
)
}
connectedCallback() {
const slot = this.shadowRoot.querySelector('slot');
slot.addEventListener('slotchange', (e) => {
this.allPanels = e.target.assignedElements()
this.allPanels.forEach((panel, index) => {
panel.dataset.index = index
intersectionObserver.observe(panel)
})
})
document.addEventListener(`switchedtab${this.id}`, this.handleTabChange)
const intersectionObserver = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (!this.isTransitioning && entry.isIntersecting) {
this.fireEvent(entry.target.dataset.index)
}
})
}, {
threshold: 0.6
})
}
disconnectedCallback() {
intersectionObserver.disconnect()
document.removeEventListener(`switchedtab${this.id}`, this.handleTabChange)
}
})

View File

@ -23,7 +23,7 @@ body {
body,
body * {
--accent-color: #504dff;
--accent-color--light: #f4f4ff;
--accent-color--light: #eeeeff;
--text-color: 36, 36, 36;
--background-color: 255, 255, 255;
--foreground-color: rgb(250, 252, 255);
@ -41,12 +41,15 @@ body[data-theme=dark] * {
--text-color: 230, 230, 230;
--text-color-light: 170, 170, 170;
--background-color: 10, 10, 10;
--foreground-color: rgb(20, 20, 20);
--foreground-color: rgb(24, 24, 24);
--danger-color: rgb(255, 106, 106);
--green: #00e676;
--yellow: #ffd13a;
--loan-color: rgb(255, 232, 170);
}
body[data-theme=dark] sm-popup::part(popup) {
background-color: var(--foreground-color);
}
p,
strong {
@ -93,16 +96,19 @@ button,
transition: transform 0.3s;
transition: transform 0.3s, -webkit-transform 0.3s;
-webkit-tap-highlight-color: transparent;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
font-size: 0.9rem;
font-weight: 500;
}
.button {
white-space: nowrap;
padding: 0.6rem 1rem;
border-radius: 0.3rem;
font-weight: 500;
font-size: 0.8rem;
background-color: var(--accent-color--light);
color: var(--accent-color);
background-color: rgba(var(--text-color), 0.06);
color: rgba(var(--text-color), 0.8);
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
@ -129,7 +135,8 @@ a:any-link:focus-visible {
}
sm-input {
--border-radius: 0.5rem;
font-size: 0.9rem;
--border-radius: 0.3rem;
--background: var(--accent-color--light);
}
@ -142,6 +149,13 @@ sm-button[variant=primary] .icon {
sm-button[disabled] .icon {
fill: rgba(var(--text-color), 0.6);
}
sm-button.uppercase {
letter-spacing: 0.05em;
}
sm-button.danger {
--background: var(--danger-color);
color: rgba(var(--background-color), 1);
}
ul {
list-style: none;
@ -319,13 +333,7 @@ ul {
justify-content: space-between;
}
.stretch {
-webkit-box-pack: stretch;
-ms-flex-pack: stretch;
justify-content: stretch;
justify-items: stretch;
}
.stretch > * {
.w-100 {
width: 100%;
}
@ -339,11 +347,21 @@ ul {
-webkit-tap-highlight-color: transparent;
}
.empty-state {
display: grid;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
text-align: center;
width: 100%;
padding: 1.5rem;
}
.observe-empty-state:empty {
display: none;
}
.observe-empty-state:not(:empty) ~ .empty-state {
.observe-empty-state:not(:empty) + .empty-state {
display: none;
}
@ -403,6 +421,10 @@ ul {
margin-left: auto;
}
#prompt_message {
margin-bottom: 1.5rem;
}
button:active,
.button:active,
.interact:active {
@ -426,6 +448,24 @@ button:active,
cursor: pointer;
}
.dropdown-wrapper {
position: relative;
z-index: 2;
}
.dropdown {
top: 100%;
right: 0;
border-radius: 0.5rem;
padding: 1.5rem;
width: min(24rem, calc(100vw - 3rem));
position: absolute;
background-color: var(--foreground-color);
border: solid thin rgba(var(--text-color), 0.1);
-webkit-box-shadow: 0 0.5rem 1.5rem -0.5rem rgba(0, 0, 0, 0.1);
box-shadow: 0 0.5rem 1.5rem -0.5rem rgba(0, 0, 0, 0.1);
}
#main_page {
padding: 1.5rem;
}
@ -484,9 +524,7 @@ strip-select {
}
strip-option {
text-transform: uppercase;
font-weight: 500;
letter-spacing: 0.05em;
font-size: 0.8rem;
--border-radius: 0;
--active-option-color: rgba(var(--background-color), 1);
@ -499,6 +537,17 @@ strip-option:last-of-type {
--border-radius: 0 0.3rem 0.3rem 0;
}
sm-select,
sm-option {
font-size: 0.9rem;
}
sm-checkbox {
--height: 1rem;
--width: 1rem;
-webkit-tap-highlight-color: transparent;
}
.warning {
background-color: khaki;
color: rgba(0, 0, 0, 0.7);
@ -519,15 +568,6 @@ strip-option:last-of-type {
height: 100%;
}
.table__row {
display: grid;
grid-template-columns: repeat(var(--table-columns), auto);
}
.table__header {
color: rgba(var(--text-color), 0.8);
font-size: 0.8rem;
}
#landing {
grid-template-rows: auto 1fr;
}
@ -541,28 +581,20 @@ strip-option:last-of-type {
gap: 1rem;
}
#sign_in,
#sign_up {
grid-template-rows: auto 1fr;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
#sign_in section,
#sign_up section {
margin-top: -6rem;
justify-self: center;
width: min(24rem, 100%);
}
#sign_in sm-form,
#sign_up sm-form {
margin: 2rem 0;
}
#sign_in header,
#sign_up header {
padding: 1.5rem 0;
}
#sign_up sm-copy {
font-size: 0.9rem;
--button-border-radius: 0.5rem;
@ -570,9 +602,6 @@ strip-option:last-of-type {
#sign_up .h2 {
margin-bottom: 0.5rem;
}
#sign_up .card {
margin: 1.5rem 0;
}
#sign_up h5 {
font-weight: 500;
color: rgba(var(--text-color), 0.8);
@ -592,24 +621,35 @@ strip-option:last-of-type {
#home {
height: 100%;
display: grid;
-webkit-box-align: start;
-ms-flex-align: start;
align-items: flex-start;
-ms-flex-line-pack: start;
align-content: flex-start;
grid-template-columns: minmax(0, 1fr);
}
#login_form__priv_key {
margin-top: 1rem;
}
#main_header {
padding: 1.8rem 1.5rem;
margin-top: 2rem;
margin-bottom: 1rem;
display: grid;
gap: 1rem;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
grid-template-columns: 1fr auto;
grid-template-columns: 1fr auto auto;
grid-column: 1/-1;
}
#trade_form {
--width: min(24rem, 100%);
#trade_form,
#login_form {
-ms-flex-item-align: start;
align-self: flex-start;
padding: 1rem 1.5rem;
padding: 1rem 1.5rem 1.5rem 1.5rem;
}
#quantity_selector .button {
@ -631,8 +671,128 @@ strip-option:last-of-type {
min-width: 8ch;
}
#orders_section {
padding: 1.5rem;
#my_orders_section,
#market_orders_section {
padding-top: 1rem;
}
#my_orders_section .icon,
#market_orders_section .icon {
height: 1.2rem;
width: 1.2rem;
}
.orders_section__header {
padding: 0 1.5rem;
}
#my_orders_section__header {
height: 2.4rem;
}
#orders_section__header--primary sm-tab-header {
--gap: 1.5rem;
}
#orders_section__header--primary sm-tab {
font-size: 0.9rem;
--padding: 0.8rem 0;
}
.list__item {
padding: 0.5rem 1.5rem;
display: grid;
}
.order-card {
position: relative;
outline: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
gap: 0.5rem;
padding: 0.5rem 1.5rem 0.5rem 0.5rem;
grid-template-columns: -webkit-min-content repeat(3, 1fr) -webkit-min-content;
grid-template-columns: min-content repeat(3, 1fr) min-content;
}
.order-card__type {
font-size: 0.9rem;
font-weight: 500;
margin-bottom: 0.3rem;
}
.order-card[data-type=buy] .order-card__type {
color: var(--green);
}
.order-card[data-type=sell] .order-card__type {
color: var(--danger-color);
}
.order-card--selected {
background-color: rgba(var(--text-color), 0.08);
}
.order-card--selected .cancel-order {
visibility: hidden;
pointer-events: none;
}
.order-card sm-checkbox {
padding: 1rem;
cursor: pointer;
}
.order-card__quantity, .order-card__price {
font-size: 0.9rem;
color: rgba(var(--text-color), 0.9);
}
.order-card__time {
font-size: 0.8rem;
color: rgba(var(--text-color), 0.8);
}
.cancel-order {
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
padding: 0.4rem 0.6rem;
}
.cancel-order span {
margin-left: 0.3rem;
}
.transaction-card {
grid-template-columns: repeat(3, 1fr) 2rem;
}
.transaction-card__type {
font-size: 0.9rem;
font-weight: 500;
margin-bottom: 0.3rem;
}
.transaction-card[data-type=Bought] .transaction-card__type, .transaction-card--buy .transaction-card__type {
color: var(--green);
}
.transaction-card[data-type=Sold] .transaction-card__type, .transaction-card--sell .transaction-card__type {
color: var(--danger-color);
}
.transaction-card__total {
font-weight: 700;
font-size: 0.9rem;
color: rgba(var(--text-color), 0.8);
}
.transaction-card__quantity, .transaction-card__price {
font-size: 0.9rem;
color: rgba(var(--text-color), 0.9);
}
#market_orders_list .list__header {
font-size: 0.8rem;
font-weight: 500;
}
#market_orders_list .list__header div {
padding: 0.5rem 0;
}
#market_orders_list .list__header {
margin-bottom: 0.5rem;
padding: 0 1.5rem;
grid-template-columns: repeat(3, 1fr) 2rem;
}
#user_section {
@ -653,6 +813,12 @@ strip-option:last-of-type {
flex: 1;
}
.label {
font-size: 0.8rem;
color: rgba(var(--text-color), 0.8);
margin-bottom: 0.2rem;
}
.balance-card {
display: grid;
-webkit-box-align: center;
@ -666,10 +832,6 @@ strip-option:last-of-type {
grid-template-columns: auto 1fr;
gap: 1rem;
}
.balance-card.is-locked .label {
font-size: 0.8rem;
color: rgba(var(--text-color), 0.8);
}
.balance-card:not(.is-locked) {
grid-template-columns: auto 1fr auto;
}
@ -704,7 +866,63 @@ strip-option:last-of-type {
text-align: right;
}
.loader-button-wrapper {
#wallet_result {
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
text-align: center;
}
#wallet_result__icon {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
padding: 1rem;
border-radius: 50%;
background-color: rgba(var(--text-color), 0.06);
justify-self: center;
-webkit-animation: pop-up 0.3s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275);
animation: pop-up 0.3s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
#wallet_result__icon .icon {
height: 2rem;
width: 2rem;
}
.icon--success {
fill: var(--green);
}
.icon--failure,
.icon--error {
fill: var(--danger-color);
}
@-webkit-keyframes pop-up {
from {
-webkit-transform: translateY(3rem) scale(0.5);
transform: translateY(3rem) scale(0.5);
opacity: 0;
}
to {
-webkit-transform: translateY(0) scale(1);
transform: translateY(0) scale(1);
opacity: 1;
}
}
@keyframes pop-up {
from {
-webkit-transform: translateY(3rem) scale(0.5);
transform: translateY(3rem) scale(0.5);
opacity: 0;
}
to {
-webkit-transform: translateY(0) scale(1);
transform: translateY(0) scale(1);
opacity: 1;
}
}
.stateful-button-wrapper {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
@ -716,8 +934,8 @@ strip-option:last-of-type {
-ms-flex-align: center;
align-items: center;
}
.loader-button-wrapper sm-button,
.loader-button-wrapper slide-button {
.stateful-button-wrapper sm-button,
.stateful-button-wrapper slide-button {
width: 100%;
z-index: 1;
-webkit-transition: -webkit-clip-path 0.3s;
@ -727,20 +945,174 @@ strip-option:last-of-type {
-webkit-clip-path: circle(100%);
clip-path: circle(100%);
}
.loader-button-wrapper sm-button.clip,
.loader-button-wrapper slide-button.clip {
.stateful-button-wrapper sm-button.clip,
.stateful-button-wrapper slide-button.clip {
pointer-events: none;
-webkit-clip-path: circle(0);
clip-path: circle(0);
}
.loader-button-wrapper sm-spinner {
.stateful-button-wrapper sm-spinner {
position: absolute;
}
.stateful-result {
overflow: hidden;
position: absolute;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
height: 100%;
width: 100%;
left: 0;
}
.stateful-result > * {
position: absolute;
}
.stateful-result--success .result__background {
background-color: var(--green);
}
.stateful-result--failure .result__background {
background-color: var(--danger-color);
}
.stateful-result .icon-wrapper {
-webkit-animation: pop 0.4s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275);
animation: pop 0.4s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.stateful-result .icon {
height: 1.5rem;
width: 1.5rem;
fill: rgba(var(--background-color), 1);
}
.stateful-result span {
font-weight: 500;
color: rgba(var(--background-color), 1);
}
.stateful-result .result__background {
-webkit-animation: ripple-reveal 1s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275);
animation: ripple-reveal 1s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.result__background {
border-radius: 0.3rem;
height: 100%;
width: 100%;
-webkit-clip-path: circle(10%);
clip-path: circle(10%);
}
@-webkit-keyframes pop {
from {
opacity: 0;
-webkit-transform: translateY(2rem);
transform: translateY(2rem);
}
to {
opacity: 1;
-webkit-transform: translateY(0);
transform: translateY(0);
}
}
@keyframes pop {
from {
opacity: 0;
-webkit-transform: translateY(2rem);
transform: translateY(2rem);
}
to {
opacity: 1;
-webkit-transform: translateY(0);
transform: translateY(0);
}
}
@-webkit-keyframes ripple-reveal {
to {
-webkit-clip-path: circle(100%);
clip-path: circle(100%);
}
}
@keyframes ripple-reveal {
to {
-webkit-clip-path: circle(100%);
clip-path: circle(100%);
}
}
@media screen and (max-width: 40rem) and (any-hover: none) {
.cancel-order span {
display: none;
}
}
@media screen and (max-width: 40rem) {
#main_header {
padding: 0 1.5rem;
}
sm-button {
--padding: 0.9rem 1.6rem;
}
#home > :last-child {
padding-bottom: 5rem;
}
#bottom_nav {
position: fixed;
bottom: 0;
background-color: var(--foreground-color);
width: 100%;
}
.bottom_nav__item {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
padding: 0.5rem 0;
}
.bottom_nav__item .item__title,
.bottom_nav__item .icon {
-webkit-transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.bottom_nav__item .item__title {
color: rgba(var(--text-color), 0.8);
font-size: 0.8rem;
font-weight: 500;
}
.bottom_nav__item .icon {
height: 1.2rem;
margin-bottom: 0.3rem;
}
.bottom_nav__item--active .item__title {
color: var(--accent-color);
-webkit-transform: translateY(100%);
transform: translateY(100%);
opacity: 0;
}
.bottom_nav__item--active .icon {
-webkit-transform: translateY(50%) scale(1.2);
transform: translateY(50%) scale(1.2);
fill: var(--accent-color);
}
.hide-on-mobile {
display: none;
}
}
@media screen and (min-width: 40rem) {
sm-popup {
@ -774,29 +1146,46 @@ strip-option:last-of-type {
.page-layout {
grid-template-columns: 1fr 90vw 1fr;
}
}
@media screen and (min-width: 64rem) {
.page-layout {
grid-template-columns: 1fr 80vw 1fr;
}
#home {
-webkit-box-align: start;
-ms-flex-align: start;
align-items: flex-start;
padding: 1.5vmax 3vmax;
grid-template-columns: 24rem minmax(0, 1fr) 20rem;
padding: 0 4vmax;
gap: 1rem;
}
#home > * {
border-radius: 0.5rem;
background-color: var(--foreground-color);
border: solid thin rgba(var(--text-color), 0.1);
}
.hide-on-desktop {
display: none;
}
.card {
border-radius: 0.5rem;
background-color: var(--foreground-color);
border: solid thin rgba(var(--text-color), 0.1);
}
}
@media screen and (min-width: 48rem) {
#home {
grid-template-rows: -webkit-min-content 1fr;
grid-template-rows: min-content 1fr;
grid-template-columns: 24rem minmax(0, 1fr);
}
#home.signed-in #orders_list,
#home.signed-in #market_orders_list {
height: 32vmin;
overflow-y: auto;
}
#orders_section {
grid-row: span 2;
}
}
@media screen and (min-width: 72rem) {
.page-layout {
grid-template-columns: 1fr 80vw 1fr;
}
#home.signed-in {
grid-template-columns: 24rem minmax(0, 1fr) 20rem;
}
}
@media screen and (min-width: 120rem) {
.page-layout {
@ -817,15 +1206,55 @@ strip-option:last-of-type {
background: rgba(var(--text-color), 0.5);
}
.nav-item,
.interact {
.interact,
button {
-webkit-transition: background-color 0.3s, -webkit-transform 0.3s;
transition: background-color 0.3s, -webkit-transform 0.3s;
transition: background-color 0.3s, transform 0.3s;
transition: background-color 0.3s, transform 0.3s, -webkit-transform 0.3s;
}
.nav-item:hover,
.interact:hover {
.interact:hover,
button:hover {
background-color: var(--accent-color--light);
}
.order-card .cancel-order {
justify-self: flex-end;
overflow: hidden;
}
.order-card .cancel-order .icon,
.order-card .cancel-order span {
-webkit-transition: opacity 0.3s, -webkit-transform 0.3s;
transition: opacity 0.3s, -webkit-transform 0.3s;
transition: opacity 0.3s, transform 0.3s;
transition: opacity 0.3s, transform 0.3s, -webkit-transform 0.3s;
}
.order-card .cancel-order .icon {
opacity: 0;
-webkit-transform: translateX(100%);
transform: translateX(100%);
}
.order-card .cancel-order span {
-webkit-transform: translateX(100%);
transform: translateX(100%);
opacity: 0;
}
.order-card:hover .cancel-order .icon, .order-card:focus-within .cancel-order .icon {
opacity: 1;
}
.order-card .cancel-order:hover .icon,
.order-card .cancel-order:hover span {
opacity: 1;
-webkit-transform: translateX(0);
transform: translateX(0);
}
.transaction-card button {
opacity: 0;
-webkit-transition: opacity 0.3s;
transition: opacity 0.3s;
}
.transaction-card:hover button {
opacity: 1;
}
}

File diff suppressed because one or more lines are too long

View File

@ -19,7 +19,7 @@ body {
&,
* {
--accent-color: #504dff;
--accent-color--light: #f4f4ff;
--accent-color--light: #eeeeff;
--text-color: 36, 36, 36;
--background-color: 255, 255, 255;
--foreground-color: rgb(250, 252, 255);
@ -42,12 +42,15 @@ body[data-theme="dark"] {
--text-color: 230, 230, 230;
--text-color-light: 170, 170, 170;
--background-color: 10, 10, 10;
--foreground-color: rgb(20, 20, 20);
--foreground-color: rgb(24, 24, 24);
--danger-color: rgb(255, 106, 106);
--green: #00e676;
--yellow: #ffd13a;
--loan-color: rgb(255, 232, 170);
}
sm-popup::part(popup) {
background-color: var(--foreground-color);
}
}
p,
@ -87,15 +90,16 @@ button,
cursor: pointer;
transition: transform 0.3s;
-webkit-tap-highlight-color: transparent;
align-items: center;
font-size: 0.9rem;
font-weight: 500;
}
.button {
white-space: nowrap;
padding: 0.6rem 1rem;
border-radius: 0.3rem;
font-weight: 500;
font-size: 0.8rem;
background-color: var(--accent-color--light);
color: var(--accent-color);
background-color: rgba(var(--text-color), 0.06);
color: rgba(var(--text-color), 0.8);
justify-content: center;
&--primary {
background-color: var(--accent-color);
@ -112,7 +116,8 @@ a:any-link:focus-visible {
}
sm-input {
--border-radius: 0.5rem;
font-size: 0.9rem;
--border-radius: 0.3rem;
--background: var(--accent-color--light);
}
sm-button {
@ -128,8 +133,14 @@ sm-button {
fill: rgba(var(--text-color), 0.6);
}
}
&.uppercase {
letter-spacing: 0.05em;
}
&.danger {
--background: var(--danger-color);
color: rgba(var(--background-color), 1);
}
}
ul {
list-style: none;
}
@ -289,14 +300,9 @@ ul {
justify-content: space-between;
}
.stretch {
justify-content: stretch;
justify-items: stretch;
& > * {
.w-100 {
width: 100%;
}
}
.interact {
position: relative;
@ -304,12 +310,19 @@ ul {
transition: transform 0.3s;
-webkit-tap-highlight-color: transparent;
}
.empty-state {
display: grid;
justify-content: center;
text-align: center;
width: 100%;
padding: 1.5rem;
}
.observe-empty-state:empty {
display: none;
}
.observe-empty-state:not(:empty) ~ .empty-state {
.observe-empty-state:not(:empty) + .empty-state {
display: none;
}
@ -360,6 +373,9 @@ ul {
}
}
}
#prompt_message {
margin-bottom: 1.5rem;
}
button:active,
.button:active,
@ -381,6 +397,22 @@ button:active,
cursor: pointer;
}
.dropdown-wrapper {
position: relative;
z-index: 2;
}
.dropdown {
top: 100%;
right: 0;
border-radius: 0.5rem;
padding: 1.5rem;
width: min(24rem, calc(100vw - 3rem));
position: absolute;
background-color: var(--foreground-color);
border: solid thin rgba(var(--text-color), 0.1);
box-shadow: 0 0.5rem 1.5rem -0.5rem rgba(0, 0, 0, 0.1);
}
#main_page {
padding: 1.5rem;
@ -430,9 +462,7 @@ strip-select {
border-radius: 0.3rem;
}
strip-option {
text-transform: uppercase;
font-weight: 500;
letter-spacing: 0.05em;
font-size: 0.8rem;
--border-radius: 0;
--active-option-color: rgba(var(--background-color), 1);
@ -444,6 +474,15 @@ strip-option {
--border-radius: 0 0.3rem 0.3rem 0;
}
}
sm-select,
sm-option {
font-size: 0.9rem;
}
sm-checkbox {
--height: 1rem;
--width: 1rem;
-webkit-tap-highlight-color: transparent;
}
.warning {
background-color: khaki;
color: rgba(0, 0, 0, 0.7);
@ -461,16 +500,6 @@ strip-option {
.page {
height: 100%;
}
.table {
&__row {
display: grid;
grid-template-columns: repeat(var(--table-columns), auto);
}
&__header {
color: rgba(var(--text-color), 0.8);
font-size: 0.8rem;
}
}
#landing {
grid-template-rows: auto 1fr;
header {
@ -483,7 +512,6 @@ strip-option {
}
}
#sign_in,
#sign_up {
grid-template-rows: auto 1fr;
align-items: center;
@ -492,14 +520,9 @@ strip-option {
justify-self: center;
width: min(24rem, 100%);
}
sm-form {
margin: 2rem 0;
}
header {
padding: 1.5rem 0;
}
}
#sign_up {
sm-copy {
font-size: 0.9rem;
--button-border-radius: 0.5rem;
@ -507,9 +530,6 @@ strip-option {
.h2 {
margin-bottom: 0.5rem;
}
.card {
margin: 1.5rem 0;
}
h5 {
font-weight: 500;
color: rgba(var(--text-color), 0.8);
@ -528,21 +548,28 @@ strip-option {
#home {
height: 100%;
display: grid;
align-items: flex-start;
align-content: flex-start;
grid-template-columns: minmax(0, 1fr);
}
#login_form__priv_key {
margin-top: 1rem;
}
#main_header {
padding: 1.8rem 1.5rem;
margin-top: 2rem;
margin-bottom: 1rem;
display: grid;
gap: 1rem;
align-items: center;
grid-template-columns: 1fr auto;
grid-template-columns: 1fr auto auto;
grid-column: 1/-1;
}
#trade_form {
--width: min(24rem, 100%);
#trade_form,
#login_form {
align-self: flex-start;
padding: 1rem 1.5rem;
padding: 1rem 1.5rem 1.5rem 1.5rem;
}
#quantity_selector {
.button {
@ -561,16 +588,131 @@ strip-option {
font-weight: 500;
min-width: 8ch;
}
#orders_section {
padding: 1.5rem;
#my_orders_section,
#market_orders_section {
padding-top: 1rem;
.icon {
height: 1.2rem;
width: 1.2rem;
}
}
.orders_section__header {
padding: 0 1.5rem;
}
#my_orders_section__header {
height: 2.4rem;
}
#orders_section__header--primary {
sm-tab-header {
--gap: 1.5rem;
}
sm-tab {
font-size: 0.9rem;
--padding: 0.8rem 0;
}
}
.list__item {
padding: 0.5rem 1.5rem;
display: grid;
}
.order-card {
position: relative;
outline: none;
user-select: none;
align-items: center;
gap: 0.5rem;
padding: 0.5rem 1.5rem 0.5rem 0.5rem;
grid-template-columns: min-content repeat(3, 1fr) min-content;
&__type {
font-size: 0.9rem;
font-weight: 500;
margin-bottom: 0.3rem;
}
&[data-type="buy"] &__type {
color: var(--green);
}
&[data-type="sell"] &__type {
color: var(--danger-color);
}
&--selected {
background-color: rgba(var(--text-color), 0.08);
.cancel-order {
visibility: hidden;
pointer-events: none;
}
}
sm-checkbox {
padding: 1rem;
cursor: pointer;
}
&__quantity,
&__price {
font-size: 0.9rem;
color: rgba(var(--text-color), 0.9);
}
&__time {
font-size: 0.8rem;
color: rgba(var(--text-color), 0.8);
}
}
.cancel-order {
align-items: center;
padding: 0.4rem 0.6rem;
span {
margin-left: 0.3rem;
}
}
.transaction-card {
grid-template-columns: repeat(3, 1fr) 2rem;
&__type {
font-size: 0.9rem;
font-weight: 500;
margin-bottom: 0.3rem;
}
&[data-type="Bought"] &__type,
&--buy &__type {
color: var(--green);
}
&[data-type="Sold"] &__type,
&--sell &__type {
color: var(--danger-color);
}
&__total {
font-weight: 700;
font-size: 0.9rem;
color: rgba(var(--text-color), 0.8);
}
&__quantity,
&__price {
font-size: 0.9rem;
color: rgba(var(--text-color), 0.9);
}
}
#market_orders_list {
.list__header {
font-size: 0.8rem;
font-weight: 500;
div {
padding: 0.5rem 0;
}
}
.list__header {
margin-bottom: 0.5rem;
padding: 0 1.5rem;
grid-template-columns: repeat(3, 1fr) 2rem;
}
}
#user_section {
gap: 1.5rem;
padding: 1.5rem;
align-content: flex-start;
}
.user_section__header {
}
.wallet_actions__wrapper {
grid-column: span 3;
gap: 0.5rem;
@ -579,6 +721,11 @@ strip-option {
flex: 1;
}
}
.label {
font-size: 0.8rem;
color: rgba(var(--text-color), 0.8);
margin-bottom: 0.2rem;
}
.balance-card {
display: grid;
align-items: center;
@ -588,10 +735,6 @@ strip-option {
&.is-locked {
grid-template-columns: auto 1fr;
gap: 1rem;
.label {
font-size: 0.8rem;
color: rgba(var(--text-color), 0.8);
}
}
&:not(.is-locked) {
grid-template-columns: auto 1fr auto;
@ -622,7 +765,41 @@ strip-option {
}
}
}
.loader-button-wrapper {
#wallet_result {
justify-content: center;
text-align: center;
&__icon {
display: flex;
padding: 1rem;
border-radius: 50%;
background-color: rgba(var(--text-color), 0.06);
justify-self: center;
animation: pop-up 0.3s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275);
.icon {
height: 2rem;
width: 2rem;
}
}
}
.icon--success {
fill: var(--green);
}
.icon--failure,
.icon--error {
fill: var(--danger-color);
}
@keyframes pop-up {
from {
transform: translateY(3rem) scale(0.5);
opacity: 0;
}
to {
transform: translateY(0) scale(1);
opacity: 1;
}
}
.stateful-button-wrapper {
display: flex;
position: relative;
justify-content: center;
@ -642,10 +819,124 @@ strip-option {
position: absolute;
}
}
.stateful-result {
overflow: hidden;
position: absolute;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
left: 0;
& > * {
position: absolute;
}
&--success {
.result__background {
background-color: var(--green);
}
}
&--failure {
.result__background {
background-color: var(--danger-color);
}
}
.icon-wrapper {
animation: pop 0.4s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.icon {
height: 1.5rem;
width: 1.5rem;
fill: rgba(var(--background-color), 1);
}
span {
font-weight: 500;
color: rgba(var(--background-color), 1);
}
.result__background {
animation: ripple-reveal 1s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
}
.result__background {
border-radius: 0.3rem;
height: 100%;
width: 100%;
clip-path: circle(10%);
}
@keyframes pop {
from {
opacity: 0;
transform: translateY(2rem);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes ripple-reveal {
to {
clip-path: circle(100%);
}
}
@media screen and (max-width: 40rem) and (any-hover: none) {
.cancel-order {
span {
display: none;
}
}
}
@media screen and (max-width: 40rem) {
#main_header {
padding: 0 1.5rem;
}
sm-button {
--padding: 0.9rem 1.6rem;
}
#home {
& > :last-child {
padding-bottom: 5rem;
}
}
#bottom_nav {
position: fixed;
bottom: 0;
background-color: var(--foreground-color);
width: 100%;
}
.bottom_nav__item {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
padding: 0.5rem 0;
.item__title,
.icon {
transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.item__title {
color: rgba(var(--text-color), 0.8);
font-size: 0.8rem;
font-weight: 500;
}
.icon {
height: 1.2rem;
margin-bottom: 0.3rem;
}
&--active {
.item__title {
color: var(--accent-color);
transform: translateY(100%);
opacity: 0;
}
.icon {
transform: translateY(50%) scale(1.2);
fill: var(--accent-color);
}
}
}
.hide-on-mobile {
display: none;
}
}
@media screen and (min-width: 40rem) {
sm-popup {
@ -675,26 +966,43 @@ strip-option {
.page-layout {
grid-template-columns: 1fr 90vw 1fr;
}
}
@media screen and (max-width: 64rem) {
}
@media screen and (min-width: 64rem) {
.page-layout {
grid-template-columns: 1fr 80vw 1fr;
}
#home {
align-items: flex-start;
padding: 1.5vmax 3vmax;
grid-template-columns: 24rem minmax(0, 1fr) 20rem;
padding: 0 4vmax;
gap: 1rem;
& > * {
}
.hide-on-desktop {
display: none;
}
.card {
border-radius: 0.5rem;
background-color: var(--foreground-color);
border: solid thin rgba(var(--text-color), 0.1);
}
}
.hide-on-desktop {
display: none;
@media screen and (min-width: 48rem) {
#home {
grid-template-rows: min-content 1fr;
grid-template-columns: 24rem minmax(0, 1fr);
&.signed-in {
#orders_list,
#market_orders_list {
height: 32vmin;
overflow-y: auto;
}
}
}
#orders_section {
grid-row: span 2;
}
}
@media screen and (max-width: 64rem) {
}
@media screen and (min-width: 72rem) {
.page-layout {
grid-template-columns: 1fr 80vw 1fr;
}
#home.signed-in {
grid-template-columns: 24rem minmax(0, 1fr) 20rem;
}
}
@media screen and (min-width: 120rem) {
@ -716,11 +1024,53 @@ strip-option {
background: rgba(var(--text-color), 0.5);
}
}
.nav-item,
.interact {
.interact,
button {
transition: background-color 0.3s, transform 0.3s;
&:hover {
background-color: var(--accent-color--light);
}
}
.order-card {
.cancel-order {
justify-self: flex-end;
overflow: hidden;
.icon,
span {
transition: opacity 0.3s, transform 0.3s;
}
.icon {
opacity: 0;
transform: translateX(100%);
}
span {
transform: translateX(100%);
opacity: 0;
}
}
&:hover,
&:focus-within {
.cancel-order {
.icon {
opacity: 1;
}
}
}
.cancel-order:hover {
.icon,
span {
opacity: 1;
transform: translateX(0);
}
}
}
.transaction-card {
button {
opacity: 0;
transition: opacity 0.3s;
}
&:hover button {
opacity: 1;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -2,281 +2,22 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RanchiMall market</title>
<script src="components.js" defer></script>
<link rel="stylesheet" href="css/main.min.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet">
<script id="floGlobals">
/* Constants for FLO blockchain operations !!Make sure to add this at beginning!! */
const floGlobals = {
//Required for all
blockchain: "FLO",
//Required for blockchain API operators
apiURL: {
FLO: ['https://livenet.flocha.in/', 'https://flosight.duckdns.org/'],
FLO_TEST: ['https://testnet-flosight.duckdns.org/', 'https://testnet.flocha.in/']
},
tokenURL: "https://ranchimallflo.duckdns.org/",
token: "rupee",
adminID: "FKAEdnPfjXLHSYwrXQu377ugN4tXU7VGdf",
sendAmt: 0.001,
fee: 0.0005,
}
</script>
<script src="floGlobals.js"></script>
<script src="https://sairajzero.github.io/Standard_Operations/cdn/floCrypto.js"></script>
<script src="https://github.com/sairajzero/Standard_Operations/releases/download/test/floBlockchainAPI.js"></script>
<script src="fn.js"></script>
</head>
<body class="hide-completely">
<sm-notifications id="notification_drawer"></sm-notifications>
<audio id="notification_sound">
<source src="https://rmservices.duckdns.org/files/notification-sound.mp3" type="audio/mpeg">
<source src="https://rmservices.duckdns.org/files/notification-sound.ogg" type="audio/ogg">
</audio>
<sm-popup id="confirmation_popup">
<h4 id="confirm_title"></h4>
<p id="confirm_message"></p>
<div class="flex align-center">
<sm-button variant="no-outline" class="cancel-btn">Cancel</sm-button>
<sm-button variant="no-outline" class="submit-btn">OK</sm-button>
</div>
</sm-popup>
<sm-popup id="prompt_popup">
<h4 id="prompt_title"></h4>
<p id="prompt_message"></p>
<sm-input id="prompt_input"></sm-input>
<div class="flex align-center">
<sm-button variant="no-outline" class="cancel-btn">Cancel</sm-button>
<sm-button variant="no-outline" class="submit-btn" type="submit">OK</sm-button>
</div>
</sm-popup>
<article id="landing" class="page page-layout hide-completely">
<header class="flex space-between">
<div class="logo">
<svg class="main-logo" viewBox="0 0 27.25 32">
<title>RanchiMall</title>
<path
d="M27.14,30.86c-.74-2.48-3-4.36-8.25-6.94a20,20,0,0,1-4.2-2.49,6,6,0,0,1-1.25-1.67,4,4,0,0,1,0-2.26c.37-1.08.79-1.57,3.89-4.55a11.66,11.66,0,0,0,3.34-4.67,6.54,6.54,0,0,0,.05-2.82C20,3.6,18.58,2,16.16.49c-.89-.56-1.29-.64-1.3-.24a3,3,0,0,1-.3.72l-.3.55L13.42.94C13,.62,12.4.26,12.19.15c-.4-.2-.73-.18-.72.05a9.39,9.39,0,0,1-.61,1.33s-.14,0-.27-.13C8.76.09,8-.27,8,.23A11.73,11.73,0,0,1,6.76,2.6C4.81,5.87,2.83,7.49.77,7.49c-.89,0-.88,0-.61,1,.22.85.33.92,1.09.69A5.29,5.29,0,0,0,3,8.33c.23-.17.45-.29.49-.26a2,2,0,0,1,.22.63A1.31,1.31,0,0,0,4,9.34a5.62,5.62,0,0,0,2.27-.87L7,8l.13.55c.19.74.32.82,1,.65a7.06,7.06,0,0,0,3.46-2.47l.6-.71-.06.64c-.17,1.63-1.3,3.42-3.39,5.42L6.73,14c-3.21,3.06-3,5.59.6,8a46.77,46.77,0,0,0,4.6,2.41c.28.13,1,.52,1.59.87,3.31,2,4.95,3.92,4.95,5.93a2.49,2.49,0,0,0,.07.77h0c.09.09,0,.1.9-.14a2.61,2.61,0,0,0,.83-.32,3.69,3.69,0,0,0-.55-1.83A11.14,11.14,0,0,0,17,26.81a35.7,35.7,0,0,0-5.1-2.91C9.37,22.64,8.38,22,7.52,21.17a3.53,3.53,0,0,1-1.18-2.48c0-1.38.71-2.58,2.5-4.23,2.84-2.6,3.92-3.91,4.67-5.65a3.64,3.64,0,0,0,.42-2A3.37,3.37,0,0,0,13.61,5l-.32-.74.29-.48c.17-.27.37-.63.46-.8l.15-.3.44.64a5.92,5.92,0,0,1,1,2.81,5.86,5.86,0,0,1-.42,1.94c0,.12-.12.3-.15.4a9.49,9.49,0,0,1-.67,1.1,28,28,0,0,1-4,4.29C8.62,15.49,8.05,16.44,8,17.78a3.28,3.28,0,0,0,1.11,2.76c.95,1,2.07,1.74,5.25,3.32,3.64,1.82,5.22,2.9,6.41,4.38A4.78,4.78,0,0,1,21.94,31a3.21,3.21,0,0,0,.14.92,1.06,1.06,0,0,0,.43-.05l.83-.22.46-.12-.06-.46c-.21-1.53-1.62-3.25-3.94-4.8a37.57,37.57,0,0,0-5.22-2.82A13.36,13.36,0,0,1,11,21.19a3.36,3.36,0,0,1-.8-4.19c.41-.85.83-1.31,3.77-4.15,2.39-2.31,3.43-4.13,3.43-6a5.85,5.85,0,0,0-2.08-4.29c-.23-.21-.44-.43-.65-.65A2.5,2.5,0,0,1,15.27.69a10.6,10.6,0,0,1,2.91,2.78A4.16,4.16,0,0,1,19,6.16a4.91,4.91,0,0,1-.87,3c-.71,1.22-1.26,1.82-4.27,4.67a9.47,9.47,0,0,0-2.07,2.6,2.76,2.76,0,0,0-.33,1.54,2.76,2.76,0,0,0,.29,1.47c.57,1.21,2.23,2.55,4.65,3.73a32.41,32.41,0,0,1,5.82,3.24c2.16,1.6,3.2,3.16,3.2,4.8a1.94,1.94,0,0,0,.09.76,4.54,4.54,0,0,0,1.66-.4C27.29,31.42,27.29,31.37,27.14,30.86ZM6.1,7h0a3.77,3.77,0,0,1-1.46.45L4,7.51l.68-.83a25.09,25.09,0,0,0,3-4.82A12,12,0,0,1,8.28.76c.11-.12.77.32,1.53,1l.63.58-.57.84A10.34,10.34,0,0,1,6.1,7Zm5.71-1.78A9.77,9.77,0,0,1,9.24,7.18h0a5.25,5.25,0,0,1-1.17.28l-.58,0,.65-.78a21.29,21.29,0,0,0,2.1-3.12c.22-.41.42-.76.44-.79s.5.43.9,1.24L12,5ZM13.41,3a2.84,2.84,0,0,1-.45.64,11,11,0,0,1-.9-.91l-.84-.9.19-.45c.34-.79.39-.8,1-.31A9.4,9.4,0,0,1,13.8,2.33q-.18.34-.39.69Z" />
</svg>
<div class="grid">
<h4>RanchiMall market</h4>
</div>
</div>
<div class="flex">
<!-- <a href="#/sign_up" class="button">Sign up</a> -->
<a href="#/sign_in" class="button button--primary">Sign in</a>
</div>
</header>
<div class="grid justify-center">
<h1 class="h1">Decentralized banking <br> made simple</h1>
<p>*Interest rates are re-calculated with each new transaction done on network</p>
<div class="interest-container">
</div>
</div>
</article>
<article id="sign_in" class="page page-layout hide-completely">
<header>
<div class="logo">
<svg class="main-logo" viewBox="0 0 27.25 32">
<title>RanchiMall</title>
<path
d="M27.14,30.86c-.74-2.48-3-4.36-8.25-6.94a20,20,0,0,1-4.2-2.49,6,6,0,0,1-1.25-1.67,4,4,0,0,1,0-2.26c.37-1.08.79-1.57,3.89-4.55a11.66,11.66,0,0,0,3.34-4.67,6.54,6.54,0,0,0,.05-2.82C20,3.6,18.58,2,16.16.49c-.89-.56-1.29-.64-1.3-.24a3,3,0,0,1-.3.72l-.3.55L13.42.94C13,.62,12.4.26,12.19.15c-.4-.2-.73-.18-.72.05a9.39,9.39,0,0,1-.61,1.33s-.14,0-.27-.13C8.76.09,8-.27,8,.23A11.73,11.73,0,0,1,6.76,2.6C4.81,5.87,2.83,7.49.77,7.49c-.89,0-.88,0-.61,1,.22.85.33.92,1.09.69A5.29,5.29,0,0,0,3,8.33c.23-.17.45-.29.49-.26a2,2,0,0,1,.22.63A1.31,1.31,0,0,0,4,9.34a5.62,5.62,0,0,0,2.27-.87L7,8l.13.55c.19.74.32.82,1,.65a7.06,7.06,0,0,0,3.46-2.47l.6-.71-.06.64c-.17,1.63-1.3,3.42-3.39,5.42L6.73,14c-3.21,3.06-3,5.59.6,8a46.77,46.77,0,0,0,4.6,2.41c.28.13,1,.52,1.59.87,3.31,2,4.95,3.92,4.95,5.93a2.49,2.49,0,0,0,.07.77h0c.09.09,0,.1.9-.14a2.61,2.61,0,0,0,.83-.32,3.69,3.69,0,0,0-.55-1.83A11.14,11.14,0,0,0,17,26.81a35.7,35.7,0,0,0-5.1-2.91C9.37,22.64,8.38,22,7.52,21.17a3.53,3.53,0,0,1-1.18-2.48c0-1.38.71-2.58,2.5-4.23,2.84-2.6,3.92-3.91,4.67-5.65a3.64,3.64,0,0,0,.42-2A3.37,3.37,0,0,0,13.61,5l-.32-.74.29-.48c.17-.27.37-.63.46-.8l.15-.3.44.64a5.92,5.92,0,0,1,1,2.81,5.86,5.86,0,0,1-.42,1.94c0,.12-.12.3-.15.4a9.49,9.49,0,0,1-.67,1.1,28,28,0,0,1-4,4.29C8.62,15.49,8.05,16.44,8,17.78a3.28,3.28,0,0,0,1.11,2.76c.95,1,2.07,1.74,5.25,3.32,3.64,1.82,5.22,2.9,6.41,4.38A4.78,4.78,0,0,1,21.94,31a3.21,3.21,0,0,0,.14.92,1.06,1.06,0,0,0,.43-.05l.83-.22.46-.12-.06-.46c-.21-1.53-1.62-3.25-3.94-4.8a37.57,37.57,0,0,0-5.22-2.82A13.36,13.36,0,0,1,11,21.19a3.36,3.36,0,0,1-.8-4.19c.41-.85.83-1.31,3.77-4.15,2.39-2.31,3.43-4.13,3.43-6a5.85,5.85,0,0,0-2.08-4.29c-.23-.21-.44-.43-.65-.65A2.5,2.5,0,0,1,15.27.69a10.6,10.6,0,0,1,2.91,2.78A4.16,4.16,0,0,1,19,6.16a4.91,4.91,0,0,1-.87,3c-.71,1.22-1.26,1.82-4.27,4.67a9.47,9.47,0,0,0-2.07,2.6,2.76,2.76,0,0,0-.33,1.54,2.76,2.76,0,0,0,.29,1.47c.57,1.21,2.23,2.55,4.65,3.73a32.41,32.41,0,0,1,5.82,3.24c2.16,1.6,3.2,3.16,3.2,4.8a1.94,1.94,0,0,0,.09.76,4.54,4.54,0,0,0,1.66-.4C27.29,31.42,27.29,31.37,27.14,30.86ZM6.1,7h0a3.77,3.77,0,0,1-1.46.45L4,7.51l.68-.83a25.09,25.09,0,0,0,3-4.82A12,12,0,0,1,8.28.76c.11-.12.77.32,1.53,1l.63.58-.57.84A10.34,10.34,0,0,1,6.1,7Zm5.71-1.78A9.77,9.77,0,0,1,9.24,7.18h0a5.25,5.25,0,0,1-1.17.28l-.58,0,.65-.78a21.29,21.29,0,0,0,2.1-3.12c.22-.41.42-.76.44-.79s.5.43.9,1.24L12,5ZM13.41,3a2.84,2.84,0,0,1-.45.64,11,11,0,0,1-.9-.91l-.84-.9.19-.45c.34-.79.39-.8,1-.31A9.4,9.4,0,0,1,13.8,2.33q-.18.34-.39.69Z" />
</svg>
<div class="grid">
<h4>RanchiMall market</h4>
</div>
</div>
</header>
<section>
<h1 class="h2">Sign In</h1>
<p>Welcome back, glad to see you again</p>
<sm-form>
<sm-input id="private_key_field" type="password" placeholder="FLO private key"
error-text="Private key is invalid" data-private-key required></sm-input>
<sm-button id="sign_in_button" variant="primary" disabled>Sign In</sm-button>
</sm-form>
<p>
New here? <a href="#/sign_up">get your FLO login credentials</a>
</p>
</section>
</article>
<article id="sign_up" class="page page-layout hide-completely">
<header>
<div class="logo">
<svg class="main-logo" viewBox="0 0 27.25 32">
<title>RanchiMall</title>
<path
d="M27.14,30.86c-.74-2.48-3-4.36-8.25-6.94a20,20,0,0,1-4.2-2.49,6,6,0,0,1-1.25-1.67,4,4,0,0,1,0-2.26c.37-1.08.79-1.57,3.89-4.55a11.66,11.66,0,0,0,3.34-4.67,6.54,6.54,0,0,0,.05-2.82C20,3.6,18.58,2,16.16.49c-.89-.56-1.29-.64-1.3-.24a3,3,0,0,1-.3.72l-.3.55L13.42.94C13,.62,12.4.26,12.19.15c-.4-.2-.73-.18-.72.05a9.39,9.39,0,0,1-.61,1.33s-.14,0-.27-.13C8.76.09,8-.27,8,.23A11.73,11.73,0,0,1,6.76,2.6C4.81,5.87,2.83,7.49.77,7.49c-.89,0-.88,0-.61,1,.22.85.33.92,1.09.69A5.29,5.29,0,0,0,3,8.33c.23-.17.45-.29.49-.26a2,2,0,0,1,.22.63A1.31,1.31,0,0,0,4,9.34a5.62,5.62,0,0,0,2.27-.87L7,8l.13.55c.19.74.32.82,1,.65a7.06,7.06,0,0,0,3.46-2.47l.6-.71-.06.64c-.17,1.63-1.3,3.42-3.39,5.42L6.73,14c-3.21,3.06-3,5.59.6,8a46.77,46.77,0,0,0,4.6,2.41c.28.13,1,.52,1.59.87,3.31,2,4.95,3.92,4.95,5.93a2.49,2.49,0,0,0,.07.77h0c.09.09,0,.1.9-.14a2.61,2.61,0,0,0,.83-.32,3.69,3.69,0,0,0-.55-1.83A11.14,11.14,0,0,0,17,26.81a35.7,35.7,0,0,0-5.1-2.91C9.37,22.64,8.38,22,7.52,21.17a3.53,3.53,0,0,1-1.18-2.48c0-1.38.71-2.58,2.5-4.23,2.84-2.6,3.92-3.91,4.67-5.65a3.64,3.64,0,0,0,.42-2A3.37,3.37,0,0,0,13.61,5l-.32-.74.29-.48c.17-.27.37-.63.46-.8l.15-.3.44.64a5.92,5.92,0,0,1,1,2.81,5.86,5.86,0,0,1-.42,1.94c0,.12-.12.3-.15.4a9.49,9.49,0,0,1-.67,1.1,28,28,0,0,1-4,4.29C8.62,15.49,8.05,16.44,8,17.78a3.28,3.28,0,0,0,1.11,2.76c.95,1,2.07,1.74,5.25,3.32,3.64,1.82,5.22,2.9,6.41,4.38A4.78,4.78,0,0,1,21.94,31a3.21,3.21,0,0,0,.14.92,1.06,1.06,0,0,0,.43-.05l.83-.22.46-.12-.06-.46c-.21-1.53-1.62-3.25-3.94-4.8a37.57,37.57,0,0,0-5.22-2.82A13.36,13.36,0,0,1,11,21.19a3.36,3.36,0,0,1-.8-4.19c.41-.85.83-1.31,3.77-4.15,2.39-2.31,3.43-4.13,3.43-6a5.85,5.85,0,0,0-2.08-4.29c-.23-.21-.44-.43-.65-.65A2.5,2.5,0,0,1,15.27.69a10.6,10.6,0,0,1,2.91,2.78A4.16,4.16,0,0,1,19,6.16a4.91,4.91,0,0,1-.87,3c-.71,1.22-1.26,1.82-4.27,4.67a9.47,9.47,0,0,0-2.07,2.6,2.76,2.76,0,0,0-.33,1.54,2.76,2.76,0,0,0,.29,1.47c.57,1.21,2.23,2.55,4.65,3.73a32.41,32.41,0,0,1,5.82,3.24c2.16,1.6,3.2,3.16,3.2,4.8a1.94,1.94,0,0,0,.09.76,4.54,4.54,0,0,0,1.66-.4C27.29,31.42,27.29,31.37,27.14,30.86ZM6.1,7h0a3.77,3.77,0,0,1-1.46.45L4,7.51l.68-.83a25.09,25.09,0,0,0,3-4.82A12,12,0,0,1,8.28.76c.11-.12.77.32,1.53,1l.63.58-.57.84A10.34,10.34,0,0,1,6.1,7Zm5.71-1.78A9.77,9.77,0,0,1,9.24,7.18h0a5.25,5.25,0,0,1-1.17.28l-.58,0,.65-.78a21.29,21.29,0,0,0,2.1-3.12c.22-.41.42-.76.44-.79s.5.43.9,1.24L12,5ZM13.41,3a2.84,2.84,0,0,1-.45.64,11,11,0,0,1-.9-.91l-.84-.9.19-.45c.34-.79.39-.8,1-.31A9.4,9.4,0,0,1,13.8,2.33q-.18.34-.39.69Z" />
</svg>
<div class="grid">
<h4>RanchiMall market</h4>
</div>
</div>
</header>
<section class="grid">
<h1 class="h2">FLO credentials</h1>
<p>Get your FLO credentials to use RanchiMall market and all RanchiMall FLO apps. </p>
<div class="grid gap-1-5 card">
<div class="grid gap-0-5">
<h5>FLO ID</h5>
<sm-copy id="generated_flo_id"></sm-copy>
</div>
<div class="grid gap-0-5">
<h5>Private key</h5>
<sm-copy id="generated_private_key"></sm-copy>
</div>
</div>
<sm-button id="sign_up_button" variant="primary">Sign in with these credentials</sm-button>
<strong class="warning">
Keep your private key secure and don't share with anyone.
Once lost there is no way to recover private key.
</strong>
</section>
</article>
<article id="loading" class="page page-layout hide-completely">
<sm-spinner></sm-spinner>
<h4>Loading RanchiMall Market</h4>
</article>
<article id="home" class="page">
<section>
<header id="main_header">
<div class="logo">
<svg class="main-logo" viewBox="0 0 27.25 32">
<title>RanchiMall</title>
<path
d="M27.14,30.86c-.74-2.48-3-4.36-8.25-6.94a20,20,0,0,1-4.2-2.49,6,6,0,0,1-1.25-1.67,4,4,0,0,1,0-2.26c.37-1.08.79-1.57,3.89-4.55a11.66,11.66,0,0,0,3.34-4.67,6.54,6.54,0,0,0,.05-2.82C20,3.6,18.58,2,16.16.49c-.89-.56-1.29-.64-1.3-.24a3,3,0,0,1-.3.72l-.3.55L13.42.94C13,.62,12.4.26,12.19.15c-.4-.2-.73-.18-.72.05a9.39,9.39,0,0,1-.61,1.33s-.14,0-.27-.13C8.76.09,8-.27,8,.23A11.73,11.73,0,0,1,6.76,2.6C4.81,5.87,2.83,7.49.77,7.49c-.89,0-.88,0-.61,1,.22.85.33.92,1.09.69A5.29,5.29,0,0,0,3,8.33c.23-.17.45-.29.49-.26a2,2,0,0,1,.22.63A1.31,1.31,0,0,0,4,9.34a5.62,5.62,0,0,0,2.27-.87L7,8l.13.55c.19.74.32.82,1,.65a7.06,7.06,0,0,0,3.46-2.47l.6-.71-.06.64c-.17,1.63-1.3,3.42-3.39,5.42L6.73,14c-3.21,3.06-3,5.59.6,8a46.77,46.77,0,0,0,4.6,2.41c.28.13,1,.52,1.59.87,3.31,2,4.95,3.92,4.95,5.93a2.49,2.49,0,0,0,.07.77h0c.09.09,0,.1.9-.14a2.61,2.61,0,0,0,.83-.32,3.69,3.69,0,0,0-.55-1.83A11.14,11.14,0,0,0,17,26.81a35.7,35.7,0,0,0-5.1-2.91C9.37,22.64,8.38,22,7.52,21.17a3.53,3.53,0,0,1-1.18-2.48c0-1.38.71-2.58,2.5-4.23,2.84-2.6,3.92-3.91,4.67-5.65a3.64,3.64,0,0,0,.42-2A3.37,3.37,0,0,0,13.61,5l-.32-.74.29-.48c.17-.27.37-.63.46-.8l.15-.3.44.64a5.92,5.92,0,0,1,1,2.81,5.86,5.86,0,0,1-.42,1.94c0,.12-.12.3-.15.4a9.49,9.49,0,0,1-.67,1.1,28,28,0,0,1-4,4.29C8.62,15.49,8.05,16.44,8,17.78a3.28,3.28,0,0,0,1.11,2.76c.95,1,2.07,1.74,5.25,3.32,3.64,1.82,5.22,2.9,6.41,4.38A4.78,4.78,0,0,1,21.94,31a3.21,3.21,0,0,0,.14.92,1.06,1.06,0,0,0,.43-.05l.83-.22.46-.12-.06-.46c-.21-1.53-1.62-3.25-3.94-4.8a37.57,37.57,0,0,0-5.22-2.82A13.36,13.36,0,0,1,11,21.19a3.36,3.36,0,0,1-.8-4.19c.41-.85.83-1.31,3.77-4.15,2.39-2.31,3.43-4.13,3.43-6a5.85,5.85,0,0,0-2.08-4.29c-.23-.21-.44-.43-.65-.65A2.5,2.5,0,0,1,15.27.69a10.6,10.6,0,0,1,2.91,2.78A4.16,4.16,0,0,1,19,6.16a4.91,4.91,0,0,1-.87,3c-.71,1.22-1.26,1.82-4.27,4.67a9.47,9.47,0,0,0-2.07,2.6,2.76,2.76,0,0,0-.33,1.54,2.76,2.76,0,0,0,.29,1.47c.57,1.21,2.23,2.55,4.65,3.73a32.41,32.41,0,0,1,5.82,3.24c2.16,1.6,3.2,3.16,3.2,4.8a1.94,1.94,0,0,0,.09.76,4.54,4.54,0,0,0,1.66-.4C27.29,31.42,27.29,31.37,27.14,30.86ZM6.1,7h0a3.77,3.77,0,0,1-1.46.45L4,7.51l.68-.83a25.09,25.09,0,0,0,3-4.82A12,12,0,0,1,8.28.76c.11-.12.77.32,1.53,1l.63.58-.57.84A10.34,10.34,0,0,1,6.1,7Zm5.71-1.78A9.77,9.77,0,0,1,9.24,7.18h0a5.25,5.25,0,0,1-1.17.28l-.58,0,.65-.78a21.29,21.29,0,0,0,2.1-3.12c.22-.41.42-.76.44-.79s.5.43.9,1.24L12,5ZM13.41,3a2.84,2.84,0,0,1-.45.64,11,11,0,0,1-.9-.91l-.84-.9.19-.45c.34-.79.39-.8,1-.31A9.4,9.4,0,0,1,13.8,2.33q-.18.34-.39.69Z" />
</svg>
<div class="grid">
<h4>RanchiMall Market</h4>
</div>
</div>
<theme-toggle></theme-toggle>
</header>
<sm-form id="trade_form">
<div class="flex space-between align-center">
<h4>Trade FLO</h4>
<strip-select id="trade_type_selector">
<strip-option value="buy" selected>Buy</strip-option>
<strip-option value="sell">Sell</strip-option>
</strip-select>
</div>
<sm-input id="get_price" variant="outlined" placeholder="Max price" type="number" step="0.00000001"
required hiderequired animate>
</sm-input>
<sm-input id="get_quantity" variant="outlined" placeholder="Quantity" type="number" step="0.00000001"
required hiderequired animate>
</sm-input>
<div id="quantity_selector" class="flex align-center">
<span id="quantity_type">Rupee</span>
<button class="button" value="25">25%</button>
<button class="button" value="50">50%</button>
<button class="button" value="75">75%</button>
<button class="button" value="100">100%</button>
</div>
<sm-button id="trade_button" class="uppercase" variant="primary" onclick="tradeFlo()">BUY</sm-button>
</sm-form>
</section>
<section id="orders_section" class="grid gap-1-5">
<div class="flex space-between align-center">
<h4>My orders</h4>
<strip-select id="orders_scope_selector">
<strip-option value="active" selected>Open</strip-option>
<strip-option value="completed">Completed</strip-option>
</strip-select>
</div>
<div class="table" style="--table-columns: 4;">
<div class="table__header table__row">
<div></div>
<div>Quantity</div>
<div>At price</div>
<div>Order placed</div>
</div>
</div>
</section>
<section id="user_section" class="grid">
<h4 class="flex align-center user_section__header">
<svg xmlns="http://www.w3.org/2000/svg" class="icon button__icon--left" height="24px"
viewBox="0 0 24 24" width="24px">
<path d="M0 0h24v24H0V0z" fill="none" />
<path
d="M21 7.28V5c0-1.1-.9-2-2-2H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-2.28c.59-.35 1-.98 1-1.72V9c0-.74-.41-1.37-1-1.72zM20 9v6h-7V9h7zM5 19V5h14v2h-6c-1.1 0-2 .9-2 2v6c0 1.1.9 2 2 2h6v2H5z" />
<circle cx="16" cy="12" r="1.5" />
</svg>
My wallet
</h4>
<div id="wallet_actions">
<p>Select asset</p>
<sm-select id="wallet_asset_selector">
<sm-option value="FLO">FLO</sm-option>
<sm-option value="Rupee">Rupee</sm-option>
</sm-select>
<div class="flex wallet_actions__wrapper">
<button class="button" value="deposit">
Deposit
</button>
<button class="button" value="withdraw">
Withdraw
</button>
</div>
</div>
<div class="grid gap-0-5">
<h4>Balance</h4>
<div class="balance-card">
<div class="balance-card__icon">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path
d="M16.36,15.39c1.83,0,4.26-2.49,4.36-4.74-5.65-.19-4.91.47-7.28,2.39,2.19-2.4,1.42-7.79-1.43-10V6.17c2.33,1.49,2.21,5.14,0,7.15-2.23-2-2.27-5.69,0-7.15V3c-2.83,2.26-3.62,7.66-1.44,10-2.36-1.93-1.63-2.58-7.28-2.39.1,2.26,2.55,4.73,4.36,4.74,0,0-1.93.22-2.74-2.62,2.38-.37,4.29-.14,6.28,2-.79-.11-4.89,1.13-4.38,3.26.53.06,3,.3,3.58-.83-.17.18-1.25.5-1.53.05.38-1.39,2.32-2,2.32-2-1,1.82-.48,4.63.82,5.72,1.31-1.08,1.8-3.95.82-5.72,0,0,1.95.6,2.32,2-.29.46-1.36.12-1.53-.05.58,1.14,3.06.88,3.58.83.49-2.17-3.58-3.36-4.38-3.26,2-2.17,3.92-2.39,6.28-2C18.3,15.62,16.36,15.39,16.36,15.39ZM12,19.46c-.91-.79-.5-3,0-3.59C12.5,16.45,12.91,18.66,12,19.46Z" />
</svg>
</div>
<div class="balance-card__token">FLO</div>
<div id="flo_balance"></div>
</div>
<div class="balance-card">
<div class="balance-card__icon">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path
d="M15.3,4.91a4.78,4.78,0,0,0-.39-.5l3.14,0L18.75,2H6L5.25,4.6H9a4.22,4.22,0,0,1,3.06,1,3.16,3.16,0,0,1,.75,1.24H5.93L5.25,9.22h7.62a3.15,3.15,0,0,1-.34.82,3,3,0,0,1-1.37,1.17,5.34,5.34,0,0,1-2.2.4H5.5l0,1.9,7,8.49h3.56v-.17L9.68,14l.09,0a8.07,8.07,0,0,0,3.65-1,5,5,0,0,0,2-2.09A6.29,6.29,0,0,0,16,9.22h2.1l.69-2.42H15.93A5.93,5.93,0,0,0,15.3,4.91Z" />
</svg>
</div>
<div class="balance-card__token">Rupee</div>
<div id="rupee_balance"></div>
</div>
</div>
</section>
</article>
<sm-popup id="wallet_popup">
<header slot="header" class="popup__header">
<button class="popup__header__close" onclick="hidePopup()">
<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>
<h4 id="wallet_popup__title" class="capitalize"></h4>
</header>
<sm-form id="wallet_form">
<sm-input id="get_user_amount" variant="outlined" placeholder="Quantity" type="number" step="0.00000001"
required hiderequired animate>
</sm-input>
<sm-input id="get_private_key" variant="outlined" placeholder="FLO private key" type="password" required
error-text="Invalid private key" hiderequired animate>
</sm-input>
<div id="wallet_popup__cta_wrapper" class="loader-button-wrapper">
<sm-button id="wallet_popup__cta" variant="primary"></sm-button>
</div>
</sm-form>
</sm-popup>
<body>
<div>Current FLO Rate: <span id="cur-rate"></span></div>
<form id="login-form">
<fieldset>
<legend>Login</legend>
@ -291,8 +32,37 @@
<fieldset>
<legend>Profile</legend>
<span id="user_id"></span><br />
FLO: <span id="flo_bal"></span><br />
Rupee: <span id="rupee_bal"></span><br />
<button onclick="proxy.lock();">Add password lock</button><br />
<button onclick="UI_evt.logout();">logout</button>
<form id="buy-form">
<fieldset>
<legend>Buy</legend>
<input type="number" name="quantity" placeholder="Enter Quantity" />
<input type="number" name="max-price" placeholder="Enter Max Price" />
<input type="button" name="buy" value="buy" onclick="UI_evt.buy();" />
</fieldset>
</form>
<form id="sell-form">
<fieldset>
<legend>Sell</legend>
<input type="number" name="quantity" placeholder="Enter Quantity" />
<input type="number" name="min-price" placeholder="Enter Min Price" />
<input type="button" name="sell" value="sell" onclick="UI_evt.sell();" />
</fieldset>
</form>
<form id="deposit-withdraw-form">
<fieldset>
<legend>Deposit/Withdraw</legend><br />
<input type="number" name="quantity" placeholder="Enter Quantity" />
<input type="button" name="deposit-flo" value="Deposit FLO" onclick="UI_evt.depositFLO();" />
<input type="button" name="withdraw-flo" value="Withdraw FLO" onclick="UI_evt.withdrawFLO();" />
<input type="button" name="deposit-rupee" value="Deposit Rupee" onclick="UI_evt.depositRupee();" />
<input type="button" name="withdraw-rupee" value="Withdraw Rupee"
onclick="UI_evt.withdrawRupee();" />
</fieldset>
</form>
<button onclick="toggle_view('my-profile');">Toggle</button>
<div id="my-profile">
<div id="my-orders">
@ -320,7 +90,7 @@
<th>Select</th>
<th>Quantity</th>
<th>Min Price</th>
<th>Order placed</th>
<th>Order Placed</th>
</tr>
</thead>
<tbody data-type="sell"></tbody>
@ -328,6 +98,7 @@
</fieldset>
<button name="cancel-orders" onclick="UI_evt.cancelOrders();">Cancel Orders</button>
</fieldset>
</div>
<div id="my-transactions">
<fieldset>
@ -402,19 +173,6 @@
</fieldset>
</div>
</div>
<template id="net_balance_template">
<span class="available-balance"></span>
</template>
<template id="locked_balance_template">
<div>
<span class="label">Locked</span>
<span class="locked-balance"></span>
</div>
<div>
<span class="label">Available</span>
<span class="available-balance"></span>
</div>
</template>
<script id="ui_utils">
// Global variables
const domRefs = {};
@ -558,34 +316,6 @@
})
}
// displays a popup for asking user input. Use this instead of JS prompt
async function getPromptInput(title, message = '', options = {}) {
const { isPassword = true, cancelText = 'Cancel', confirmText = 'OK' } = options
showPopup('prompt_popup', true)
getRef('prompt_title').textContent = title;
let input = getRef('prompt_input');
input.setAttribute("placeholder", message)
let buttons = getRef('prompt_popup').querySelectorAll("sm-button");
if (isPassword)
input.setAttribute("type", "text")
else
input.setAttribute("type", "password")
input.focusIn()
buttons[0].textContent = cancelText;
buttons[1].textContent = confirmText;
return new Promise((resolve, reject) => {
buttons[0].onclick = () => {
hidePopup()
return;
}
buttons[1].onclick = () => {
let value = input.value;
hidePopup()
resolve(value)
}
})
}
//Function for displaying toast notifications. pass in error for mode param if you want to show an error.
function notify(message, mode, options = {}) {
const { pinned = false, sound = false } = options
@ -825,23 +555,23 @@
}
</script>
<script>
let user_id; //container for user ID and proxy private-key
var user_id; //container for user ID and proxy private-key
const proxy = {
private: null,
public: null,
async lock() {
lock() {
if (!this.private)
throw "No proxy key found!";
let pwd = await getPromptInput("Enter password", '', { isPassword: true });
let pwd = prompt("Enter password: ");
if (!pwd)
notify("Password cannot be empty", 'error');
alert("Password cannot be empty");
else if (pwd.length < 4)
notify("Password minimum length is 4", 'error');
alert("Password minimum length is 4");
else {
let tmp = Crypto.AES.encrypt(this.private, pwd);
localStorage.setItem("proxy_secret", "?" + tmp);
notify("Successfully locked with Password", 'success');
alert("Successfully locked with Password");
}
},
clear() {
@ -860,7 +590,7 @@
try {
let tmp = localStorage.getItem("proxy_secret");
if (typeof tmp === "string" && tmp.startsWith("?")) {
getPromptInput("Enter password", '', { isPassword: true }).then(pwd => {
let pwd = prompt("Enter password: ");
if (!pwd)
throw "Password Required for making transactions";
else {
@ -871,7 +601,6 @@
}
}
});
}
this.private = tmp;
this.public = floCrypto.getPubKeyHex(tmp);
@ -937,6 +666,14 @@
}).catch(error => console.error(error))
}
function get_rate() {
getRate().then(rate => {
console.log("Rate: ", rate);
let container = document.getElementById("cur-rate");
container.textContent = "Rs " + parseFloat(rate).toFixed(2);
}).catch(error => console.error(error))
}
function refresh(init = false) {
if (init)
console.info("init");
@ -945,23 +682,11 @@
list_buy();
list_sell();
list_txns();
get_rate();
if (init || document.getElementById('user-container').style.display === "block")
account();
}
function showBalance(containerId, availableBalance = 0, lockedBalance = 0) {
getRef(containerId).innerHTML = ''
const templateToClone = lockedBalance ? 'locked_balance_template' : 'net_balance_template';
const card = getRef(templateToClone).content.cloneNode(true).firstElementChild
card.querySelector('.available-balance').textContent = availableBalance
if (lockedBalance) {
card.querySelector('.locked-balance').textContent = lockedBalance
}
getRef(containerId).className = lockedBalance ? 'grid balance-card__amount-wrapper' : ''
getRef(containerId).parentNode.className = `balance-card ${lockedBalance ? 'is-locked' : ''}`
getRef(containerId).append(card)
}
function account() {
getAccount().then(acc => {
console.debug(acc);
@ -975,14 +700,13 @@
let flo_locked = acc.sellOrders.reduce((a, x) => a + x.quantity, 0);
let flo_net = flo_total - flo_locked;
console.debug("FLO", flo_total, flo_locked, flo_net);
showBalance("flo_balance", flo_net, flo_locked)
document.getElementById("flo_bal").textContent = flo_net + "(+" + flo_locked + ")";
//Rupee Balance
let rupee_total = acc.rupee_total;
let rupee_locked = acc.buyOrders.reduce((a, x) => a + x.quantity * x.maxPrice, 0);
let rupee_net = rupee_total - rupee_locked;
console.debug("RUPEE", rupee_total, rupee_locked, rupee_net);
showBalance("rupee_balance", rupee_net, rupee_locked)
document.getElementById("rupee_bal").textContent = rupee_net + "(+" + rupee_locked + ")";
//My buy orders
let container = document.getElementById("my-buy-orders").getElementsByTagName("tbody")[0];
container.innerHTML = '';
@ -1046,17 +770,16 @@
const UI_evt = {};
UI_evt.signup = async function () {
UI_evt.signup = function () {
let sid = document.forms['login-form']['sid'].value;
let privKey = await getPromptInput("Register private key", "Enter the private key of floID you want to register", { isPassword: true });
if (privKey) {
let privKey = prompt("Enter Private Key of floID to register: ");
signUp(privKey, sid).then(result => {
console.info(result);
notify("Account registered!", 'success')
alert("Account registered!")
}).catch(error => {
notify(error, 'error');
console.error(error)
alert(error);
});
}
};
UI_evt.logout = function () {
@ -1080,40 +803,82 @@
}).catch(error => console.error(error));
};
UI_evt.sell = function () {
let formInputs = document.forms['sell-form'];
sell(parseFloat(formInputs["quantity"].value), parseFloat(formInputs["min-price"].value), proxy.secret)
.then(result => console.log(result))
.catch(error => console.error(error))
.finally(_ => formInputs.reset());
};
UI_evt.buy = function () {
let formInputs = document.forms['buy-form'];
buy(parseFloat(formInputs["quantity"].value), parseFloat(formInputs["max-price"].value), proxy.secret)
.then(result => console.log(result))
.catch(error => console.error(error))
.finally(_ => formInputs.reset());
};
UI_evt.cancelOrders = function () {
let container = document.getElementById('my-orders');
let cancel = [];
let inputs = container.querySelectorAll('input[checked]')
let inputs = container.getElementsByTagName('input')
for (let i = 0; i < inputs.length; i++) {
if (inputs[i].type === "checkbox" && inputs[i].checked) {
let row = inputs[i].parentElement.parentElement
let id = row.dataset['id'];
let type = row.parentElement.dataset['type'];
cancel.push([type, id]);
}
}
cancel.forEach(o => cancelOrder(o[0], o[1], proxy.secret)
.then(result => console.log(result))
.catch(error => console.error(o, error)))
};
UI_evt.depositFLO = function () {
let formInputs = document.forms['deposit-withdraw-form'];
let privKey = prompt("Enter private key");
depositFLO(parseFloat(formInputs["quantity"].value), user_id, privKey, proxy.secret)
.then(result => console.log(result))
.catch(error => console.error(error))
.finally(_ => formInputs.reset());
}
UI_evt.depositRupee = function () {
let formInputs = document.forms['deposit-withdraw-form'];
let privKey = prompt("Enter private key");
depositRupee(parseFloat(formInputs["quantity"].value), user_id, privKey, proxy.secret)
.then(result => console.log(result))
.catch(error => console.error(error))
.finally(_ => formInputs.reset());
}
UI_evt.withdrawFLO = function () {
let formInputs = document.forms['deposit-withdraw-form'];
withdrawFLO(parseFloat(formInputs["quantity"].value), proxy.secret)
.then(result => console.log(result))
.catch(error => console.error(error))
.finally(_ => formInputs.reset());
}
UI_evt.withdrawRupee = function () {
let formInputs = document.forms['deposit-withdraw-form'];
withdrawRupee(parseFloat(formInputs["quantity"].value), proxy.secret)
.then(result => console.log(result))
.catch(error => console.error(error))
.finally(_ => formInputs.reset());
}
refresh(true);
</script>
<script>
function showProcess(id) {
getRef(id).children[0].classList.add('clip')
getRef(id).append(document.createElement('sm-spinner'))
}
function hideProcess(id) {
getRef(id).children[0].classList.remove('clip')
getRef(id).querySelector('sm-spinner')?.remove()
}
let tradeType = 'buy'
getRef('trade_type_selector').addEventListener('change', e => {
tradeType = e.detail.value
getRef('get_price').setAttribute('placeholder', tradeType === 'buy' ? 'Max price' : 'Min price')
getRef('trade_button').textContent = tradeType
getRef('quantity_type').textContent = tradeType === 'buy' ? `Rupee` : `FLO`
getRef('get_price').setAttribute('placeholder', e.detail.value === 'buy' ? 'Max price' : 'Min price')
getRef('trade_button').textContent = e.detail.value
})
async function tradeFlo() {
const tradeType = getRef('trade_type_selector').value
const quantity = parseFloat(getRef('get_quantity').value)
const price = parseFloat(getRef('get_price').value)
try {
@ -1131,77 +896,6 @@
getRef('trade_form').reset()
}
}
const balance = {
flo: 5.1245,
rupee: 457.2
}
const rate = {
flo: 1.487
}
getRef('quantity_selector').addEventListener('click', e => {
// Get latest balance and exchange rate
if (e.target.closest('button')) {
const target = e.target.closest('button')
const fraction = parseInt(target.value) / 100
if (tradeType === 'buy') {
getRef('get_quantity').value = parseFloat(((balance.rupee * fraction) / rate.flo).toFixed(8))
} else {
getRef('get_quantity').value = parseFloat((balance.flo * fraction).toFixed(8))
}
}
})
getRef('wallet_actions').addEventListener('click', e => {
if (e.target.closest('.button')) {
const target = e.target.closest('.button')
showPopup('wallet_popup')
const type = target.value
const asset = getRef('wallet_asset_selector').value
getRef('wallet_popup__cta').textContent = `${type}`
getRef('wallet_popup__cta').setAttribute('value', type)
getRef('wallet_popup__title').textContent = `${type} ${asset}`
if (type === 'withdraw') {
getRef('get_private_key').classList.add('hide-completely')
getRef('get_private_key').removeAttribute('required')
getRef('get_private_key').removeAttribute('hiderequired')
} else {
getRef('get_private_key').setAttribute('required', '')
getRef('get_private_key').setAttribute('hiderequired', '')
getRef('get_private_key').classList.remove('hide-completely')
}
getRef('wallet_form').elementsChanged()
}
})
getRef('wallet_popup__cta').addEventListener('click', async e => {
const asset = getRef('wallet_asset_selector').value
const type = e.target.getAttribute('value')
const quantity = parseFloat(getRef('get_quantity').value)
console.log(type, asset)
try {
showProcess('wallet_popup__cta_wrapper')
if (type === 'deposit') {
const privKey = getRef('get_private_key').value;
if (asset === 'FLO') {
await depositFLO(quantity, user_id, privKey, proxy.secret)
} else {
await depositRupee(quantity, user_id, privKey, proxy.secret)
}
notify(`Deposited ${asset} successfully`)
} else {
if (asset === 'FLO') {
await withdrawFLO(quantity, proxy.secret)
} else {
await withdrawRupee(quantity, proxy.secret)
}
notify(`Withdrawn ${asset} successfully`)
}
}
catch (err) {
notify(err, 'error')
}
finally {
hideProcess('wallet_popup__cta_wrapper')
}
})
</script>
</body>