mirror of
https://github.com/basicswap/basicswap.git
synced 2025-05-03 19:32:37 +00:00
Merge pull request #265 from nahuhh/offertweaks
bids/offers: responsive and styling tweaks
This commit is contained in:
commit
fcdb2e7dfe
5 changed files with 132 additions and 127 deletions
basicswap
|
@ -189,7 +189,7 @@ const formatAddress = (address, displayLength = 15) => {
|
||||||
const getTimeStrokeColor = (expireTime) => {
|
const getTimeStrokeColor = (expireTime) => {
|
||||||
const now = Math.floor(Date.now() / 1000);
|
const now = Math.floor(Date.now() / 1000);
|
||||||
const timeLeft = expireTime - now;
|
const timeLeft = expireTime - now;
|
||||||
|
|
||||||
if (timeLeft <= 300) return '#9CA3AF'; // 5 minutes or less
|
if (timeLeft <= 300) return '#9CA3AF'; // 5 minutes or less
|
||||||
if (timeLeft <= 1800) return '#3B82F6'; // 30 minutes or less
|
if (timeLeft <= 1800) return '#3B82F6'; // 30 minutes or less
|
||||||
return '#10B981'; // More than 30 minutes
|
return '#10B981'; // More than 30 minutes
|
||||||
|
@ -781,7 +781,7 @@ async function updateBidsTable(options = {}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const totalPages = Math.ceil(state.jsonData.length / PAGE_SIZE);
|
const totalPages = Math.ceil(state.jsonData.length / PAGE_SIZE);
|
||||||
|
|
||||||
if (resetPage && state.jsonData.length > 0) {
|
if (resetPage && state.jsonData.length > 0) {
|
||||||
state.currentPage = 1;
|
state.currentPage = 1;
|
||||||
}
|
}
|
||||||
|
@ -861,7 +861,7 @@ if (elements.refreshBidsButton) {
|
||||||
updateLoadingState(true);
|
updateLoadingState(true);
|
||||||
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 500));
|
await new Promise(resolve => setTimeout(resolve, 500));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await updateBidsTable({ resetPage: true, refreshData: true });
|
await updateBidsTable({ resetPage: true, refreshData: true });
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -192,7 +192,13 @@ const safeParseInt = (value) => {
|
||||||
return isNaN(parsed) ? 0 : parsed;
|
return isNaN(parsed) ? 0 : parsed;
|
||||||
};
|
};
|
||||||
|
|
||||||
const formatAddress = (address, displayLength = 15) => {
|
const formatAddress = (address, displayLength = 20) => {
|
||||||
|
if (!address) return '';
|
||||||
|
if (address.length <= displayLength) return address;
|
||||||
|
return `${address.slice(8, displayLength)}...`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatAddressSMSG = (address, displayLength = 14) => {
|
||||||
if (!address) return '';
|
if (!address) return '';
|
||||||
if (address.length <= displayLength) return address;
|
if (address.length <= displayLength) return address;
|
||||||
return `${address.slice(0, displayLength)}...`;
|
return `${address.slice(0, displayLength)}...`;
|
||||||
|
@ -218,17 +224,17 @@ const getTimeStrokeColor = (expireTime) => {
|
||||||
const getStatusClass = (status) => {
|
const getStatusClass = (status) => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 'Completed':
|
case 'Completed':
|
||||||
return 'bg-green-100 text-green-800 dark:bg-green-500 dark:text-white';
|
return 'bg-green-300 text-black dark:bg-green-600 dark:text-white';
|
||||||
case 'Expired':
|
case 'Expired':
|
||||||
return 'bg-gray-100 text-gray-800 dark:bg-gray-400 dark:text-white';
|
return 'bg-gray-200 text-black dark:bg-gray-400 dark:text-white';
|
||||||
case 'Abandoned':
|
case 'Error':
|
||||||
return 'bg-red-100 text-red-800 dark:bg-red-500 dark:text-white';
|
return 'bg-red-300 text-black dark:bg-red-600 dark:text-white';
|
||||||
case 'Failed':
|
case 'Failed':
|
||||||
return 'bg-rose-100 text-rose-800 dark:bg-rose-500 dark:text-white';
|
return 'bg-red-300 text-black dark:bg-red-600 dark:text-white';
|
||||||
case 'Failed, refunded':
|
case 'Failed, refunded':
|
||||||
return 'bg-gray-100 text-orange-800 dark:bg-gray-400 dark:text-red-500';
|
return 'bg-gray-200 text-black dark:bg-gray-400 dark:text-red-500';
|
||||||
default:
|
default:
|
||||||
return 'bg-blue-100 text-blue-800 dark:bg-blue-500 dark:text-white';
|
return 'bg-blue-300 text-black dark:bg-blue-500 dark:text-white';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -274,10 +280,10 @@ function hasActiveFilters() {
|
||||||
const hasNonDefaultCoinTo = coinToSelect && coinToSelect.value !== 'any';
|
const hasNonDefaultCoinTo = coinToSelect && coinToSelect.value !== 'any';
|
||||||
const hasNonDefaultExpired = withExpiredSelect && withExpiredSelect.value !== 'true';
|
const hasNonDefaultExpired = withExpiredSelect && withExpiredSelect.value !== 'true';
|
||||||
|
|
||||||
return hasNonDefaultState ||
|
return hasNonDefaultState ||
|
||||||
hasSearchQuery ||
|
hasSearchQuery ||
|
||||||
hasNonDefaultCoinFrom ||
|
hasNonDefaultCoinFrom ||
|
||||||
hasNonDefaultCoinTo ||
|
hasNonDefaultCoinTo ||
|
||||||
hasNonDefaultExpired;
|
hasNonDefaultExpired;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,7 +311,7 @@ function filterAndSortData(bids) {
|
||||||
const coinFromSelect = document.getElementById('coin_from');
|
const coinFromSelect = document.getElementById('coin_from');
|
||||||
const selectedOption = coinFromSelect?.querySelector(`option[value="${state.filters.coin_from}"]`);
|
const selectedOption = coinFromSelect?.querySelector(`option[value="${state.filters.coin_from}"]`);
|
||||||
const coinName = selectedOption?.textContent.trim();
|
const coinName = selectedOption?.textContent.trim();
|
||||||
|
|
||||||
if (coinName) {
|
if (coinName) {
|
||||||
const coinToMatch = state.currentTab === 'sent' ? bid.coin_from : bid.coin_to;
|
const coinToMatch = state.currentTab === 'sent' ? bid.coin_from : bid.coin_to;
|
||||||
if (!coinMatches(coinToMatch, coinName)) {
|
if (!coinMatches(coinToMatch, coinName)) {
|
||||||
|
@ -318,7 +324,7 @@ function filterAndSortData(bids) {
|
||||||
const coinToSelect = document.getElementById('coin_to');
|
const coinToSelect = document.getElementById('coin_to');
|
||||||
const selectedOption = coinToSelect?.querySelector(`option[value="${state.filters.coin_to}"]`);
|
const selectedOption = coinToSelect?.querySelector(`option[value="${state.filters.coin_to}"]`);
|
||||||
const coinName = selectedOption?.textContent.trim();
|
const coinName = selectedOption?.textContent.trim();
|
||||||
|
|
||||||
if (coinName) {
|
if (coinName) {
|
||||||
const coinToMatch = state.currentTab === 'sent' ? bid.coin_to : bid.coin_from;
|
const coinToMatch = state.currentTab === 'sent' ? bid.coin_to : bid.coin_from;
|
||||||
if (!coinMatches(coinToMatch, coinName)) {
|
if (!coinMatches(coinToMatch, coinName)) {
|
||||||
|
@ -334,7 +340,7 @@ function filterAndSortData(bids) {
|
||||||
const identity = IdentityManager.cache.get(bid.addr_from);
|
const identity = IdentityManager.cache.get(bid.addr_from);
|
||||||
const label = identity?.data?.label || '';
|
const label = identity?.data?.label || '';
|
||||||
const matchesLabel = label.toLowerCase().includes(searchStr);
|
const matchesLabel = label.toLowerCase().includes(searchStr);
|
||||||
|
|
||||||
if (!(matchesBidId || matchesIdentity || matchesLabel)) {
|
if (!(matchesBidId || matchesIdentity || matchesLabel)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -358,10 +364,10 @@ function updateCoinFilterImages() {
|
||||||
|
|
||||||
function updateButtonImage(select, button) {
|
function updateButtonImage(select, button) {
|
||||||
if (!select || !button) return;
|
if (!select || !button) return;
|
||||||
|
|
||||||
const selectedOption = select.options[select.selectedIndex];
|
const selectedOption = select.options[select.selectedIndex];
|
||||||
const imagePath = selectedOption.getAttribute('data-image');
|
const imagePath = selectedOption.getAttribute('data-image');
|
||||||
|
|
||||||
if (imagePath && select.value !== 'any') {
|
if (imagePath && select.value !== 'any') {
|
||||||
button.style.backgroundImage = `url(${imagePath})`;
|
button.style.backgroundImage = `url(${imagePath})`;
|
||||||
button.style.backgroundSize = '25px';
|
button.style.backgroundSize = '25px';
|
||||||
|
@ -385,7 +391,7 @@ const updateLoadingState = (isLoading) => {
|
||||||
const refreshButton = elements[`refresh${type}Bids`];
|
const refreshButton = elements[`refresh${type}Bids`];
|
||||||
const refreshText = refreshButton?.querySelector(`#refresh${type}Text`);
|
const refreshText = refreshButton?.querySelector(`#refresh${type}Text`);
|
||||||
const refreshIcon = refreshButton?.querySelector('svg');
|
const refreshIcon = refreshButton?.querySelector('svg');
|
||||||
|
|
||||||
if (refreshButton) {
|
if (refreshButton) {
|
||||||
refreshButton.disabled = isLoading;
|
refreshButton.disabled = isLoading;
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
|
@ -431,7 +437,7 @@ const updateConnectionStatus = (status) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const config = statusConfig[status] || statusConfig.connected;
|
const config = statusConfig[status] || statusConfig.connected;
|
||||||
|
|
||||||
['sent', 'received'].forEach(type => {
|
['sent', 'received'].forEach(type => {
|
||||||
const dot = elements[`statusDot${type.charAt(0).toUpperCase() + type.slice(1)}`];
|
const dot = elements[`statusDot${type.charAt(0).toUpperCase() + type.slice(1)}`];
|
||||||
const text = elements[`statusText${type.charAt(0).toUpperCase() + type.slice(1)}`];
|
const text = elements[`statusText${type.charAt(0).toUpperCase() + type.slice(1)}`];
|
||||||
|
@ -613,12 +619,12 @@ const createTableRow = async (bid) => {
|
||||||
const identity = await IdentityManager.getIdentityData(bid.addr_from);
|
const identity = await IdentityManager.getIdentityData(bid.addr_from);
|
||||||
const uniqueId = `${bid.bid_id}_${Date.now()}`;
|
const uniqueId = `${bid.bid_id}_${Date.now()}`;
|
||||||
const timeColor = getTimeStrokeColor(bid.expire_at);
|
const timeColor = getTimeStrokeColor(bid.expire_at);
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
||||||
<!-- Time Column -->
|
<!-- Time Column -->
|
||||||
<td class="py-3 px-6">
|
<td class="py-3 pl-6 pr-3">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center min-w-max">
|
||||||
<svg class="w-5 h-5 mr-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 mr-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||||
<g stroke-linecap="round" stroke-width="2" fill="none" stroke="${timeColor}" stroke-linejoin="round">
|
<g stroke-linecap="round" stroke-width="2" fill="none" stroke="${timeColor}" stroke-linejoin="round">
|
||||||
<circle cx="12" cy="12" r="11"></circle>
|
<circle cx="12" cy="12" r="11"></circle>
|
||||||
|
@ -629,58 +635,59 @@ const createTableRow = async (bid) => {
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
|
||||||
<!-- Details Column -->
|
<!-- Details Column -->
|
||||||
<td class="py-3 px-6">
|
<td class="p-3 hidden lg:flex">
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center min-w-max">
|
||||||
<span class="text-xs font-medium mr-2">${state.currentTab === 'sent' ? 'Out' : 'In'}</span>
|
|
||||||
<div class="relative" data-tooltip-target="tooltip-identity-${uniqueId}">
|
<div class="relative" data-tooltip-target="tooltip-identity-${uniqueId}">
|
||||||
<a href="/identity/${bid.addr_from}" class="text-xs">
|
<a href="/identity/${bid.addr_from}" class="text-xs font-mono">
|
||||||
${identity?.label || formatAddress(bid.addr_from)}
|
<span class="mr-2">
|
||||||
|
${state.currentTab === 'sent' ? 'Out' : 'In'}
|
||||||
|
</span>
|
||||||
|
${identity?.label || formatAddressSMSG(bid.addr_from)}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-xs opacity-75">
|
<div class="font-mono text-xs opacity-75">
|
||||||
<a href="/bid/${bid.bid_id}">
|
<a href="/offer/${bid.offer_id}">
|
||||||
Bid: ${formatAddress(bid.bid_id)}
|
Offer: ${formatAddress(bid.offer_id)}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<!-- Send Coin Column -->
|
<!-- Send Coin Column -->
|
||||||
<td class="py-3 px-6">
|
<td class="p-3">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center min-w-max">
|
||||||
<img class="w-6 h-6 mr-2"
|
<img class="w-8 h-8 mr-2"
|
||||||
src="/static/images/coins/${bid.coin_from.replace(' ', '-')}.png"
|
src="/static/images/coins/${state.currentTab === 'sent' ? bid.coin_to.replace(' ', '-') : bid.coin_from.replace(' ', '-')}.png"
|
||||||
alt="${bid.coin_from}"
|
alt="${state.currentTab === 'sent' ? bid.coin_to : bid.coin_from}"
|
||||||
onerror="this.src='/static/images/coins/default.png'">
|
onerror="this.src='/static/images/coins/default.png'">
|
||||||
<div>
|
<div>
|
||||||
<div class="text-sm font-medium monospace">${bid.amount_from}</div>
|
<div class="text-sm font-medium monospace">${state.currentTab === 'sent' ? bid.amount_to : bid.amount_from}</div>
|
||||||
<div class="text-xs opacity-75 monospace">${bid.coin_from}</div>
|
<div class="text-xs opacity-75 monospace">${state.currentTab === 'sent' ? bid.coin_to : bid.coin_from}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<!-- Receive Coin Column -->
|
<!-- Receive Coin Column -->
|
||||||
<td class="py-3 px-6">
|
<td class="p-3">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center min-w-max">
|
||||||
<img class="w-6 h-6 mr-2"
|
<img class="w-8 h-8 mr-2"
|
||||||
src="/static/images/coins/${bid.coin_to.replace(' ', '-')}.png"
|
src="/static/images/coins/${state.currentTab === 'sent' ? bid.coin_from.replace(' ', '-') : bid.coin_to.replace(' ', '-')}.png"
|
||||||
alt="${bid.coin_to}"
|
alt="${state.currentTab === 'sent' ? bid.coin_from : bid.coin_to}"
|
||||||
onerror="this.src='/static/images/coins/default.png'">
|
onerror="this.src='/static/images/coins/default.png'">
|
||||||
<div>
|
<div>
|
||||||
<div class="text-sm font-medium monospace">${bid.amount_to}</div>
|
<div class="text-sm font-medium monospace">${state.currentTab === 'sent' ? bid.amount_from : bid.amount_to}</div>
|
||||||
<div class="text-xs opacity-75 monospace">${bid.coin_to}</div>
|
<div class="text-xs opacity-75 monospace">${state.currentTab === 'sent' ? bid.coin_from : bid.coin_to}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<!-- Status Column -->
|
<!-- Status Column -->
|
||||||
<td class="py-3 px-6">
|
<td class="p-3">
|
||||||
<div class="relative" data-tooltip-target="tooltip-status-${uniqueId}">
|
<div class="flex justify-center" data-tooltip-target="tooltip-status-${uniqueId}">
|
||||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium
|
<span class="w-full xl:w-4/5 flex bold justify-center items-center px-2.5 py-1 rounded-full text-xs font-medium
|
||||||
${getStatusClass(bid.bid_state)}">
|
${getStatusClass(bid.bid_state)}">
|
||||||
${bid.bid_state}
|
${bid.bid_state}
|
||||||
</span>
|
</span>
|
||||||
|
@ -688,11 +695,13 @@ const createTableRow = async (bid) => {
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<!-- Actions Column -->
|
<!-- Actions Column -->
|
||||||
<td class="py-3 px-6">
|
<td class="py-3 pr-6 pl-3">
|
||||||
<a href="/bid/${bid.bid_id}"
|
<div class="flex justify-center">
|
||||||
class="inline-block w-24 py-2 px-3 text-center text-sm font-medium text-white bg-blue-500 rounded-lg hover:bg-blue-600 transition-colors">
|
<a href="/bid/${bid.bid_id}"
|
||||||
View Bid
|
class="inline-block w-24 py-2 px-3 text-center text-sm font-medium text-white bg-blue-500 rounded-lg hover:bg-blue-600 transition-colors">
|
||||||
</a>
|
View Bid
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
@ -759,12 +768,12 @@ const updateTableContent = async (type) => {
|
||||||
const initializeTooltips = () => {
|
const initializeTooltips = () => {
|
||||||
if (window.TooltipManager) {
|
if (window.TooltipManager) {
|
||||||
window.TooltipManager.cleanup();
|
window.TooltipManager.cleanup();
|
||||||
|
|
||||||
const tooltipTriggers = document.querySelectorAll('[data-tooltip-target]');
|
const tooltipTriggers = document.querySelectorAll('[data-tooltip-target]');
|
||||||
tooltipTriggers.forEach(trigger => {
|
tooltipTriggers.forEach(trigger => {
|
||||||
const targetId = trigger.getAttribute('data-tooltip-target');
|
const targetId = trigger.getAttribute('data-tooltip-target');
|
||||||
const tooltipContent = document.getElementById(targetId);
|
const tooltipContent = document.getElementById(targetId);
|
||||||
|
|
||||||
if (tooltipContent) {
|
if (tooltipContent) {
|
||||||
window.TooltipManager.create(trigger, tooltipContent.innerHTML, {
|
window.TooltipManager.create(trigger, tooltipContent.innerHTML, {
|
||||||
placement: trigger.getAttribute('data-tooltip-placement') || 'top',
|
placement: trigger.getAttribute('data-tooltip-placement') || 'top',
|
||||||
|
@ -786,7 +795,7 @@ const fetchBids = async () => {
|
||||||
const endpoint = state.currentTab === 'sent' ? '/json/sentbids' : '/json/bids';
|
const endpoint = state.currentTab === 'sent' ? '/json/sentbids' : '/json/bids';
|
||||||
const withExpiredSelect = document.getElementById('with_expired');
|
const withExpiredSelect = document.getElementById('with_expired');
|
||||||
const includeExpired = withExpiredSelect ? withExpiredSelect.value === 'true' : true;
|
const includeExpired = withExpiredSelect ? withExpiredSelect.value === 'true' : true;
|
||||||
|
|
||||||
console.log('Fetching bids, include expired:', includeExpired);
|
console.log('Fetching bids, include expired:', includeExpired);
|
||||||
|
|
||||||
const response = await fetch(endpoint, {
|
const response = await fetch(endpoint, {
|
||||||
|
@ -814,7 +823,7 @@ const fetchBids = async () => {
|
||||||
state.filters.with_expired = includeExpired;
|
state.filters.with_expired = includeExpired;
|
||||||
|
|
||||||
data = filterAndSortData(data);
|
data = filterAndSortData(data);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in fetchBids:', error);
|
console.error('Error in fetchBids:', error);
|
||||||
|
@ -827,18 +836,18 @@ const updateBidsTable = async () => {
|
||||||
console.log('Already loading, skipping update');
|
console.log('Already loading, skipping update');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log('Starting updateBidsTable for tab:', state.currentTab);
|
console.log('Starting updateBidsTable for tab:', state.currentTab);
|
||||||
console.log('Current filters:', state.filters);
|
console.log('Current filters:', state.filters);
|
||||||
|
|
||||||
state.isLoading = true;
|
state.isLoading = true;
|
||||||
updateLoadingState(true);
|
updateLoadingState(true);
|
||||||
|
|
||||||
const bids = await fetchBids();
|
const bids = await fetchBids();
|
||||||
|
|
||||||
console.log('Fetched bids:', bids.length);
|
console.log('Fetched bids:', bids.length);
|
||||||
|
|
||||||
const filteredBids = bids.filter(bid => {
|
const filteredBids = bids.filter(bid => {
|
||||||
// State filter
|
// State filter
|
||||||
if (state.filters.state !== -1) {
|
if (state.filters.state !== -1) {
|
||||||
|
@ -860,7 +869,7 @@ const updateBidsTable = async () => {
|
||||||
const coinFromSelect = document.getElementById('coin_from');
|
const coinFromSelect = document.getElementById('coin_from');
|
||||||
const selectedOption = coinFromSelect?.querySelector(`option[value="${state.filters.coin_from}"]`);
|
const selectedOption = coinFromSelect?.querySelector(`option[value="${state.filters.coin_from}"]`);
|
||||||
const coinName = selectedOption?.textContent.trim();
|
const coinName = selectedOption?.textContent.trim();
|
||||||
|
|
||||||
if (coinName) {
|
if (coinName) {
|
||||||
const coinToMatch = state.currentTab === 'sent' ? bid.coin_from : bid.coin_to;
|
const coinToMatch = state.currentTab === 'sent' ? bid.coin_from : bid.coin_to;
|
||||||
yourCoinMatch = coinMatches(coinToMatch, coinName);
|
yourCoinMatch = coinMatches(coinToMatch, coinName);
|
||||||
|
@ -876,7 +885,7 @@ const updateBidsTable = async () => {
|
||||||
const coinToSelect = document.getElementById('coin_to');
|
const coinToSelect = document.getElementById('coin_to');
|
||||||
const selectedOption = coinToSelect?.querySelector(`option[value="${state.filters.coin_to}"]`);
|
const selectedOption = coinToSelect?.querySelector(`option[value="${state.filters.coin_to}"]`);
|
||||||
const coinName = selectedOption?.textContent.trim();
|
const coinName = selectedOption?.textContent.trim();
|
||||||
|
|
||||||
if (coinName) {
|
if (coinName) {
|
||||||
const coinToMatch = state.currentTab === 'sent' ? bid.coin_to : bid.coin_from;
|
const coinToMatch = state.currentTab === 'sent' ? bid.coin_to : bid.coin_from;
|
||||||
theirCoinMatch = coinMatches(coinToMatch, coinName);
|
theirCoinMatch = coinMatches(coinToMatch, coinName);
|
||||||
|
@ -896,11 +905,11 @@ const updateBidsTable = async () => {
|
||||||
const searchStr = state.filters.searchQuery.toLowerCase();
|
const searchStr = state.filters.searchQuery.toLowerCase();
|
||||||
const matchesBidId = bid.bid_id.toLowerCase().includes(searchStr);
|
const matchesBidId = bid.bid_id.toLowerCase().includes(searchStr);
|
||||||
const matchesIdentity = bid.addr_from?.toLowerCase().includes(searchStr);
|
const matchesIdentity = bid.addr_from?.toLowerCase().includes(searchStr);
|
||||||
|
|
||||||
const identity = IdentityManager.cache.get(bid.addr_from);
|
const identity = IdentityManager.cache.get(bid.addr_from);
|
||||||
const label = identity?.data?.label || '';
|
const label = identity?.data?.label || '';
|
||||||
const matchesLabel = label.toLowerCase().includes(searchStr);
|
const matchesLabel = label.toLowerCase().includes(searchStr);
|
||||||
|
|
||||||
if (!(matchesBidId || matchesIdentity || matchesLabel)) {
|
if (!(matchesBidId || matchesIdentity || matchesLabel)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -981,7 +990,7 @@ function handleSearch(event) {
|
||||||
if (searchTimeout) {
|
if (searchTimeout) {
|
||||||
clearTimeout(searchTimeout);
|
clearTimeout(searchTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
searchTimeout = setTimeout(() => {
|
searchTimeout = setTimeout(() => {
|
||||||
state.filters.searchQuery = event.target.value.toLowerCase();
|
state.filters.searchQuery = event.target.value.toLowerCase();
|
||||||
updateBidsTable();
|
updateBidsTable();
|
||||||
|
@ -1114,7 +1123,7 @@ function setupFilterEventListeners() {
|
||||||
if (searchTimeout) {
|
if (searchTimeout) {
|
||||||
clearTimeout(searchTimeout);
|
clearTimeout(searchTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
searchTimeout = setTimeout(() => {
|
searchTimeout = setTimeout(() => {
|
||||||
state.filters.searchQuery = event.target.value.toLowerCase();
|
state.filters.searchQuery = event.target.value.toLowerCase();
|
||||||
updateBidsTable();
|
updateBidsTable();
|
||||||
|
@ -1178,7 +1187,7 @@ const setupEventListeners = () => {
|
||||||
elements.tabButtons.forEach(tab => {
|
elements.tabButtons.forEach(tab => {
|
||||||
const isSelected = tab.getAttribute('data-tabs-target') === targetId;
|
const isSelected = tab.getAttribute('data-tabs-target') === targetId;
|
||||||
tab.setAttribute('aria-selected', isSelected);
|
tab.setAttribute('aria-selected', isSelected);
|
||||||
|
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
tab.classList.add('bg-gray-100', 'dark:bg-gray-600', 'text-gray-900', 'dark:text-white');
|
tab.classList.add('bg-gray-100', 'dark:bg-gray-600', 'text-gray-900', 'dark:text-white');
|
||||||
tab.classList.remove('hover:text-gray-600', 'hover:bg-gray-50', 'dark:hover:bg-gray-500');
|
tab.classList.remove('hover:text-gray-600', 'hover:bg-gray-50', 'dark:hover:bg-gray-500');
|
||||||
|
@ -1263,7 +1272,7 @@ const setupEventListeners = () => {
|
||||||
const stateValue = parseInt(filterElements.stateSelect.value);
|
const stateValue = parseInt(filterElements.stateSelect.value);
|
||||||
|
|
||||||
state.filters.state = isNaN(stateValue) ? -1 : stateValue;
|
state.filters.state = isNaN(stateValue) ? -1 : stateValue;
|
||||||
|
|
||||||
console.log('State filter changed:', {
|
console.log('State filter changed:', {
|
||||||
selectedValue: filterElements.stateSelect.value,
|
selectedValue: filterElements.stateSelect.value,
|
||||||
parsedState: state.filters.state
|
parsedState: state.filters.state
|
||||||
|
@ -1275,8 +1284,8 @@ const setupEventListeners = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
[
|
[
|
||||||
filterElements.sortBySelect,
|
filterElements.sortBySelect,
|
||||||
filterElements.sortDirSelect,
|
filterElements.sortDirSelect,
|
||||||
filterElements.withExpiredSelect
|
filterElements.withExpiredSelect
|
||||||
].forEach(element => {
|
].forEach(element => {
|
||||||
if (element) {
|
if (element) {
|
||||||
|
@ -1299,7 +1308,7 @@ const setupEventListeners = () => {
|
||||||
document.addEventListener('change', (event) => {
|
document.addEventListener('change', (event) => {
|
||||||
const target = event.target;
|
const target = event.target;
|
||||||
const filterForm = document.querySelector('.flex.flex-wrap.justify-center');
|
const filterForm = document.querySelector('.flex.flex-wrap.justify-center');
|
||||||
|
|
||||||
if (filterForm && filterForm.contains(target)) {
|
if (filterForm && filterForm.contains(target)) {
|
||||||
const formData = {
|
const formData = {
|
||||||
state: filterElements.stateSelect?.value,
|
state: filterElements.stateSelect?.value,
|
||||||
|
@ -1347,7 +1356,7 @@ const setupRefreshButtons = () => {
|
||||||
if (refreshButton) {
|
if (refreshButton) {
|
||||||
refreshButton.addEventListener('click', async () => {
|
refreshButton.addEventListener('click', async () => {
|
||||||
const lowerType = type.toLowerCase();
|
const lowerType = type.toLowerCase();
|
||||||
|
|
||||||
if (state.isRefreshing) {
|
if (state.isRefreshing) {
|
||||||
console.log('Already refreshing, skipping');
|
console.log('Already refreshing, skipping');
|
||||||
return;
|
return;
|
||||||
|
@ -1416,7 +1425,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
|
||||||
WebSocketManager.initialize();
|
WebSocketManager.initialize();
|
||||||
setupEventListeners();
|
setupEventListeners();
|
||||||
setupRefreshButtons();
|
setupRefreshButtons();
|
||||||
setupFilterEventListeners();
|
setupFilterEventListeners();
|
||||||
|
|
||||||
updateClearFiltersButton();
|
updateClearFiltersButton();
|
||||||
|
|
|
@ -200,7 +200,7 @@ const WebSocketManager = {
|
||||||
this.isPageHidden = false;
|
this.isPageHidden = false;
|
||||||
this.lastVisibilityChange = Date.now();
|
this.lastVisibilityChange = Date.now();
|
||||||
this.isIntentionallyClosed = false;
|
this.isIntentionallyClosed = false;
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.priceUpdatePaused = false;
|
this.priceUpdatePaused = false;
|
||||||
if (!this.isConnected()) {
|
if (!this.isConnected()) {
|
||||||
|
@ -848,7 +848,7 @@ function continueInitialization() {
|
||||||
listingLabel.textContent = isSentOffers ? 'Total Listings: ' : 'Network Listings: ';
|
listingLabel.textContent = isSentOffers ? 'Total Listings: ' : 'Network Listings: ';
|
||||||
}
|
}
|
||||||
//console.log('Initialization completed');
|
//console.log('Initialization completed');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function initializeTooltips() {
|
function initializeTooltips() {
|
||||||
|
@ -875,7 +875,7 @@ function filterAndSortData() {
|
||||||
|
|
||||||
localStorage.setItem('offersTableSettings', JSON.stringify({
|
localStorage.setItem('offersTableSettings', JSON.stringify({
|
||||||
coin_to: filters.coin_to,
|
coin_to: filters.coin_to,
|
||||||
coin_from: filters.coin_from,
|
coin_from: filters.coin_from,
|
||||||
status: filters.status,
|
status: filters.status,
|
||||||
sent_from: filters.sent_from,
|
sent_from: filters.sent_from,
|
||||||
sortColumn: currentSortColumn,
|
sortColumn: currentSortColumn,
|
||||||
|
@ -936,7 +936,7 @@ function filterAndSortData() {
|
||||||
const calculateValue = offer => {
|
const calculateValue = offer => {
|
||||||
const fromUSD = parseFloat(offer.amount_from) * getPrice(offer.coin_from);
|
const fromUSD = parseFloat(offer.amount_from) * getPrice(offer.coin_from);
|
||||||
const toUSD = parseFloat(offer.amount_to) * getPrice(offer.coin_to);
|
const toUSD = parseFloat(offer.amount_to) * getPrice(offer.coin_to);
|
||||||
return (isSentOffers || offer.is_own_offer) ?
|
return (isSentOffers || offer.is_own_offer) ?
|
||||||
((toUSD / fromUSD) - 1) * 100 :
|
((toUSD / fromUSD) - 1) * 100 :
|
||||||
((fromUSD / toUSD) - 1) * 100;
|
((fromUSD / toUSD) - 1) * 100;
|
||||||
};
|
};
|
||||||
|
@ -967,7 +967,7 @@ function filterAndSortData() {
|
||||||
return currentSortDirection === 'desc' ? -comparison : comparison;
|
return currentSortDirection === 'desc' ? -comparison : comparison;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return filteredData;
|
return filteredData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1081,7 +1081,7 @@ async function fetchLatestPrices() {
|
||||||
const existingCache = CacheManager.get(PRICES_CACHE_KEY, true);
|
const existingCache = CacheManager.get(PRICES_CACHE_KEY, true);
|
||||||
const fallbackData = existingCache ? existingCache.value : null;
|
const fallbackData = existingCache ? existingCache.value : null;
|
||||||
const url = `${offersConfig.apiEndpoints.coinGecko}/simple/price?ids=bitcoin,bitcoin-cash,dash,dogecoin,decred,litecoin,particl,pivx,monero,zano,wownero,zcoin&vs_currencies=USD,BTC&api_key=${offersConfig.apiKeys.coinGecko}`;
|
const url = `${offersConfig.apiEndpoints.coinGecko}/simple/price?ids=bitcoin,bitcoin-cash,dash,dogecoin,decred,litecoin,particl,pivx,monero,zano,wownero,zcoin&vs_currencies=USD,BTC&api_key=${offersConfig.apiKeys.coinGecko}`;
|
||||||
|
|
||||||
const response = await fetch('/json/readurl', {
|
const response = await fetch('/json/readurl', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -1102,7 +1102,7 @@ async function fetchLatestPrices() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
if (data.Error) {
|
if (data.Error) {
|
||||||
if (fallbackData) {
|
if (fallbackData) {
|
||||||
return fallbackData;
|
return fallbackData;
|
||||||
|
@ -1177,7 +1177,7 @@ async function fetchOffers() {
|
||||||
|
|
||||||
const data = await offersResponse.json();
|
const data = await offersResponse.json();
|
||||||
const processedData = Array.isArray(data) ? data : Object.values(data);
|
const processedData = Array.isArray(data) ? data : Object.values(data);
|
||||||
|
|
||||||
jsonData = formatInitialData(processedData);
|
jsonData = formatInitialData(processedData);
|
||||||
originalJsonData = [...jsonData];
|
originalJsonData = [...jsonData];
|
||||||
|
|
||||||
|
@ -2502,7 +2502,7 @@ if (refreshButton) {
|
||||||
const currentTime = Date.now();
|
const currentTime = Date.now();
|
||||||
const elapsedTime = currentTime - startTime;
|
const elapsedTime = currentTime - startTime;
|
||||||
const remainingTime = Math.ceil((REFRESH_COOLDOWN - elapsedTime) / 1000);
|
const remainingTime = Math.ceil((REFRESH_COOLDOWN - elapsedTime) / 1000);
|
||||||
|
|
||||||
if (remainingTime <= 0) {
|
if (remainingTime <= 0) {
|
||||||
clearInterval(countdownInterval);
|
clearInterval(countdownInterval);
|
||||||
refreshText.textContent = 'Refresh';
|
refreshText.textContent = 'Refresh';
|
||||||
|
@ -2527,7 +2527,7 @@ if (refreshButton) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const cachedPrices = CacheManager.get('prices_coingecko');
|
const cachedPrices = CacheManager.get('prices_coingecko');
|
||||||
let previousPrices = cachedPrices ? cachedPrices.value : null;
|
const previousPrices = cachedPrices ? cachedPrices.value : null;
|
||||||
CacheManager.clear();
|
CacheManager.clear();
|
||||||
window.isManualRefresh = true;
|
window.isManualRefresh = true;
|
||||||
const endpoint = isSentOffers ? '/json/sentoffers' : '/json/offers';
|
const endpoint = isSentOffers ? '/json/sentoffers' : '/json/offers';
|
||||||
|
@ -2660,7 +2660,7 @@ function handleTableSort(columnIndex, header) {
|
||||||
if (window.sortTimeout) {
|
if (window.sortTimeout) {
|
||||||
clearTimeout(window.sortTimeout);
|
clearTimeout(window.sortTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.sortTimeout = setTimeout(() => {
|
window.sortTimeout = setTimeout(() => {
|
||||||
applyFilters();
|
applyFilters();
|
||||||
}, 100);
|
}, 100);
|
||||||
|
@ -2719,7 +2719,7 @@ function loadSavedSettings() {
|
||||||
const saved = localStorage.getItem('offersTableSettings');
|
const saved = localStorage.getItem('offersTableSettings');
|
||||||
if (saved) {
|
if (saved) {
|
||||||
const settings = JSON.parse(saved);
|
const settings = JSON.parse(saved);
|
||||||
|
|
||||||
['coin_to', 'coin_from', 'status', 'sent_from'].forEach(id => {
|
['coin_to', 'coin_from', 'status', 'sent_from'].forEach(id => {
|
||||||
const element = document.getElementById(id);
|
const element = document.getElementById(id);
|
||||||
if (element && settings[id]) element.value = settings[id];
|
if (element && settings[id]) element.value = settings[id];
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
{% include 'header.html' %}
|
{% include 'header.html' %}
|
||||||
{% from 'style.html' import breadcrumb_line_svg, page_back_svg, page_forwards_svg, filter_clear_svg, filter_apply_svg, circular_arrows_svg, input_arrow_down_svg, arrow_right_svg %}
|
{% from 'style.html' import breadcrumb_line_svg, page_back_svg, page_forwards_svg, filter_clear_svg, filter_apply_svg, circular_arrows_svg, input_arrow_down_svg, arrow_right_svg %}
|
||||||
|
|
||||||
<div class="container mx-auto">
|
<div class="xl:container mx-auto">
|
||||||
<section class="py-3 px-4 mt-6">
|
<section class="py-3 px-4 mt-6">
|
||||||
<div class="lg:container mx-auto">
|
<div class="xl:container mx-auto">
|
||||||
<div class="relative py-8 px-8 bg-coolGray-900 dark:bg-blue-500 rounded-md overflow-hidden">
|
<div class="relative py-8 px-8 bg-coolGray-900 dark:bg-blue-500 rounded-md overflow-hidden">
|
||||||
<img class="absolute z-10 left-4 top-4" src="/static/images/elements/dots-red.svg" alt="">
|
<img class="absolute z-10 left-4 top-4" src="/static/images/elements/dots-red.svg" alt="">
|
||||||
<img class="absolute z-10 right-4 bottom-4" src="/static/images/elements/dots-red.svg" alt="">
|
<img class="absolute z-10 right-4 bottom-4" src="/static/images/elements/dots-red.svg" alt="">
|
||||||
|
@ -49,7 +49,10 @@
|
||||||
<div class="flex flex-wrap justify-center -m-1.5">
|
<div class="flex flex-wrap justify-center -m-1.5">
|
||||||
<div class="w-full md:w-auto p-1.5">
|
<div class="w-full md:w-auto p-1.5">
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<input type="text" id="searchInput" name="search" autocomplete="off" placeholder="Search bid ID, offer ID, address or label..." class="hover:border-blue-500 dark:hover:bg-gray-50 text-gray-900 pl-4 pr-10 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-400 text-sm rounded-lg outline-none block w-96 p-2.5 focus:ring-blue-500 focus:border-blue-500 focus:ring-0 dark:focus:bg-gray-500 dark:focus:text-white">
|
<input type="text"
|
||||||
|
id="searchInput"
|
||||||
|
name="search" autocomplete="off" placeholder="Search bid ID, offer ID, address or label..."
|
||||||
|
class="w-full md:w-auto hover:border-blue-500 dark:hover:bg-gray-50 text-gray-900 pl-4 pr-10 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-400 text-sm rounded-lg outline-none block w-96 p-2.5 focus:ring-blue-500 focus:border-blue-500 focus:ring-0 dark:focus:bg-gray-500 dark:focus:text-white">
|
||||||
<div class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
|
<div class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
|
||||||
<svg class="w-5 h-5 text-gray-500 dark:text-gray-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 text-gray-500 dark:text-gray-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
|
||||||
|
@ -162,42 +165,42 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<div id="bidstab">
|
<div id="bidstab">
|
||||||
<div class="rounded-lg px-6" id="sent" role="tabpanel" aria-labelledby="sent-tab">
|
<div class="rounded-lg lg:px-6" id="sent" role="tabpanel" aria-labelledby="sent-tab">
|
||||||
<div id="sent-content">
|
<div id="sent-content">
|
||||||
<div class="lg:container mx-auto lg:px-0 px-6">
|
<div class="xl:container mx-auto lg:px-0">
|
||||||
<div class="pt-0 pb-6 bg-coolGray-100 dark:bg-gray-500 rounded-xl">
|
<div class="pt-0 pb-6 bg-coolGray-100 dark:bg-gray-500 rounded-xl">
|
||||||
<div class="px-0">
|
<div class="px-0">
|
||||||
<div class="w-auto overflow-auto lg:overflow-hidden">
|
<div class="w-auto overflow-auto lg:overflow-hidden">
|
||||||
<table class="w-full min-w-max">
|
<table class="w-full lg:min-w-max">
|
||||||
<thead class="uppercase">
|
<thead class="uppercase">
|
||||||
<tr class="text-left">
|
<tr class="text-left">
|
||||||
<th class="p-0">
|
<th class="p-0">
|
||||||
<div class="py-3 px-6 rounded-tl-xl bg-coolGray-200 dark:bg-gray-600">
|
<div class="py-3 pl-16 rounded-tl-xl bg-coolGray-200 dark:bg-gray-600">
|
||||||
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Date/Time</span>
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Date/Time</span>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th class="p-0">
|
<th class="p-0 hidden lg:block">
|
||||||
<div class="py-3 px-6 bg-coolGray-200 dark:bg-gray-600">
|
<div class="p-3 bg-coolGray-200 dark:bg-gray-600">
|
||||||
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Details</span>
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Details</span>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th class="p-0">
|
<th class="p-0">
|
||||||
<div class="py-3 px-6 bg-coolGray-200 dark:bg-gray-600">
|
<div class="p-3 bg-coolGray-200 dark:bg-gray-600">
|
||||||
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">You Send</span>
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">You Send</span>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th class="p-0">
|
<th class="p-0">
|
||||||
<div class="py-3 px-6 bg-coolGray-200 dark:bg-gray-600">
|
<div class="p-3 bg-coolGray-200 dark:bg-gray-600">
|
||||||
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">You Receive</span>
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">You Receive</span>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th class="p-0">
|
<th class="p-0">
|
||||||
<div class="py-3 px-6 bg-coolGray-200 dark:bg-gray-600">
|
<div class="p-3 text-center bg-coolGray-200 dark:bg-gray-600">
|
||||||
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Status</span>
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Status</span>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th class="p-0">
|
<th class="p-0">
|
||||||
<div class="py-3 px-6 rounded-tr-xl bg-coolGray-200 dark:bg-gray-600">
|
<div class="p-3 pr-6 text-center rounded-tr-xl bg-coolGray-200 dark:bg-gray-600">
|
||||||
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Actions</span>
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Actions</span>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
|
@ -252,42 +255,42 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Received Bids Tab -->
|
<!-- Received Bids Tab -->
|
||||||
<div class="hidden rounded-lg px-6" id="received" role="tabpanel" aria-labelledby="received-tab">
|
<div class="hidden rounded-lg lg:px-6" id="received" role="tabpanel" aria-labelledby="received-tab">
|
||||||
<div id="received-content">
|
<div id="received-content">
|
||||||
<div class="lg:container mx-auto lg:px-0">
|
<div class="xl:container mx-auto lg:px-0">
|
||||||
<div class="pt-0 pb-6 bg-coolGray-100 dark:bg-gray-500 rounded-xl">
|
<div class="pt-0 pb-6 bg-coolGray-100 dark:bg-gray-500 rounded-xl">
|
||||||
<div class="px-0">
|
<div class="px-0">
|
||||||
<div class="w-auto overflow-auto lg:overflow-hidden">
|
<div class="w-auto overflow-auto lg:overflow-hidden">
|
||||||
<table class="w-full min-w-max">
|
<table class="w-full lg:min-w-max">
|
||||||
<thead class="uppercase">
|
<thead class="uppercase">
|
||||||
<tr class="text-left">
|
<tr class="text-left">
|
||||||
<th class="p-0">
|
<th class="p-0">
|
||||||
<div class="py-3 px-6 rounded-tl-xl bg-coolGray-200 dark:bg-gray-600">
|
<div class="p-3 pl-16 rounded-tl-xl bg-coolGray-200 dark:bg-gray-600">
|
||||||
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Date/Time</span>
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Date/Time</span>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th class="p-0">
|
<th class="p-0">
|
||||||
<div class="py-3 px-6 bg-coolGray-200 dark:bg-gray-600">
|
<div class="p-3 bg-coolGray-200 dark:bg-gray-600">
|
||||||
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Details</span>
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Details</span>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th class="p-0">
|
<th class="p-0">
|
||||||
<div class="py-3 px-6 bg-coolGray-200 dark:bg-gray-600">
|
<div class="p-3 bg-coolGray-200 dark:bg-gray-600">
|
||||||
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">You Send</span>
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">You Send</span>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th class="p-0">
|
<th class="p-0">
|
||||||
<div class="py-3 px-6 bg-coolGray-200 dark:bg-gray-600">
|
<div class="p-3 bg-coolGray-200 dark:bg-gray-600">
|
||||||
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">You Receive</span>
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">You Receive</span>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th class="p-0">
|
<th class="p-0">
|
||||||
<div class="py-3 px-6 bg-coolGray-200 dark:bg-gray-600">
|
<div class="p-3 text-center bg-coolGray-200 dark:bg-gray-600">
|
||||||
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Status</span>
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Status</span>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th class="p-0">
|
<th class="p-0">
|
||||||
<div class="py-3 px-6 rounded-tr-xl bg-coolGray-200 dark:bg-gray-600">
|
<div class="p-3 pr-6 text-center rounded-tr-xl bg-coolGray-200 dark:bg-gray-600">
|
||||||
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Actions</span>
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Actions</span>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
|
|
|
@ -137,7 +137,7 @@ function getWebSocketConfig() {
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="py-4 px-3 flex flex-wrap overflow-hidden container-to-blur">
|
<section class="py-4 px-3 flex-wrap overflow-hidden container-to-blur">
|
||||||
<div class="lg:container mx-auto">
|
<div class="lg:container mx-auto">
|
||||||
<div class="flex flex-wrap justify-center lg:justify-start xl:justify-center" id="coin-container">
|
<div class="flex flex-wrap justify-center lg:justify-start xl:justify-center" id="coin-container">
|
||||||
{% set coin_data = {
|
{% set coin_data = {
|
||||||
|
@ -335,37 +335,29 @@ function getWebSocketConfig() {
|
||||||
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold">Details</span>
|
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold">Details</span>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
{% if sent_offers %}
|
|
||||||
<th class="p-0">
|
<th class="p-0">
|
||||||
<div class="py-3 px-4 bg-coolGray-200 dark:bg-gray-600 text-left">
|
<div class="py-3 px-4 bg-coolGray-200 dark:bg-gray-600 text-left">
|
||||||
|
{% if sent_offers %}
|
||||||
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold">Max Recv</span>
|
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold">Max Recv</span>
|
||||||
</div>
|
{% else %}
|
||||||
</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>
|
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold">Max Send</span>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
{% endif %}
|
|
||||||
<th class="p-0">
|
<th class="p-0">
|
||||||
<div class="py-3 px-4 bg-coolGray-200 dark:bg-gray-600 text-center">
|
<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>
|
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold">Swap</span>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
{% if sent_offers %}
|
|
||||||
<th class="p-0">
|
<th class="p-0">
|
||||||
<div class="py-3 px-4 bg-coolGray-200 dark:bg-gray-600 text-right">
|
<div class="py-3 px-4 bg-coolGray-200 dark:bg-gray-600 text-right">
|
||||||
|
{% if sent_offers %}
|
||||||
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold pr-2">Your Liq.</span>
|
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold pr-2">Your Liq.</span>
|
||||||
</div>
|
{% else %}
|
||||||
</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>
|
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold pr-2">Max Recv</span>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
{% endif %}
|
|
||||||
<th class="p-0" data-sortable="true" data-column-index="5">
|
<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">
|
<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>
|
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold">Rate</span>
|
||||||
|
@ -377,6 +369,7 @@ function getWebSocketConfig() {
|
||||||
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold">Market +/-</span>
|
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold">Market +/-</span>
|
||||||
<span class="sort-icon ml-1 text-gray-600 dark:text-gray-400" id="sort-icon-6">↓</span>
|
<span class="sort-icon ml-1 text-gray-600 dark:text-gray-400" id="sort-icon-6">↓</span>
|
||||||
</div>
|
</div>
|
||||||
|
</th>
|
||||||
<th class="p-0">
|
<th class="p-0">
|
||||||
<div class="py-3 px-4 bg-coolGray-200 dark:bg-gray-600 rounded-tr-xl">
|
<div class="py-3 px-4 bg-coolGray-200 dark:bg-gray-600 rounded-tr-xl">
|
||||||
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold">Trade</span>
|
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold">Trade</span>
|
||||||
|
|
Loading…
Reference in a new issue