mirror of
https://github.com/basicswap/basicswap.git
synced 2024-11-17 00:07:56 +00:00
commit
c9d1129e93
3 changed files with 177 additions and 253 deletions
|
@ -637,20 +637,11 @@ function filterAndSortData() {
|
|||
|
||||
let passesFilter = true;
|
||||
|
||||
if (isSentOffers) {
|
||||
if (filters.coin_to !== 'any' && coinFrom.toLowerCase() !== filters.coin_to.toLowerCase()) {
|
||||
passesFilter = false;
|
||||
}
|
||||
if (filters.coin_from !== 'any' && coinTo.toLowerCase() !== filters.coin_from.toLowerCase()) {
|
||||
passesFilter = false;
|
||||
}
|
||||
} else {
|
||||
if (filters.coin_to !== 'any' && coinTo.toLowerCase() !== filters.coin_to.toLowerCase()) {
|
||||
passesFilter = false;
|
||||
}
|
||||
if (filters.coin_from !== 'any' && coinFrom.toLowerCase() !== filters.coin_from.toLowerCase()) {
|
||||
passesFilter = false;
|
||||
}
|
||||
if (filters.coin_to !== 'any' && coinTo.toLowerCase() !== filters.coin_to.toLowerCase()) {
|
||||
passesFilter = false;
|
||||
}
|
||||
if (filters.coin_from !== 'any' && coinFrom.toLowerCase() !== filters.coin_from.toLowerCase()) {
|
||||
passesFilter = false;
|
||||
}
|
||||
|
||||
if (isSentOffers && filters.active && filters.active !== 'any') {
|
||||
|
@ -939,7 +930,7 @@ function getProfitColorClass(percentage) {
|
|||
const numericPercentage = parseFloat(percentage);
|
||||
if (numericPercentage > 0) return 'text-green-500';
|
||||
if (numericPercentage < 0) return 'text-red-500';
|
||||
if (numericPercentage === 0) return 'text-yellowr-400';
|
||||
if (numericPercentage === 0) return 'text-yellow-400';
|
||||
return 'text-white';
|
||||
}
|
||||
|
||||
|
@ -1025,16 +1016,16 @@ function createDetailsColumn(offer) {
|
|||
`;
|
||||
}
|
||||
|
||||
function createOrderbookColumn(offer, coinFrom, coinTo) {
|
||||
function createTakerAmountColumn(offer, coinTo, coinFrom) {
|
||||
const toAmount = parseFloat(offer.amount_to);
|
||||
const fromSymbol = getCoinSymbol(coinFrom);
|
||||
return `
|
||||
<td class="py-0">
|
||||
<div class="py-3 px-4 text-right">
|
||||
<a data-tooltip-target="tooltip-wallet${offer.offer_id}" href="/wallet/${fromSymbol}" class="items-center monospace">
|
||||
<div class="py-3 px-4 text-left">
|
||||
<a data-tooltip-target="tooltip-wallet${escapeHtml(offer.offer_id)}" href="/wallet/${escapeHtml(fromSymbol)}" class="items-center monospace">
|
||||
<div class="pr-2">
|
||||
<div class="text-sm font-semibold">${toAmount.toFixed(4)}</div>
|
||||
<div class="text-xs text-gray-500 dark:text-gray-400">${coinFrom}</div>
|
||||
<div class="text-sm text-gray-500 dark:text-gray-400">${coinFrom}</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -1042,7 +1033,7 @@ function createOrderbookColumn(offer, coinFrom, coinTo) {
|
|||
`;
|
||||
}
|
||||
|
||||
function createSwapColumn(offer, coinFrom, coinTo) {
|
||||
function createSwapColumn(offer, coinTo, coinFrom) {
|
||||
return `
|
||||
<td class="py-0 px-0 text-right text-sm">
|
||||
<a data-tooltip-target="tooltip-offer${offer.offer_id}" href="/offer/${offer.offer_id}">
|
||||
|
@ -1061,16 +1052,16 @@ function createSwapColumn(offer, coinFrom, coinTo) {
|
|||
`;
|
||||
}
|
||||
|
||||
function createTakerAmountColumn(offer, coinTo, coinFrom) {
|
||||
function createOrderbookColumn(offer, coinFrom, coinTo) {
|
||||
const fromAmount = parseFloat(offer.amount_from);
|
||||
const toSymbol = getCoinSymbol(coinTo);
|
||||
return `
|
||||
<td class="p-0">
|
||||
<div class="py-3 px-4 text-left">
|
||||
<div class="py-3 px-4 text-right">
|
||||
<a data-tooltip-target="tooltip-wallet-maker${escapeHtml(offer.offer_id)}" href="/wallet/${escapeHtml(toSymbol)}" class="items-center monospace">
|
||||
<div class="pr-2">
|
||||
<div class="text-sm font-semibold">${fromAmount.toFixed(4)}</div>
|
||||
<div class="text-xs text-gray-500 dark:text-gray-400">${coinTo}</div>
|
||||
<div class="text-sm text-gray-500 dark:text-gray-400">${coinTo}</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -1101,17 +1092,17 @@ function createRateColumn(offer, coinFrom, coinTo) {
|
|||
console.log(`Rate in USD: $${rateInUSD.toFixed(2)}`);
|
||||
|
||||
return `
|
||||
<td class="py-3 pl-6 bold monospace text-xs text-right items-center rate-table-info">
|
||||
<td class="py-3 semibold monospace text-xs text-right items-center rate-table-info">
|
||||
<div class="relative">
|
||||
<div class="flex flex-col items-end" data-tooltip-target="tooltip-rate-${offer.offer_id}">
|
||||
<span class="text-gray-700 dark:text-white">
|
||||
$${rateInUSD.toFixed(2)}/${fromSymbol}
|
||||
<div class="flex flex-col items-end pr-3" data-tooltip-target="tooltip-rate-${offer.offer_id}">
|
||||
<span class="text-sm bold text-gray-700 dark:text-white">
|
||||
$${rateInUSD.toFixed(2)} USD
|
||||
</span>
|
||||
<span class="text-gray-700 dark:text-white">
|
||||
${rate.toFixed(6)} ${toSymbol}/${fromSymbol}
|
||||
<span class="bold text-gray-700 dark:text-white">
|
||||
${rate.toFixed(8)} ${toSymbol}/${fromSymbol}
|
||||
</span>
|
||||
<span class="text-gray-700 dark:text-white">
|
||||
${inverseRate.toFixed(6)} ${fromSymbol}/${toSymbol}
|
||||
<span class="semibold text-gray-400 dark:text-gray-300">
|
||||
${inverseRate.toFixed(8)} ${fromSymbol}/${toSymbol}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1183,7 +1174,7 @@ function createTooltips(offer, isSentOffers, coinFrom, coinTo, postedTime, expir
|
|||
</div>
|
||||
|
||||
<div id="tooltip-offer${offer.offer_id}" role="tooltip" class="inline-block absolute z-10 py-2 px-3 text-sm font-medium text-white ${offer.is_own_offer ? 'bg-gray-300' : 'bg-green-700'} rounded-lg shadow-sm opacity-0 transition-opacity duration-300 tooltip">
|
||||
<div class="active-revoked-expired"><span class="bold">${offer.is_own_offer ? 'Edit Offer' : `Buy ${coinTo}`}</span></div>
|
||||
<div class="active-revoked-expired"><span class="bold">${offer.is_own_offer ? 'Edit Offer' : `Buy ${coinFrom}`}</span></div>
|
||||
<div class="tooltip-arrow pr-6" data-popper-arrow></div>
|
||||
</div>
|
||||
|
||||
|
@ -1283,14 +1274,14 @@ function createCombinedRateTooltip(offer, coinFrom, coinTo) {
|
|||
<p class="font-bold mb-1">Exchange Rate Explanation:</p>
|
||||
<p>This offer is ${action} ${coinFrom} for ${coinTo} <br/>at a rate that is ${Math.abs(percentDiff).toFixed(2)}% ${aboveOrBelow} market price.</p>
|
||||
<p class="font-bold mt-1">Exchange Rates:</p>
|
||||
<p>1 ${coinFrom} = ${rate.toFixed(6)} ${toSymbol}</p>
|
||||
<p>1 ${coinTo} = ${inverseRate.toFixed(6)} ${fromSymbol}</p>
|
||||
<p>1 ${coinFrom} = ${rate.toFixed(8)} ${coinTo}</p>
|
||||
<p>1 ${coinTo} = ${inverseRate.toFixed(8)} ${coinFrom}</p>
|
||||
<p class="font-bold mt-2">USD Equivalent:</p>
|
||||
<p>1 ${coinFrom} = $${rateInUSD.toFixed(2)} USD</p>
|
||||
<p class="font-bold mt-2">Current market prices:</p>
|
||||
<p>${coinFrom}: $${fromPriceUSD.toFixed(2)} USD</p>
|
||||
<p>${coinTo}: $${toPriceUSD.toFixed(2)} USD</p>
|
||||
<p class="mt-1">Market rate: 1 ${coinFrom} = ${marketRate.toFixed(6)} ${toSymbol}</p>
|
||||
<p class="mt-1">Market rate: 1 ${coinFrom} = ${marketRate.toFixed(8)} ${coinTo}</p>
|
||||
`;
|
||||
}
|
||||
|
||||
|
@ -1646,8 +1637,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
|
||||
document.getElementById('coin_to').addEventListener('change', applyFilters);
|
||||
document.getElementById('coin_from').addEventListener('change', applyFilters);
|
||||
document.getElementById('sort_by').addEventListener('change', applyFilters);
|
||||
document.getElementById('sort_dir').addEventListener('change', applyFilters);
|
||||
|
||||
document.getElementById('clearFilters').addEventListener('click', () => {
|
||||
filterForm.reset();
|
||||
|
|
|
@ -209,7 +209,7 @@ fetchHistoricalDataXHR: (coinSymbol) => {
|
|||
|
||||
// Cache
|
||||
const cache = {
|
||||
ttl: 15 * 60 * 1000,
|
||||
ttl: 15 * 60 * 1000, // 15 minutes in milliseconds
|
||||
set: (key, value, customTtl = null) => {
|
||||
const item = {
|
||||
value: value,
|
||||
|
@ -858,7 +858,7 @@ const app = {
|
|||
autoRefreshInterval: null,
|
||||
nextRefreshTime: null,
|
||||
lastRefreshedTime: null,
|
||||
isAutoRefreshEnabled: localStorage.getItem('autoRefreshEnabled') === 'true',
|
||||
isAutoRefreshEnabled: localStorage.getItem('autoRefreshEnabled') !== 'false',
|
||||
refreshTexts: {
|
||||
label: 'Auto-refresh in',
|
||||
disabled: 'Auto-refresh: disabled',
|
||||
|
@ -868,6 +868,7 @@ const app = {
|
|||
init: () => {
|
||||
window.addEventListener('load', app.onLoad);
|
||||
app.loadLastRefreshedTime();
|
||||
app.updateAutoRefreshButton();
|
||||
},
|
||||
|
||||
onLoad: async () => {
|
||||
|
@ -882,44 +883,22 @@ const app = {
|
|||
} else {
|
||||
console.warn('Chart container not found, skipping chart initialization');
|
||||
}
|
||||
for (const coin of config.coins) {
|
||||
await app.loadCoinData(coin);
|
||||
}
|
||||
|
||||
// Load all coin data immediately
|
||||
await app.loadAllCoinData();
|
||||
|
||||
if (chartModule.chart) {
|
||||
config.currentResolution = 'month';
|
||||
await chartModule.updateChart('BTC');
|
||||
app.updateResolutionButtons('BTC');
|
||||
}
|
||||
ui.setActiveContainer('btc-container');
|
||||
config.coins.forEach(coin => {
|
||||
const container = document.getElementById(`${coin.symbol.toLowerCase()}-container`);
|
||||
if (container) {
|
||||
container.addEventListener('click', () => {
|
||||
ui.setActiveContainer(`${coin.symbol.toLowerCase()}-container`);
|
||||
if (chartModule.chart) {
|
||||
if (coin.symbol === 'WOW') {
|
||||
config.currentResolution = 'day';
|
||||
}
|
||||
chartModule.updateChart(coin.symbol);
|
||||
app.updateResolutionButtons(coin.symbol);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
const refreshAllButton = document.getElementById('refresh-all');
|
||||
if (refreshAllButton) {
|
||||
refreshAllButton.addEventListener('click', app.refreshAllData);
|
||||
}
|
||||
|
||||
// Set up event listeners and other initializations
|
||||
app.setupEventListeners();
|
||||
app.initializeSelectImages();
|
||||
const headers = document.querySelectorAll('th');
|
||||
headers.forEach((header, index) => {
|
||||
header.addEventListener('click', () => app.sortTable(index, header.classList.contains('disabled')));
|
||||
});
|
||||
const closeErrorButton = document.getElementById('close-error');
|
||||
if (closeErrorButton) {
|
||||
closeErrorButton.addEventListener('click', ui.hideErrorMessage);
|
||||
}
|
||||
app.initAutoRefresh();
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error during initialization:', error);
|
||||
ui.displayErrorMessage('Failed to initialize the dashboard. Please try refreshing the page.');
|
||||
|
@ -930,7 +909,13 @@ const app = {
|
|||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
loadAllCoinData: async () => {
|
||||
for (const coin of config.coins) {
|
||||
await app.loadCoinData(coin);
|
||||
}
|
||||
},
|
||||
|
||||
loadCoinData: async (coin) => {
|
||||
const cacheKey = `coinData_${coin.symbol}`;
|
||||
let cachedData = cache.get(cacheKey);
|
||||
|
@ -962,6 +947,39 @@ const app = {
|
|||
ui.displayCoinData(coin.symbol, data);
|
||||
ui.updateLoadTimeAndCache(0, cachedData);
|
||||
},
|
||||
|
||||
setupEventListeners: () => {
|
||||
config.coins.forEach(coin => {
|
||||
const container = document.getElementById(`${coin.symbol.toLowerCase()}-container`);
|
||||
if (container) {
|
||||
container.addEventListener('click', () => {
|
||||
ui.setActiveContainer(`${coin.symbol.toLowerCase()}-container`);
|
||||
if (chartModule.chart) {
|
||||
if (coin.symbol === 'WOW') {
|
||||
config.currentResolution = 'day';
|
||||
}
|
||||
chartModule.updateChart(coin.symbol);
|
||||
app.updateResolutionButtons(coin.symbol);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const refreshAllButton = document.getElementById('refresh-all');
|
||||
if (refreshAllButton) {
|
||||
refreshAllButton.addEventListener('click', app.refreshAllData);
|
||||
}
|
||||
|
||||
const headers = document.querySelectorAll('th');
|
||||
headers.forEach((header, index) => {
|
||||
header.addEventListener('click', () => app.sortTable(index, header.classList.contains('disabled')));
|
||||
});
|
||||
|
||||
const closeErrorButton = document.getElementById('close-error');
|
||||
if (closeErrorButton) {
|
||||
closeErrorButton.addEventListener('click', ui.hideErrorMessage);
|
||||
}
|
||||
},
|
||||
|
||||
initAutoRefresh: () => {
|
||||
const toggleAutoRefreshButton = document.getElementById('toggle-auto-refresh');
|
||||
|
@ -990,13 +1008,13 @@ const app = {
|
|||
app.stopAutoRefresh();
|
||||
|
||||
if (resetTimer || !app.nextRefreshTime) {
|
||||
app.nextRefreshTime = Date.now() + 15 * 60 * 1000;
|
||||
app.nextRefreshTime = Date.now() + cache.ttl;
|
||||
}
|
||||
|
||||
const timeUntilNextRefresh = Math.max(0, app.nextRefreshTime - Date.now());
|
||||
|
||||
if (timeUntilNextRefresh === 0) {
|
||||
app.nextRefreshTime = Date.now() + 15 * 60 * 1000;
|
||||
app.nextRefreshTime = Date.now() + cache.ttl;
|
||||
}
|
||||
|
||||
app.autoRefreshInterval = setTimeout(() => {
|
||||
|
@ -1061,37 +1079,37 @@ const app = {
|
|||
},
|
||||
|
||||
updateAutoRefreshButton: () => {
|
||||
const button = document.getElementById('toggle-auto-refresh');
|
||||
if (button) {
|
||||
if (app.isAutoRefreshEnabled) {
|
||||
button.classList.remove('text-gray-600', 'dark:text-gray-400');
|
||||
button.classList.add('text-green-500', 'dark:text-green-400');
|
||||
app.startSpinAnimation();
|
||||
} else {
|
||||
button.classList.remove('text-green-500', 'dark:text-green-400');
|
||||
button.classList.add('text-gray-600', 'dark:text-gray-400');
|
||||
app.stopSpinAnimation();
|
||||
const button = document.getElementById('toggle-auto-refresh');
|
||||
if (button) {
|
||||
if (app.isAutoRefreshEnabled) {
|
||||
button.classList.remove('text-gray-600', 'dark:text-gray-400');
|
||||
button.classList.add('text-green-500', 'dark:text-green-400');
|
||||
app.startSpinAnimation();
|
||||
} else {
|
||||
button.classList.remove('text-green-500', 'dark:text-green-400');
|
||||
button.classList.add('text-gray-600', 'dark:text-gray-400');
|
||||
app.stopSpinAnimation();
|
||||
}
|
||||
button.title = app.isAutoRefreshEnabled ? 'Disable Auto-Refresh' : 'Enable Auto-Refresh';
|
||||
}
|
||||
button.title = app.isAutoRefreshEnabled ? 'Disable Auto-Refresh' : 'Enable Auto-Refresh';
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
startSpinAnimation: () => {
|
||||
const svg = document.querySelector('#toggle-auto-refresh svg');
|
||||
if (svg) {
|
||||
svg.classList.add('animate-spin');
|
||||
setTimeout(() => {
|
||||
startSpinAnimation: () => {
|
||||
const svg = document.querySelector('#toggle-auto-refresh svg');
|
||||
if (svg) {
|
||||
svg.classList.add('animate-spin');
|
||||
setTimeout(() => {
|
||||
svg.classList.remove('animate-spin');
|
||||
}, 2000);
|
||||
}
|
||||
},
|
||||
|
||||
stopSpinAnimation: () => {
|
||||
const svg = document.querySelector('#toggle-auto-refresh svg');
|
||||
if (svg) {
|
||||
svg.classList.remove('animate-spin');
|
||||
}, 2000); // Remove the animation after 2 seconds
|
||||
}
|
||||
},
|
||||
|
||||
stopSpinAnimation: () => {
|
||||
const svg = document.querySelector('#toggle-auto-refresh svg');
|
||||
if (svg) {
|
||||
svg.classList.remove('animate-spin');
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
refreshAllData: async () => {
|
||||
ui.showLoader();
|
||||
|
@ -1099,9 +1117,7 @@ stopSpinAnimation: () => {
|
|||
try {
|
||||
cache.clear();
|
||||
await app.updateBTCPrice();
|
||||
for (const coin of config.coins) {
|
||||
await app.loadCoinData(coin);
|
||||
}
|
||||
await app.loadAllCoinData();
|
||||
if (chartModule.currentCoin) {
|
||||
await chartModule.updateChart(chartModule.currentCoin, true);
|
||||
}
|
||||
|
|
|
@ -142,24 +142,25 @@ function getAPIKeys() {
|
|||
|
||||
<section class="py-4 flex flex-wrap justify-center overflow-hidden container-to-blur">
|
||||
<div class="container px-4 mx-auto">
|
||||
<div class="flex flex-wrap -m-3">
|
||||
{% set coin_data = {
|
||||
'BTC': {'name': 'Bitcoin', 'symbol': 'BTC', 'image': 'Bitcoin.png', 'show': true},
|
||||
'XMR': {'name': 'Monero', 'symbol': 'XMR', 'image': 'Monero.png', 'show': true},
|
||||
'PART': {'name': 'Particl', 'symbol': 'PART', 'image': 'Particl.png', 'show': true},
|
||||
'LTC': {'name': 'Litecoin', 'symbol': 'LTC', 'image': 'Litecoin.png', 'show': true},
|
||||
'FIRO': {'name': 'Firo', 'symbol': 'FIRO', 'image': 'Firo.png', 'show': true},
|
||||
'PIVX': {'name': 'PIVX', 'symbol': 'PIVX', 'image': 'PIVX.png', 'show': true},
|
||||
'DASH': {'name': 'Dash', 'symbol': 'DASH', 'image': 'Dash.png', 'show': true},
|
||||
'ETH': {'name': 'Ethereum', 'symbol': 'ETH', 'image': 'Ethereum.png', 'show': false},
|
||||
'DOGE': {'name': 'Dogecoin', 'symbol': 'DOGE', 'image': 'Doge.png', 'show': false},
|
||||
'DCR': {'name': 'Decred', 'symbol': 'DCR', 'image': 'Decred.png', 'show': true},
|
||||
'ZANO': {'name': 'Zano', 'symbol': 'ZANO', 'image': 'Zano.png', 'show': false},
|
||||
'BCH': {'name': 'BCH', 'symbol': 'BCH', 'image': 'Bitcoin-cash.png', 'show': true},
|
||||
'WOW': {'name': 'Wownero', 'symbol': 'WOW', 'image': 'Wownero.png', 'show': true}
|
||||
} %}
|
||||
<div class="flex flex-wrap justify-center -m-3">
|
||||
{% set coin_data = {
|
||||
'BTC': {'name': 'Bitcoin', 'symbol': 'BTC', 'image': 'Bitcoin.png', 'show': true},
|
||||
'XMR': {'name': 'Monero', 'symbol': 'XMR', 'image': 'Monero.png', 'show': true},
|
||||
'PART': {'name': 'Particl', 'symbol': 'PART', 'image': 'Particl.png', 'show': true},
|
||||
'LTC': {'name': 'Litecoin', 'symbol': 'LTC', 'image': 'Litecoin.png', 'show': true},
|
||||
'FIRO': {'name': 'Firo', 'symbol': 'FIRO', 'image': 'Firo.png', 'show': true},
|
||||
'PIVX': {'name': 'PIVX', 'symbol': 'PIVX', 'image': 'PIVX.png', 'show': true},
|
||||
'DASH': {'name': 'Dash', 'symbol': 'DASH', 'image': 'Dash.png', 'show': true},
|
||||
'ETH': {'name': 'Ethereum', 'symbol': 'ETH', 'image': 'Ethereum.png', 'show': false},
|
||||
'DOGE': {'name': 'Dogecoin', 'symbol': 'DOGE', 'image': 'Doge.png', 'show': false},
|
||||
'DCR': {'name': 'Decred', 'symbol': 'DCR', 'image': 'Decred.png', 'show': true},
|
||||
'ZANO': {'name': 'Zano', 'symbol': 'ZANO', 'image': 'Zano.png', 'show': false},
|
||||
'BCH': {'name': 'BCH', 'symbol': 'BCH', 'image': 'Bitcoin-cash.png', 'show': true},
|
||||
'WOW': {'name': 'Wownero', 'symbol': 'WOW', 'image': 'Wownero.png', 'show': true}
|
||||
}
|
||||
%}
|
||||
{% for coin_symbol, coin in coin_data.items() if coin_symbol in enabled_chart_coins and coin.show %}
|
||||
<div class="w-full sm:w-1/2 lg:w-1/6 p-3" id="{{ coin_symbol.lower() }}-container">
|
||||
<div class="w-full sm:w-1/2 lg:w-1/5 p-3" id="{{ coin_symbol.lower() }}-container">
|
||||
<div class="px-5 py-3 h-full bg-coolGray-100 dark:bg-gray-500 rounded-2xl dark:text-white {% if coin_symbol == 'BTC' %}active-container{% endif %}" style="min-height: 180px;">
|
||||
<div class="flex items-center">
|
||||
<img src="/static/images/coins/{{ coin.image }}" class="rounded-xl" style="width: 28px; height: 28px; object-fit: contain;" alt="{{ coin.name }}">
|
||||
|
@ -204,144 +205,48 @@ function getAPIKeys() {
|
|||
<div class="flex items-center justify-center pb-4 dark:text-white">
|
||||
<div class="rounded-b-md">
|
||||
<div class="w-full md:w-0/12">
|
||||
<div class="container flex flex-wrap justify-center">
|
||||
<div class="md:w-auto p-1.5 hover-container">
|
||||
<div class="flex">
|
||||
{% if sent_offers %}
|
||||
|
||||
<button id="coin_to_button" class="bg-gray-50 text-gray-900 appearance-none w-10 dark:bg-gray-500 dark:text-white border-l border-t border-b border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-l-lg flex items-center" disabled></button>
|
||||
<div class="relative">
|
||||
{{ input_arrow_down_svg | safe }}
|
||||
<select name="coin_to" id="coin_to" class="bg-gray-50 text-gray-900 appearance-none pr-10 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-none rounded-r-lg outline-none block w-full p-2.5 focus:ring-0">
|
||||
<option value="any" {% if filters.coin_to==-1 %} selected{% endif %}>Filter {% if sent_offers %}Sending{% else %}Bids{% endif %}</option>
|
||||
{% for c in coins_from %}
|
||||
<option class="text-sm" value="{{ c[0] }}" {% if filters.coin_to==c[0] %} selected{% endif %} data-image="/static/images/coins/{{ c[1]|replace(" ", "-") }}.png">{{ c[1] }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center">
|
||||
<div class="w-full md:w-auto p-1.5">
|
||||
<p class="text-sm font-heading">{{ arrow_right_svg | safe }}</p>
|
||||
<div class="container flex flex-wrap">
|
||||
<div class="md:w-auto hover-container">
|
||||
<div class="flex flex-wrap justify-center">
|
||||
<div class="md:w-auto hover-container">
|
||||
<div class="flex">
|
||||
<button id="coin_to_button" class="bg-gray-50 text-gray-900 appearance-none w-10 dark:bg-gray-500 dark:text-white border-l border-t border-b border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-l-lg flex items-center" disabled></button>
|
||||
<div class="relative">
|
||||
{{ input_arrow_down_svg | safe }}
|
||||
<select name="coin_to" id="coin_to" class="bg-gray-50 text-gray-900 appearance-none pr-10 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-none rounded-r-lg outline-none block w-full p-2.5 focus:ring-0">
|
||||
<option value="any" {% if filters.coin_to==-1 %} selected{% endif %}>Filter {% if sent_offers %}Receiving{% else %}Bids{% endif %}</option>
|
||||
{% for c in coins %}
|
||||
<option class="text-sm" value="{{ c[0] }}" {% if filters.coin_to==c[0] %} selected{% endif %} data-image="/static/images/coins/{{ c[1]|replace(" ", "-") }}.png">{{ c[1] }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<div class="w-full md:w-auto p-1.5">
|
||||
<p class="text-sm font-heading">{{ arrow_right_svg | safe }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<button id="coin_from_button" class="bg-gray-50 text-gray-900 appearance-none w-10 dark:bg-gray-500 dark:text-white border-l border-t border-b border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-l-lg flex items-center" disabled></button>
|
||||
<div class="relative">
|
||||
{{ input_arrow_down_svg | safe }}
|
||||
<select name="coin_from" id="coin_from" class="bg-gray-50 text-gray-900 appearance-none pr-10 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-none rounded-r-lg outline-none block w-full p-2.5 focus:ring-0">
|
||||
<option value="any" {% if filters.coin_from==-1 %} selected{% endif %}>Filter {% if sent_offers %}Sending{% else %}Offers{% endif %}</option>
|
||||
{% for c in coins_from %}
|
||||
<option class="text-sm" value="{{ c[0] }}" {% if filters.coin_from==c[0] %} selected{% endif %} data-image="/static/images/coins/{{ c[1]|replace(" ", "-") }}.png">{{ c[1] }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button id="coin_from_button" class="bg-gray-50 text-gray-900 appearance-none w-10 dark:bg-gray-500 dark:text-white border-l border-t border-b border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-l-lg flex items-center" disabled></button>
|
||||
<div class="relative">
|
||||
{{ input_arrow_down_svg | safe }}
|
||||
<select name="coin_from" id="coin_from" class="bg-gray-50 text-gray-900 appearance-none pr-10 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-none rounded-r-lg outline-none block w-full p-2.5 focus:ring-0">
|
||||
<option value="any" {% if filters.coin_from==-1 %} selected{% endif %}>Filter {% if sent_offers %}Receiving{% else %}Offers{% endif %}</option>
|
||||
{% for c in coins %}
|
||||
<option class="text-sm" value="{{ c[0] }}" {% if filters.coin_from==c[0] %} selected{% endif %} data-image="/static/images/coins/{{ c[1]|replace(" ", "-") }}.png">{{ c[1] }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="md:w-auto p-1.5 hover-container">
|
||||
<div class="flex">
|
||||
|
||||
<button id="coin_from_button" class="bg-gray-50 text-gray-900 appearance-none w-10 dark:bg-gray-500 dark:text-white border-l border-t border-b border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-l-lg flex items-center" disabled></button>
|
||||
<div class="relative">
|
||||
{{ input_arrow_down_svg | safe }}
|
||||
<select name="coin_from" id="coin_from" class="bg-gray-50 text-gray-900 appearance-none pr-10 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-none rounded-r-lg outline-none block w-full p-2.5 focus:ring-0">
|
||||
<option value="any" {% if filters.coin_from==-1 %} selected{% endif %}>Filter {% if sent_offers %}Sending{% else %}Bids{% endif %}</option>
|
||||
{% for c in coins %}
|
||||
<option class="text-sm" value="{{ c[0] }}" {% if filters.coin_from==c[0] %} selected{% endif %} data-image="/static/images/coins/{{ c[1]|replace(" ", "-") }}.png">{{ c[1] }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<div class="w-full md:w-auto p-1.5">
|
||||
<p class="text-sm font-heading">{{ arrow_right_svg | safe }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button id="coin_to_button" class="bg-gray-50 text-gray-900 appearance-none w-10 dark:bg-gray-500 dark:text-white border-l border-t border-b border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-l-lg flex items-center" disabled></button>
|
||||
<div class="relative">
|
||||
{{ input_arrow_down_svg | safe }}
|
||||
<select name="coin_to" id="coin_to" class="bg-gray-50 text-gray-900 appearance-none pr-10 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-none rounded-r-lg outline-none block w-full p-2.5 focus:ring-0">
|
||||
<option value="any" {% if filters.coin_to==-1 %} selected{% endif %}>Filter {% if sent_offers %}Receiving{% else %}Offers{% endif %}</option>
|
||||
{% for c in coins_from %}
|
||||
<option class="text-sm" value="{{ c[0] }}" {% if filters.coin_to==c[0] %} selected{% endif %} data-image="/static/images/coins/{{ c[1]|replace(" ", "-") }}.png">{{ c[1] }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="w-full md:w-auto mt-3">
|
||||
<div class="w-full md:w-auto p-1.5">
|
||||
<p class="text-sm font-heading bold">Sort By:</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full md:w-auto p-1.5">
|
||||
<div class="relative">
|
||||
{{ input_arrow_down_svg | safe }}
|
||||
<select name="sort_by" id="sort_by" class="hover:border-blue-500 bg-gray-50 text-gray-900 appearance-none pr-10 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 focus:ring-0">
|
||||
<option value="created_at" {% if filters.sort_by=='created_at' %} selected{% endif %}>Time Created</option>
|
||||
<option value="rate" {% if filters.sort_by=='rate' %} selected{% endif %}>Rate</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full md:w-auto p-1.5">
|
||||
<div class="relative">
|
||||
{{ input_arrow_down_svg | safe }}
|
||||
<select name="sort_dir" id="sort_dir" class="hover:border-blue-500 bg-gray-50 text-gray-900 appearance-none pr-10 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 focus:ring-0">
|
||||
<option value="desc" {% if filters.sort_dir=='desc' %} selected{% endif %}>Descending</option>
|
||||
<option value="asc" {% if filters.sort_dir=='asc' %} selected{% endif %}>Ascending</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center hidden">
|
||||
<div class="w-full md:w-auto p-1.5">
|
||||
<p class="text-sm font-heading bold">Sent From Node:</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full md:w-auto p-1.5 hidden">
|
||||
<div class="relative">
|
||||
{{ input_arrow_down_svg | safe }}
|
||||
<select name="sent_from" class="hover:border-blue-500 bg-gray-50 text-gray-900 appearance-none pr-10 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 focus:ring-0">
|
||||
<option value="any" {% if filters.sent_from=='any' %} selected{% endif %}>Any</option>
|
||||
<option value="only" {% if filters.sent_from=='only' %} selected{% endif %}>Only</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{% if sent_offers %}
|
||||
<div class="flex items-center">
|
||||
<div class="w-full md:w-auto p-1.5">
|
||||
<p class="text-sm font-heading bold">State:</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full md:w-auto p-1.5">
|
||||
<div class="relative">
|
||||
{{ input_arrow_down_svg | safe }}
|
||||
<select name="active" class="hover:border-blue-500 bg-gray-50 text-gray-900 appearance-none pr-10 border border-gray-200 dark:border-gray-400 dark:text-gray-50 dark:bg-gray-500 dark:text-white dark:placeholder-gray-50 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 focus:ring-0">
|
||||
<option value="any" {% if filters.active=='any' %} selected{% endif %}>Any</option>
|
||||
<option value="active" {% if filters.active=='active' %} selected{% endif %}>Active</option>
|
||||
<option value="expired" {% if filters.active=='expired' %} selected{% endif %}>Expired</option>
|
||||
<!-- todo <option value="revoked" {% if filters.active=='revoked' %} selected{% endif %}>Revoked</option>!-->
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="w-full md:w-auto p-1.5">
|
||||
</div>
|
||||
<div class="w-full md:w-auto ml-5">
|
||||
<div class="relative">
|
||||
<button type="button" id="clearFilters" class="flex flex-wrap justify-center w-full px-4 py-2.5 font-medium text-sm hover:text-white dark:text-white dark:bg-gray-500 bg-coolGray-200 hover:bg-green-600 hover:border-green-600 rounded-lg transition duration-200 border border-coolGray-200 dark:border-gray-400 rounded-md shadow-button focus:ring-0 focus:outline-none">
|
||||
<span>Clear Filters</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full md:w-auto hidden p-1.5">
|
||||
<div class="relative">
|
||||
<button type="submit" id="applyFilters" class="flex flex-wrap justify-center w-full px-4 py-2.5 font-medium text-sm text-white bg-blue-600 hover:bg-green-600 hover:border-green-600 rounded-lg transition duration-200 border border-blue-500 rounded-md shadow-button focus:ring-0 focus:outline-none">
|
||||
{{ filter_apply_svg | safe }}
|
||||
<span>Apply Filters</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full md:w-auto p-1.5">
|
||||
<div class="w-full md:w-auto ml-5">
|
||||
<div class="relative">
|
||||
<button type="button" id="refreshOffers" class="flex flex-wrap justify-center w-full px-4 py-2.5 font-medium text-sm text-white bg-blue-600 hover:bg-green-600 hover:border-green-600 rounded-lg transition duration-200 border border-blue-500 rounded-md shadow-button focus:ring-0 focus:outline-none">
|
||||
<svg id="refreshIcon" class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
|
@ -351,7 +256,7 @@ function getAPIKeys() {
|
|||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full md:w-auto p-1.5">
|
||||
<div class="w-full md:w-auto ml-5">
|
||||
<div class="relative">
|
||||
<button id="toggleView" class="hidden flex flex-wrap justify-center w-full px-4 py-2.5 font-medium text-sm text-white bg-blue-600 hover:bg-green-600 hover:border-green-600 rounded-lg transition duration-200 border border-blue-500 rounded-md shadow-button focus:ring-0 focus:outline-none">
|
||||
<span>Toggle JSON View</span>
|
||||
|
@ -368,9 +273,7 @@ function getAPIKeys() {
|
|||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
<div id="jsonView" class="hidden mb-4">
|
||||
<pre id="jsonContent" class="bg-gray-100 p-4 rounded overflow-auto" style="max-height: 300px;"></pre>
|
||||
|
@ -392,21 +295,37 @@ function getAPIKeys() {
|
|||
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold">Details</span>
|
||||
</div>
|
||||
</th>
|
||||
{% if sent_offers %}
|
||||
<th class="p-0">
|
||||
<div class="py-3 px-4 bg-coolGray-200 dark:bg-gray-600 text-left">
|
||||
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold">Max send</span>
|
||||
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold">Max Recv</span>
|
||||
</div>
|
||||
</th>
|
||||
{% else %}
|
||||
<th class="p-0">
|
||||
<div class="py-3 px-4 bg-coolGray-200 dark:bg-gray-600 text-left">
|
||||
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold">Max Send</span>
|
||||
</div>
|
||||
</th>
|
||||
{% endif %}
|
||||
<th class="p-0">
|
||||
<div class="py-3 px-4 bg-coolGray-200 dark:bg-gray-600 text-center">
|
||||
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold">Swap</span>
|
||||
</div>
|
||||
</th>
|
||||
{% if sent_offers %}
|
||||
<th class="p-0">
|
||||
<div class="py-3 px-4 bg-coolGray-200 dark:bg-gray-600 text-right">
|
||||
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold pr-2">Your Liq.</span>
|
||||
</div>
|
||||
</th>
|
||||
{% else %}
|
||||
<th class="p-0">
|
||||
<div class="py-3 px-4 bg-coolGray-200 dark:bg-gray-600 text-right">
|
||||
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold pr-2">Max Recv</span>
|
||||
</div>
|
||||
</th>
|
||||
{% endif %}
|
||||
<th class="p-0" data-sortable="true" data-column-index="5">
|
||||
<div class="py-3 px-4 bg-coolGray-200 dark:bg-gray-600 text-right flex items-center justify-end">
|
||||
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold">Rate</span>
|
||||
|
|
Loading…
Reference in a new issue