Added smart contract filtering
This commit is contained in:
parent
9a3f2360ab
commit
1d7e9cd943
26
css/main.css
26
css/main.css
@ -1168,7 +1168,7 @@ theme-toggle {
|
||||
|
||||
.sc-card {
|
||||
display: grid;
|
||||
gap: 0.5rem;
|
||||
gap: 1rem;
|
||||
background-color: rgba(var(--foreground-color), 1);
|
||||
padding: max(1rem, 1.5vw);
|
||||
border-radius: 0.5rem;
|
||||
@ -1198,6 +1198,30 @@ theme-toggle {
|
||||
.sc-card__info-link .icon {
|
||||
fill: var(--accent-color);
|
||||
}
|
||||
.sc-card > :last-child {
|
||||
justify-content: flex-end;
|
||||
padding-top: 1rem;
|
||||
}
|
||||
.sc-card > :last-child .button {
|
||||
background-color: transparent;
|
||||
border: solid 1px var(--accent-color);
|
||||
font-size: 0.9rem;
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
|
||||
.involved-tokens li {
|
||||
padding: 0.2rem 0.5rem;
|
||||
border-radius: 0.2rem;
|
||||
background-color: rgba(var(--text-color), 0.06);
|
||||
font-size: 0.85rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
.involved-tokens li a {
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
}
|
||||
.involved-tokens li a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#filter_s_c_popup {
|
||||
--width: min(36rem, 100%);
|
||||
|
||||
2
css/main.min.css
vendored
2
css/main.min.css
vendored
File diff suppressed because one or more lines are too long
@ -1066,7 +1066,7 @@ theme-toggle {
|
||||
}
|
||||
.sc-card {
|
||||
display: grid;
|
||||
gap: 0.5rem;
|
||||
gap: 1rem;
|
||||
background-color: rgba(var(--foreground-color), 1);
|
||||
padding: max(1rem, 1.5vw);
|
||||
border-radius: 0.5rem;
|
||||
@ -1095,6 +1095,31 @@ theme-toggle {
|
||||
fill: var(--accent-color);
|
||||
}
|
||||
}
|
||||
> :last-child {
|
||||
justify-content: flex-end;
|
||||
padding-top: 1rem;
|
||||
.button {
|
||||
background-color: transparent;
|
||||
border: solid 1px var(--accent-color);
|
||||
font-size: 0.9rem;
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
.involved-tokens {
|
||||
li {
|
||||
padding: 0.2rem 0.5rem;
|
||||
border-radius: 0.2rem;
|
||||
background-color: rgba(var(--text-color), 0.06);
|
||||
font-size: 0.85rem;
|
||||
font-weight: 500;
|
||||
a {
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#filter_s_c_popup {
|
||||
|
||||
170
index.html
170
index.html
@ -80,20 +80,21 @@
|
||||
</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()">
|
||||
<button class="button button--colored margin-left-auto" onclick="clearFilters()">
|
||||
Clear
|
||||
</button>
|
||||
<button class="button button--primary" onclick="applyFilter()">
|
||||
<button class="button button--primary" onclick="renderSmartContracts()">
|
||||
Apply
|
||||
</button>
|
||||
</footer>
|
||||
</sm-popup>
|
||||
<!-- Set urls for token and flo Apis -->
|
||||
<script>
|
||||
const testMode = false
|
||||
const floGlobals = {
|
||||
blockchain: "FLO",
|
||||
tokenApiUrl: 'https://ranchimallflo.ranchimall.net',
|
||||
floApiUrl: 'https://flosight.ranchimall.net',
|
||||
blockchain: testMode ? "FLO_TEST" : "FLO",
|
||||
tokenApiUrl: testMode ? 'https://ranchimallflo-testnet-blockbook.ranchimall.net' : 'https://ranchimallflo.ranchimall.net',
|
||||
floApiUrl: testMode ? 'https://blockbook-testnet.ranchimall.net' : 'https://flosight.ranchimall.net',
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
@ -139,24 +140,8 @@
|
||||
return getRef("notification_drawer").push(message, { icon, ...options });
|
||||
}
|
||||
// Use instead of document.getElementById
|
||||
const domRefs = {};
|
||||
function getRef(elementId) {
|
||||
if (!domRefs.hasOwnProperty(elementId)) {
|
||||
domRefs[elementId] = {
|
||||
count: 1,
|
||||
ref: null,
|
||||
};
|
||||
return document.getElementById(elementId);
|
||||
} else {
|
||||
if (domRefs[elementId].count < 3) {
|
||||
domRefs[elementId].count = domRefs[elementId].count + 1;
|
||||
return document.getElementById(elementId);
|
||||
} else {
|
||||
if (!domRefs[elementId].ref)
|
||||
domRefs[elementId].ref = document.getElementById(elementId);
|
||||
return domRefs[elementId].ref;
|
||||
}
|
||||
}
|
||||
return document.getElementById(elementId);
|
||||
}
|
||||
|
||||
// Use when a function needs to be executed after user finishes changes
|
||||
@ -198,13 +183,14 @@
|
||||
filterButton.classList.toggle('selected')
|
||||
}
|
||||
const scTypes = [['time-trigger', 'Timed Event'], ['external-trigger', 'External Trigger'], ['tokenswap', 'Token Swap']]
|
||||
const { tokens, types } = floGlobals.appliedFilters
|
||||
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">
|
||||
<div id="type_filter_list" 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}/>
|
||||
<label class=${`sc-filter sc-type-filter interact ${types.has(type) ? 'selected' : ''}`}>
|
||||
<input type="checkbox" name="sc-type-filter" value=${type} onchange=${checkSelected} ?checked=${types.has(type)}/>
|
||||
<span class="sc-filter__name">${title}</span>
|
||||
</label>
|
||||
`)}
|
||||
@ -214,8 +200,8 @@
|
||||
<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}/>
|
||||
<label class=${`sc-filter token-filter interact ${tokens.has(token) ? 'selected' : ''}`}>
|
||||
<input type="checkbox" name="token-filter" value=${token} onchange=${checkSelected} ?checked=${tokens.has(token)}/>
|
||||
<span class="sc-filter__name">${token}</span>
|
||||
</label>
|
||||
`)}
|
||||
@ -228,7 +214,8 @@
|
||||
document.addEventListener('popupclosed', e => {
|
||||
zIndex--
|
||||
switch (e.target.id) {
|
||||
case 'saved_ids_popup':
|
||||
case 'filter_s_c_popup':
|
||||
renderElem(getRef('filter_s_c_popup__content'), html``)
|
||||
break;
|
||||
}
|
||||
})
|
||||
@ -1121,20 +1108,75 @@
|
||||
await renderHome(state)
|
||||
})
|
||||
router.addRoute('home', renderHome)
|
||||
router.addRoute('smart-contracts', async state => {
|
||||
const smartContracts = floGlobals.smartContractList.map(contract => {
|
||||
floGlobals.appliedFilters = {
|
||||
tokens: new Set(),
|
||||
types: new Set()
|
||||
}
|
||||
function filterSmartContracts() {
|
||||
if (getRef('token_filter_list'))
|
||||
floGlobals.appliedFilters.tokens = new Set([...getRef('token_filter_list').querySelectorAll('input[type="checkbox"]:checked')]
|
||||
.map(elem => elem.value))
|
||||
if (getRef('type_filter_list'))
|
||||
floGlobals.appliedFilters.types = new Set([...getRef('type_filter_list').querySelectorAll('input[type="checkbox"]:checked')]
|
||||
.map(elem => elem.value))
|
||||
|
||||
let filteredContracts = floGlobals.smartContractList
|
||||
const { tokens, types } = floGlobals.appliedFilters
|
||||
if (tokens.size || types.size) {
|
||||
filteredContracts = filteredContracts.filter(sc => {
|
||||
const { acceptingToken, sellingToken, contractSubType, tokenIdentification } = sc
|
||||
if (tokens.size && !tokens.has(acceptingToken) && !tokens.has(sellingToken) && !tokens.has(tokenIdentification))
|
||||
return false
|
||||
if (types.size && !types.has(contractSubType))
|
||||
return false
|
||||
return true
|
||||
})
|
||||
}
|
||||
const totalFilters = tokens.size + types.size
|
||||
getRef('apply_filter_button').lastChild.textContent = totalFilters ? `Filter (${totalFilters})` : 'Filter';
|
||||
if (getRef('clear_filter_button'))
|
||||
getRef('clear_filter_button').classList[totalFilters ? 'remove' : 'add']('hidden')
|
||||
return filteredContracts
|
||||
}
|
||||
function renderSmartContracts() {
|
||||
const smartContracts = filterSmartContracts().map(contract => {
|
||||
const { tokenIdentification, acceptingToken, blockNumber, contractAddress, contractName, contractSubType,
|
||||
contractType, incorporationDate, oracle_address, price, sellingToken, status, transactionHash } = contract
|
||||
let type = ''
|
||||
let actions
|
||||
switch (contractSubType) {
|
||||
case 'tokenswap':
|
||||
type = 'Token Swap'
|
||||
actions = html`
|
||||
<div class="flex align-center gap-0-5">
|
||||
<button class="button button--small button--colored" onclick=${() => openPopup('token_swap_popup', contract)}>
|
||||
Sell ${acceptingToken}
|
||||
</button>
|
||||
<button class="button button--small button--colored" onclick=${() => openPopup('token_swap_popup', contract, true)}>
|
||||
Sell ${sellingToken}
|
||||
</button>
|
||||
</div>
|
||||
`
|
||||
break;
|
||||
case 'time-trigger':
|
||||
type = 'Timed Event'
|
||||
actions = html`
|
||||
<div class="flex align-center gap-0-5">
|
||||
<button class="button button--small button--colored" onclick=${() => openPopup('time_trigger_popup', contract)}>
|
||||
Participate
|
||||
</button>
|
||||
</div>
|
||||
`
|
||||
break;
|
||||
case 'external-trigger':
|
||||
type = 'External Trigger'
|
||||
actions = html`
|
||||
<div class="flex align-center gap-0-5">
|
||||
<button class="button button--small button--colored" onclick=${() => openPopup('external_trigger_popup', contract)}>
|
||||
Participate
|
||||
</button>
|
||||
</div>
|
||||
`
|
||||
break;
|
||||
}
|
||||
return html`
|
||||
@ -1147,25 +1189,73 @@
|
||||
</a>
|
||||
</div>
|
||||
<h4>${contractName}</h4>
|
||||
|
||||
<ul class="flex align-center flex-wrap gap-0-5 involved-tokens">
|
||||
${tokenIdentification ? html`
|
||||
<li>
|
||||
<a href=${`#/token/${tokenIdentification}`} class="token">${tokenIdentification}</a>
|
||||
</li>
|
||||
`: ''}
|
||||
${acceptingToken ? html`
|
||||
<li>
|
||||
<a href=${`#/token/${acceptingToken}`} class="token">${acceptingToken}</a>
|
||||
</li>
|
||||
`: ''}
|
||||
${sellingToken ? html`
|
||||
<li>
|
||||
<a href=${`#/token/${sellingToken}`} class="token">${sellingToken}</a>
|
||||
</li>
|
||||
`: ''}
|
||||
</ul>
|
||||
${actions}
|
||||
</li>
|
||||
`
|
||||
})
|
||||
renderElem(getRef('smart_contract_wrapper'), html`
|
||||
${smartContracts.length ? html`
|
||||
<ul id="smart_contract_list">
|
||||
${smartContracts}
|
||||
</ul>
|
||||
`: html`
|
||||
<div class="flex flex-direction-column align-center">
|
||||
<h3>No smart contracts found</h3>
|
||||
<p>Try changing the filters</p>
|
||||
</div>
|
||||
`}
|
||||
`)
|
||||
closePopup()
|
||||
}
|
||||
function clearFilters() {
|
||||
floGlobals.appliedFilters = {
|
||||
tokens: new Set(),
|
||||
types: new Set()
|
||||
}
|
||||
if (getRef('token_filter_list'))
|
||||
getRef('token_filter_list').querySelectorAll('input[type="checkbox"]:checked').forEach(elem => elem.checked = false)
|
||||
if (getRef('type_filter_list'))
|
||||
getRef('type_filter_list').querySelectorAll('input[type="checkbox"]:checked').forEach(elem => elem.checked = false)
|
||||
renderSmartContracts()
|
||||
closePopup()
|
||||
}
|
||||
router.addRoute('smart-contracts', async state => {
|
||||
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')}>
|
||||
<div id="smart_contract_page" class="page">
|
||||
<header class='flex space-between flex-wrap gap-1'>
|
||||
<h2>Smart contracts</h2>
|
||||
<div class="flex align-center gap-0-5">
|
||||
<button id="clear_filter_button" class="button button--small button--colored gap-0-3 hidden" onclick=${clearFilters}>
|
||||
<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>
|
||||
Clear
|
||||
</button>
|
||||
<button id="apply_filter_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>
|
||||
</header>
|
||||
<div id="smart_contract_wrapper"></div>
|
||||
</div>
|
||||
`)
|
||||
renderSmartContracts()
|
||||
getRef("page_title").textContent = '';
|
||||
})
|
||||
router.addRoute('address', async state => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user