Adding smart contract page
This commit is contained in:
parent
8b8cda084a
commit
175a42c73d
118
css/main.css
118
css/main.css
@ -243,6 +243,13 @@ ul {
|
|||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.interact {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
.overflow-ellipsis {
|
.overflow-ellipsis {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -792,8 +799,8 @@ header.grid-2 {
|
|||||||
|
|
||||||
#main_header {
|
#main_header {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr auto;
|
||||||
grid-template-areas: "logo theme" "search search";
|
grid-template-areas: "search theme";
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
}
|
}
|
||||||
@ -1134,7 +1141,84 @@ theme-toggle {
|
|||||||
min-width: 12rem;
|
min-width: 12rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#smart_contract_list {
|
||||||
|
display: grid;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.sc-card {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.5rem;
|
||||||
|
background-color: rgba(var(--foreground-color), 1);
|
||||||
|
padding: max(1rem, 1.5vw);
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
}
|
||||||
|
.sc-card__type {
|
||||||
|
display: flex;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-right: auto;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.sc-card__type::before {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
width: 0.15rem;
|
||||||
|
height: 1em;
|
||||||
|
border-radius: 0 0.5rem 0.5rem 0;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
}
|
||||||
|
.sc-card__info-link {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
.sc-card__info-link .icon {
|
||||||
|
fill: var(--accent-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
#filter_s_c_popup {
|
||||||
|
--width: min(36rem, 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
#filter_s_c_popup__content {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sc-filter {
|
||||||
|
padding: 0.5rem 0.8rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
background-color: rgba(var(--text-color), 0.06);
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
.sc-filter.selected {
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
color: rgba(var(--background-color), 1);
|
||||||
|
}
|
||||||
|
.sc-filter.selected:hover {
|
||||||
|
background-color: var(--accent-color) !important;
|
||||||
|
}
|
||||||
|
.sc-filter input {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 640px) {
|
||||||
|
.hide-on-small {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
@media only screen and (min-width: 640px) {
|
@media only screen and (min-width: 640px) {
|
||||||
|
sm-popup {
|
||||||
|
--width: 24rem;
|
||||||
|
}
|
||||||
|
.popup__header {
|
||||||
|
padding: 1rem 1.5rem 0 1.5rem;
|
||||||
|
}
|
||||||
.margin,
|
.margin,
|
||||||
.page {
|
.page {
|
||||||
margin: 0 4vw;
|
margin: 0 4vw;
|
||||||
@ -1187,14 +1271,30 @@ theme-toggle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
@media (hover: hover) {
|
@media (hover: hover) {
|
||||||
button {
|
|
||||||
transition: background-color 0.3s;
|
|
||||||
}
|
|
||||||
button:hover {
|
|
||||||
background: var(--accent-color);
|
|
||||||
color: rgba(var(--foreground-color), 1);
|
|
||||||
}
|
|
||||||
.hover {
|
.hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 0.5rem;
|
||||||
|
height: 0.5rem;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: rgba(var(--text-color), 0.3);
|
||||||
|
border-radius: 1rem;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: rgba(var(--text-color), 0.5);
|
||||||
|
}
|
||||||
|
.interact:not([disabled]) {
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
}
|
||||||
|
.interact:not([disabled]):hover {
|
||||||
|
background-color: rgba(var(--text-color), 0.06);
|
||||||
|
}
|
||||||
|
.button:not([disabled]) {
|
||||||
|
transition: background-color 0.3s, filter 0.3s;
|
||||||
|
}
|
||||||
|
.button:not([disabled]):hover {
|
||||||
|
filter: contrast(2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
2
css/main.min.css
vendored
2
css/main.min.css
vendored
File diff suppressed because one or more lines are too long
122
css/main.scss
122
css/main.scss
@ -222,7 +222,12 @@ sm-chip {
|
|||||||
ul {
|
ul {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
|
.interact {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
}
|
||||||
.overflow-ellipsis {
|
.overflow-ellipsis {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -717,10 +722,8 @@ header.grid-2 {
|
|||||||
}
|
}
|
||||||
#main_header {
|
#main_header {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr auto;
|
||||||
grid-template-areas:
|
grid-template-areas: "search theme";
|
||||||
"logo theme"
|
|
||||||
"search search";
|
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
}
|
}
|
||||||
@ -1036,7 +1039,84 @@ theme-toggle {
|
|||||||
min-width: 12rem;
|
min-width: 12rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#smart_contract_page {
|
||||||
|
}
|
||||||
|
#smart_contract_list {
|
||||||
|
display: grid;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
|
||||||
|
}
|
||||||
|
.sc-card {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.5rem;
|
||||||
|
background-color: rgba(var(--foreground-color), 1);
|
||||||
|
padding: max(1rem, 1.5vw);
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
&__type {
|
||||||
|
display: flex;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-right: auto;
|
||||||
|
align-items: center;
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
width: 0.15rem;
|
||||||
|
height: 1em;
|
||||||
|
border-radius: 0 0.5rem 0.5rem 0;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__info-link {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
.icon {
|
||||||
|
fill: var(--accent-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#filter_s_c_popup {
|
||||||
|
--width: min(36rem, 100%);
|
||||||
|
}
|
||||||
|
#filter_s_c_popup__content {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
.sc-filter {
|
||||||
|
padding: 0.5rem 0.8rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
background-color: rgba(var(--text-color), 0.06);
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
&.selected {
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
color: rgba(var(--background-color), 1);
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--accent-color) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 640px) {
|
||||||
|
.hide-on-small {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
@media only screen and (min-width: 640px) {
|
@media only screen and (min-width: 640px) {
|
||||||
|
sm-popup {
|
||||||
|
--width: 24rem;
|
||||||
|
}
|
||||||
|
.popup__header {
|
||||||
|
padding: 1rem 1.5rem 0 1.5rem;
|
||||||
|
}
|
||||||
.margin,
|
.margin,
|
||||||
.page {
|
.page {
|
||||||
margin: 0 4vw;
|
margin: 0 4vw;
|
||||||
@ -1093,14 +1173,32 @@ theme-toggle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
@media (hover: hover) {
|
@media (hover: hover) {
|
||||||
button {
|
|
||||||
transition: background-color 0.3s;
|
|
||||||
&:hover {
|
|
||||||
background: var(--accent-color);
|
|
||||||
color: rgba(var(--foreground-color), 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.hover {
|
.hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 0.5rem;
|
||||||
|
height: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: rgba(var(--text-color), 0.3);
|
||||||
|
border-radius: 1rem;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(var(--text-color), 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.interact:not([disabled]) {
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(var(--text-color), 0.06);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.button:not([disabled]) {
|
||||||
|
transition: background-color 0.3s, filter 0.3s;
|
||||||
|
&:hover {
|
||||||
|
filter: contrast(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
138
index.html
138
index.html
@ -64,7 +64,30 @@
|
|||||||
<h4 id="page_title"></h4>
|
<h4 id="page_title"></h4>
|
||||||
</div>
|
</div>
|
||||||
<main id="page_container" class="flex flex-direction-column"></main>
|
<main id="page_container" class="flex flex-direction-column"></main>
|
||||||
|
<sm-popup id="filter_s_c_popup">
|
||||||
|
<header slot="header" class="popup__header">
|
||||||
|
<button class="popup__header__close" onclick="closePopup()">
|
||||||
|
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"
|
||||||
|
fill="#000000">
|
||||||
|
<path d="M0 0h24v24H0V0z" fill="none" />
|
||||||
|
<path
|
||||||
|
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<h3>
|
||||||
|
Filter by
|
||||||
|
</h3>
|
||||||
|
</header>
|
||||||
|
<div id="filter_s_c_popup__content" class="grid gap-1-5"></div>
|
||||||
|
<footer class="flex gap-0-5">
|
||||||
|
<button class="button button--colored margin-left-auto" onclick="clearFilter()">
|
||||||
|
Clear
|
||||||
|
</button>
|
||||||
|
<button class="button button--primary" onclick="applyFilter()">
|
||||||
|
Apply
|
||||||
|
</button>
|
||||||
|
</footer>
|
||||||
|
</sm-popup>
|
||||||
<!-- Set urls for token and flo Apis -->
|
<!-- Set urls for token and flo Apis -->
|
||||||
<script>
|
<script>
|
||||||
const floGlobals = {
|
const floGlobals = {
|
||||||
@ -150,8 +173,65 @@
|
|||||||
function formatAmount(amount = 0, currency = 'inr') {
|
function formatAmount(amount = 0, currency = 'inr') {
|
||||||
if (!amount)
|
if (!amount)
|
||||||
return '0';
|
return '0';
|
||||||
return amount.toLocaleString(undefined, { currency, maximumFractionDigits: 8 })
|
return amount.toLocaleString(undefined, { currency, maximumFractionDigits: 8, minimumFractionDigits: 0 })
|
||||||
}
|
}
|
||||||
|
let zIndex = 10
|
||||||
|
// 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()
|
||||||
|
}
|
||||||
|
document.addEventListener('popupopened', async e => {
|
||||||
|
switch (e.target.id) {
|
||||||
|
case 'filter_s_c_popup':
|
||||||
|
function checkSelected(e) {
|
||||||
|
const filterButton = e.target.closest('label')
|
||||||
|
filterButton.classList.toggle('selected')
|
||||||
|
}
|
||||||
|
const scTypes = [['time-trigger', 'Timed Event'], ['external-trigger', 'External Trigger'], ['tokenswap', 'Token Swap']]
|
||||||
|
renderElem(getRef('filter_s_c_popup__content'), html`
|
||||||
|
<div class="grid gap-1">
|
||||||
|
<h5>Type</h5>
|
||||||
|
<div id="" class="flex flex-wrap gap-0-5">
|
||||||
|
${scTypes.map(([type, title]) => html`
|
||||||
|
<label class="sc-filter sc-type-filter interact">
|
||||||
|
<input type="checkbox" name="sc-type-filter" value=${type} onchange=${checkSelected}/>
|
||||||
|
<span class="sc-filter__name">${title}</span>
|
||||||
|
</label>
|
||||||
|
`)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="grid gap-1">
|
||||||
|
<h5>Involved tokens</h5>
|
||||||
|
<div id="token_filter_list" class="flex flex-wrap gap-0-5">
|
||||||
|
${floGlobals.tokenList.map(token => html`
|
||||||
|
<label class="sc-filter token-filter interact">
|
||||||
|
<input type="checkbox" name="token-filter" value=${token} onchange=${checkSelected}/>
|
||||||
|
<span class="sc-filter__name">${token}</span>
|
||||||
|
</label>
|
||||||
|
`)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
document.addEventListener('popupclosed', e => {
|
||||||
|
zIndex--
|
||||||
|
switch (e.target.id) {
|
||||||
|
case 'saved_ids_popup':
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
||||||
// fetch data and return json
|
// fetch data and return json
|
||||||
async function fetchJson(url, options = {}) {
|
async function fetchJson(url, options = {}) {
|
||||||
const response = await fetch(url, options)
|
const response = await fetch(url, options)
|
||||||
@ -347,13 +427,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function conditional(condition, value) {
|
|
||||||
if (condition)
|
|
||||||
return value
|
|
||||||
else
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
|
|
||||||
const slideInLeft = [
|
const slideInLeft = [
|
||||||
{
|
{
|
||||||
opacity: 0,
|
opacity: 0,
|
||||||
@ -959,6 +1032,52 @@
|
|||||||
await renderHome(state)
|
await renderHome(state)
|
||||||
})
|
})
|
||||||
router.addRoute('home', renderHome)
|
router.addRoute('home', renderHome)
|
||||||
|
router.addRoute('smart-contracts', async state => {
|
||||||
|
const smartContracts = floGlobals.smartContractList.map(contract => {
|
||||||
|
const { tokenIdentification, acceptingToken, blockNumber, contractAddress, contractName, contractSubType,
|
||||||
|
contractType, incorporationDate, oracle_address, price, sellingToken, status, transactionHash } = contract
|
||||||
|
let type = ''
|
||||||
|
switch (contractSubType) {
|
||||||
|
case 'tokenswap':
|
||||||
|
type = 'Token Swap'
|
||||||
|
break;
|
||||||
|
case 'time-trigger':
|
||||||
|
type = 'Timed Event'
|
||||||
|
break;
|
||||||
|
case 'external-trigger':
|
||||||
|
type = 'External Trigger'
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return html`
|
||||||
|
<li class="sc-card">
|
||||||
|
<div class="flex align-center space-between">
|
||||||
|
<p class="sc-card__type">${type}</p>
|
||||||
|
<a href=${`#/contract/${contractName}-${contractAddress}`} class="sc-card__info-link">
|
||||||
|
View details
|
||||||
|
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M10.02 6L8.61 7.41 13.19 12l-4.58 4.59L10.02 18l6-6-6-6z"/></svg>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<h4>${contractName}</h4>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
`
|
||||||
|
})
|
||||||
|
renderElem(getRef("page_container"), html`
|
||||||
|
<div id="smart-contract-page" class="page">
|
||||||
|
<header>
|
||||||
|
<div class='flex space-between'>
|
||||||
|
<h2>Smart contracts</h2>
|
||||||
|
<button class="button button--small button--colored gap-0-3" onclick=${() => openPopup('filter_s_c_popup')}>
|
||||||
|
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/></svg>
|
||||||
|
Filter
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<ul id="smart_contract_list">
|
||||||
|
${smartContracts}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
`)
|
||||||
|
})
|
||||||
router.addRoute('address', async state => {
|
router.addRoute('address', async state => {
|
||||||
try {
|
try {
|
||||||
const [floAddress] = state.wildcards
|
const [floAddress] = state.wildcards
|
||||||
@ -1062,7 +1181,6 @@
|
|||||||
if (contractParticipants[participant].winningAmount)
|
if (contractParticipants[participant].winningAmount)
|
||||||
winners.push(render.contractChoiceCard(contractParticipants[participant]))
|
winners.push(render.contractChoiceCard(contractParticipants[participant]))
|
||||||
}
|
}
|
||||||
console.log(payeeAddress)
|
|
||||||
renderElem(getRef("page_container"), html`
|
renderElem(getRef("page_container"), html`
|
||||||
<div id="contract_page" class="page">
|
<div id="contract_page" class="page">
|
||||||
${status ? html` <div class=${`status ${status}`}>${status}</div> ` : ''}
|
${status ? html` <div class=${`status ${status}`}>${status}</div> ` : ''}
|
||||||
|
|||||||
4
scripts/components.min.js
vendored
4
scripts/components.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user