mirror of
https://github.com/basicswap/basicswap.git
synced 2024-11-17 00:07:56 +00:00
Merge pull request #119 from gerlofvanek/shutdown
ui: Style info/error templates + disable shutdown button when swap is in progress.
This commit is contained in:
commit
4b18ddfe79
4 changed files with 439 additions and 143 deletions
|
@ -1,42 +1,39 @@
|
||||||
|
/* General Styles */
|
||||||
.padded_row td
|
.bold {
|
||||||
{
|
|
||||||
padding-top:1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bold
|
|
||||||
{
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.monospace
|
.monospace {
|
||||||
{
|
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
.floatright
|
.floatright {
|
||||||
{
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 1.25rem;
|
top: 1.25rem;
|
||||||
right: 1.25rem;
|
right: 1.25rem;
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
}
|
}
|
||||||
|
|
||||||
.error_msg
|
/* Table Styles */
|
||||||
{
|
.padded_row td {
|
||||||
|
padding-top: 1.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Modal Styles */
|
||||||
|
.modal-highest {
|
||||||
|
z-index: 9999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Animation */
|
||||||
#hide {
|
#hide {
|
||||||
-moz-animation: cssAnimation 0s ease-in 15s forwards;
|
-moz-animation: cssAnimation 0s ease-in 15s forwards;
|
||||||
/* Firefox */
|
|
||||||
-webkit-animation: cssAnimation 0s ease-in 15s forwards;
|
-webkit-animation: cssAnimation 0s ease-in 15s forwards;
|
||||||
/* Safari and Chrome */
|
|
||||||
-o-animation: cssAnimation 0s ease-in 15s forwards;
|
-o-animation: cssAnimation 0s ease-in 15s forwards;
|
||||||
/* Opera */
|
|
||||||
animation: cssAnimation 0s ease-in 15s forwards;
|
animation: cssAnimation 0s ease-in 15s forwards;
|
||||||
-webkit-animation-fill-mode: forwards;
|
-webkit-animation-fill-mode: forwards;
|
||||||
animation-fill-mode: forwards;
|
animation-fill-mode: forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes cssAnimation {
|
@keyframes cssAnimation {
|
||||||
to {
|
to {
|
||||||
width: 0;
|
width: 0;
|
||||||
|
@ -44,6 +41,7 @@
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@-webkit-keyframes cssAnimation {
|
@-webkit-keyframes cssAnimation {
|
||||||
to {
|
to {
|
||||||
width: 0;
|
width: 0;
|
||||||
|
@ -52,6 +50,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Custom Select Styles */
|
||||||
.custom-select .select {
|
.custom-select .select {
|
||||||
appearance: none;
|
appearance: none;
|
||||||
background-image: url('/static/images/other/coin.png');
|
background-image: url('/static/images/other/coin.png');
|
||||||
|
@ -95,8 +94,9 @@
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Blur and Overlay Styles */
|
||||||
.blurred {
|
.blurred {
|
||||||
filter: blur(4px);
|
filter: blur(3px);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
user-select: auto;
|
user-select: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable opacity on disabled form elements in Chrome */
|
/* Form Element Styles */
|
||||||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||||
select:disabled,
|
select:disabled,
|
||||||
input:disabled,
|
input:disabled,
|
||||||
|
@ -120,6 +120,7 @@
|
||||||
border: 1px solid red !important;
|
border: 1px solid red !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Active Container Styles */
|
||||||
.active-container {
|
.active-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
|
@ -137,6 +138,7 @@
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Center Spin Animation */
|
||||||
.center-spin {
|
.center-spin {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
@ -148,10 +150,11 @@
|
||||||
100% { transform: rotate(360deg); }
|
100% { transform: rotate(360deg); }
|
||||||
}
|
}
|
||||||
|
|
||||||
.hover-container:hover #coin_to_button, .hover-container:hover #coin_to {
|
/* Hover Container Styles */
|
||||||
border-color: #3b82f6;
|
.hover-container:hover #coin_to_button,
|
||||||
}
|
.hover-container:hover #coin_to,
|
||||||
.hover-container:hover #coin_from_button, .hover-container:hover #coin_from {
|
.hover-container:hover #coin_from_button,
|
||||||
|
.hover-container:hover #coin_from {
|
||||||
border-color: #3b82f6;
|
border-color: #3b82f6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,6 +164,7 @@
|
||||||
background-size: 20px 20px;
|
background-size: 20px 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Input-like Container Styles */
|
||||||
.input-like-container {
|
.input-like-container {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
|
@ -172,29 +176,33 @@
|
||||||
line-height: 1.25rem;
|
line-height: 1.25rem;
|
||||||
outline: none;
|
outline: none;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
height: 90px;
|
overflow-wrap: break-word;
|
||||||
color: #374151;
|
|
||||||
border-radius: 0.375rem;
|
|
||||||
font-size: 0.875rem;
|
|
||||||
line-height: 1.25rem;
|
|
||||||
outline: none;
|
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
|
height: auto;
|
||||||
|
min-height: 90px;
|
||||||
|
max-height: 150px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-like-container.dark {
|
||||||
|
background-color: #374151;
|
||||||
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-like-container.copying {
|
.input-like-container.copying {
|
||||||
width: inherit;
|
width: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* QR Code Styles */
|
||||||
.qrcode {
|
.qrcode {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.qrcode-border {
|
.qrcode-border {
|
||||||
|
@ -221,59 +229,52 @@
|
||||||
margin-top: 25px;
|
margin-top: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Disabled Element Styles */
|
||||||
select.select-disabled {
|
select.select-disabled,
|
||||||
opacity: 0.40 !important;
|
.disabled-input-enabled,
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.disabled-input-enabled {
|
|
||||||
opacity: 0.40 !important;
|
|
||||||
}
|
|
||||||
select.disabled-select-enabled {
|
select.disabled-select-enabled {
|
||||||
opacity: 0.40 !important;
|
opacity: 0.40 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Shutdown Modal Styles */
|
||||||
.custom-select .select {
|
#shutdownModal {
|
||||||
appearance: none;
|
z-index: 50;
|
||||||
background-position: 10px center;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
position: relative;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-select select::-webkit-scrollbar {
|
#shutdownModal > div:first-child {
|
||||||
width: 0;
|
z-index: 40;
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-select .select option {
|
#shutdownModal > div:last-child {
|
||||||
padding-left: 0;
|
z-index: 50;
|
||||||
text-indent: 0;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 0 50%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-select .select option.no-space {
|
#shutdownModal > div {
|
||||||
padding-left: 0;
|
transition: opacity 0.3s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-select .select option[data-image] {
|
#shutdownModal.hidden > div {
|
||||||
background-image: url('');
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-select .select-icon {
|
#shutdownModal:not(.hidden) > div {
|
||||||
position: absolute;
|
opacity: 1;
|
||||||
top: 50%;
|
|
||||||
left: 10px;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-select .select-image {
|
.shutdown-button {
|
||||||
display: none;
|
transition: all 0.3s ease;
|
||||||
margin-top: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-select .select:focus+.select-dropdown .select-image {
|
.shutdown-button.shutdown-disabled {
|
||||||
display: block;
|
opacity: 0.6;
|
||||||
|
cursor: not-allowed;
|
||||||
|
color: #a0aec0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shutdown-button.shutdown-disabled:hover {
|
||||||
|
background-color: #4a5568;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shutdown-button.shutdown-disabled svg {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
|
@ -2,12 +2,122 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel=icon sizes="32x32" type="image/png" href="/static/images/favicon-32.png">
|
<link type="text/css" media="all" href="/static/css/libs/flowbite.min.css" rel="stylesheet" />
|
||||||
<title>(BSX) BasicSwap - v{{ version }}</title>
|
<link type="text/css" media="all" href="/static/css/libs/tailwind.min.css" rel="stylesheet">
|
||||||
|
<link type="text/css" media="all" href="/static/css/style.css" rel="stylesheet">
|
||||||
|
<script src="/static/js/main.js"></script>
|
||||||
|
<script src="/static/js/libs/flowbite.js"></script>
|
||||||
|
<script>
|
||||||
|
const isDarkMode =
|
||||||
|
localStorage.getItem('color-theme') === 'dark' ||
|
||||||
|
(!localStorage.getItem('color-theme') &&
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').matches);
|
||||||
|
|
||||||
|
if (!localStorage.getItem('color-theme')) {
|
||||||
|
localStorage.setItem('color-theme', isDarkMode ? 'dark' : 'light');
|
||||||
|
}
|
||||||
|
|
||||||
|
document.documentElement.classList.toggle('dark', isDarkMode);
|
||||||
|
</script>
|
||||||
|
<link rel=icon sizes="32x32" type="image/png" href="/static/images/favicon/favicon-32.png">
|
||||||
|
<title>(BSX) BasicSwap - Info</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body class="dark:bg-gray-700">
|
||||||
<h2>{{ title_str }}</h2>
|
<div class="container px-4 mx-auto">
|
||||||
<p>Info: {{ message_str }}</p>
|
<div class="text-center">
|
||||||
<p><a href="/">home</a></p>
|
<a class="inline-block mb-6" href="#">
|
||||||
|
<img src="/static/images/logos/basicswap-logo.svg" class="h-20 imageshow dark-image">
|
||||||
|
<img src="/static/images/logos/basicswap-logo-dark.svg" class="h-20 imageshow light-image">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="p-6 bg-coolGray-100 dark:bg-gray-800 rounded-lg shadow-md">
|
||||||
|
<h2 class="text-xl font-bold mb-4 text-coolGray-900 dark:text-white">ERROR:</h2>
|
||||||
|
<p class="text-lg text-coolGray-500 dark:text-white mb-6">{{ message_str }}</p>
|
||||||
|
<a href="/" class="inline-block py-2 px-4 bg-blue-500 hover:bg-blue-600 text-white rounded-md transition duration-300">Home</a>
|
||||||
|
</div>
|
||||||
|
<p class="mt-10">
|
||||||
|
<span class="text-xs font-medium dark:text-white">Need help?</span>
|
||||||
|
<a class="inline-block text-xs font-medium text-blue-500 hover:text-blue-600 hover:underline" href="https://academy.particl.io/en/latest/faq/get_support.html" target="_blank">Help / Tutorials</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="text-xs font-medium text-coolGray-500 dark:text-gray-500">{{ title }}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
// Image toggling function
|
||||||
|
function toggleImages() {
|
||||||
|
const html = document.querySelector('html');
|
||||||
|
const darkImages = document.querySelectorAll('.dark-image');
|
||||||
|
const lightImages = document.querySelectorAll('.light-image');
|
||||||
|
|
||||||
|
if (html && html.classList.contains('dark')) {
|
||||||
|
toggleImageDisplay(darkImages, 'block');
|
||||||
|
toggleImageDisplay(lightImages, 'none');
|
||||||
|
} else {
|
||||||
|
toggleImageDisplay(darkImages, 'none');
|
||||||
|
toggleImageDisplay(lightImages, 'block');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleImageDisplay(images, display) {
|
||||||
|
images.forEach(img => {
|
||||||
|
img.style.display = display;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Theme toggle functionality
|
||||||
|
function setTheme(theme) {
|
||||||
|
if (theme === 'light') {
|
||||||
|
document.documentElement.classList.remove('dark');
|
||||||
|
localStorage.setItem('color-theme', 'light');
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.add('dark');
|
||||||
|
localStorage.setItem('color-theme', 'dark');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize theme
|
||||||
|
const themeToggle = document.getElementById('theme-toggle');
|
||||||
|
const themeToggleDarkIcon = document.getElementById('theme-toggle-dark-icon');
|
||||||
|
const themeToggleLightIcon = document.getElementById('theme-toggle-light-icon');
|
||||||
|
|
||||||
|
if (themeToggle && themeToggleDarkIcon && themeToggleLightIcon) {
|
||||||
|
if (localStorage.getItem('color-theme') === 'dark' || (!('color-theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
||||||
|
themeToggleLightIcon.classList.remove('hidden');
|
||||||
|
} else {
|
||||||
|
themeToggleDarkIcon.classList.remove('hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
themeToggle.addEventListener('click', () => {
|
||||||
|
if (localStorage.getItem('color-theme') === 'dark') {
|
||||||
|
setTheme('light');
|
||||||
|
} else {
|
||||||
|
setTheme('dark');
|
||||||
|
}
|
||||||
|
themeToggleDarkIcon.classList.toggle('hidden');
|
||||||
|
themeToggleLightIcon.classList.toggle('hidden');
|
||||||
|
toggleImages();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call toggleImages on load
|
||||||
|
toggleImages();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -85,8 +85,60 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const shutdownButtons = document.querySelectorAll('.shutdown-button');
|
||||||
|
const shutdownModal = document.getElementById('shutdownModal');
|
||||||
|
const closeModalButton = document.getElementById('closeShutdownModal');
|
||||||
|
|
||||||
|
function updateShutdownButtons() {
|
||||||
|
const activeSwaps = parseInt(shutdownButtons[0].getAttribute('data-active-swaps') || '0');
|
||||||
|
|
||||||
|
shutdownButtons.forEach(button => {
|
||||||
|
if (activeSwaps > 0) {
|
||||||
|
button.classList.add('shutdown-disabled');
|
||||||
|
button.setAttribute('data-disabled', 'true');
|
||||||
|
button.setAttribute('title', 'Cannot shutdown while swaps are in progress');
|
||||||
|
} else {
|
||||||
|
button.classList.remove('shutdown-disabled');
|
||||||
|
button.removeAttribute('data-disabled');
|
||||||
|
button.removeAttribute('title');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function showShutdownModal() {
|
||||||
|
shutdownModal.classList.remove('hidden');
|
||||||
|
document.body.style.overflow = 'hidden';
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideShutdownModal() {
|
||||||
|
shutdownModal.classList.add('hidden');
|
||||||
|
document.body.style.overflow = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
shutdownButtons.forEach(button => {
|
||||||
|
button.addEventListener('click', function(e) {
|
||||||
|
if (this.hasAttribute('data-disabled')) {
|
||||||
|
e.preventDefault();
|
||||||
|
showShutdownModal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
closeModalButton.addEventListener('click', hideShutdownModal);
|
||||||
|
|
||||||
|
shutdownModal.addEventListener('click', function(e) {
|
||||||
|
if (e.target === this) {
|
||||||
|
hideShutdownModal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
updateShutdownButtons();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
<link rel=icon sizes="32x32" type="image/png" href="/static/images/favicon/favicon-32.png">
|
<link rel=icon sizes="32x32" type="image/png" href="/static/images/favicon/favicon-32.png">
|
||||||
<title>(BSX) BasicSwap - v{{ version }}</title>
|
<title>(BSX) BasicSwap - v{{ version }}</title>
|
||||||
</head>
|
</head>
|
||||||
|
@ -170,17 +222,37 @@
|
||||||
</li>
|
</li>
|
||||||
{% if debug_mode == true %}
|
{% if debug_mode == true %}
|
||||||
<li>
|
<li>
|
||||||
<a href="/automation" class="flex items-center block py-4 px-4 hover:bg-gray-10 dark:hover:bg-gray-700 dark:text-white"> <span class="sr-only">Automation Strategies</span>
|
<a href="/automation" class="flex items-center block py-4 px-4 hover:bg-gray-100 dark:hover:bg-gray-700 dark:text-white"> <span class="sr-only">Automation Strategies</span>
|
||||||
{{ automation_svg | safe }} Automation Strategies</a>
|
{{ automation_svg | safe }} Automation Strategies</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
<div class="text-sm text-gray-700">
|
<div class="text-sm text-gray-700">
|
||||||
<a href="/shutdown/{{ shutdown_token }}" class="flex items-center block py-4 px-4 hover:bg-gray-100 dark:hover:bg-gray-700 dark:text-white"> <span class="sr-only">Shutdown</span>
|
<a href="/shutdown/{{ shutdown_token }}"
|
||||||
{{ shutdown_svg | safe }} Shutdown </a>
|
class="shutdown-button flex items-center block py-4 px-4 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white"
|
||||||
|
data-active-swaps="{{ summary.num_swapping }}">
|
||||||
|
{{ shutdown_svg | safe }}
|
||||||
|
<span class="ml-2">Shutdown</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="shutdownModal" tabindex="-1" class="hidden fixed inset-0 z-50 overflow-y-auto overflow-x-hidden">
|
||||||
|
<div class="fixed inset-0 bg-black bg-opacity-50 transition-opacity"></div>
|
||||||
|
<div class="flex items-center justify-center min-h-screen p-4 relative z-10">
|
||||||
|
<div class="bg-white dark:bg-gray-500 rounded-lg shadow-xl max-w-md w-full">
|
||||||
|
<div class="p-6 text-center">
|
||||||
|
<svg class="mx-auto mb-4 text-gray-400 w-12 h-12 dark:text-gray-200" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
|
||||||
|
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 11V6m0 8h.01M19 10a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/>
|
||||||
|
</svg>
|
||||||
|
<h3 class="mb-5 text-lg font-normal text-gray-300 dark:text-gray-400">Cannot Shutdown</h3>
|
||||||
|
<p class="mb-5 text-sm text-gray-500 dark:text-gray-300">Shutdown is not possible while swaps are in progress. Please wait for all swaps to complete before shutting down.</p>
|
||||||
|
<button id="closeShutdownModal" type="button" class="text-white bg-red-600 hover:bg-red-800 focus:ring-0 focus:outline-none focus:ring-red-300 dark:focus:ring-red-800 font-medium rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-center">
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- dropdown settings & tools -->
|
<!-- dropdown settings & tools -->
|
||||||
|
|
||||||
<!-- notifications -->
|
<!-- notifications -->
|
||||||
|
@ -507,9 +579,12 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
<div class="pt-8 text-sm font-medium">
|
<div class="pt-8 text-sm font-medium">
|
||||||
<a class="flex items-center pl-3 py-3 pr-4 text-gray-50 hover:bg-gray-900 rounded" href="/shutdown/{{ shutdown_token }}"> <span class="inline-block mr-3">
|
<a href="/shutdown/{{ shutdown_token }}"
|
||||||
|
class="shutdown-button flex items-center block py-4 px-4 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white"
|
||||||
|
data-active-swaps="{{ summary.num_swapping }}">
|
||||||
{{ shutdown_svg | safe }}
|
{{ shutdown_svg | safe }}
|
||||||
</span><span>Shutdown</span></a>
|
<span class="ml-2">Shutdown</span>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
@ -2,12 +2,122 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel=icon sizes="32x32" type="image/png" href="/static/images/favicon-32.png">
|
<link type="text/css" media="all" href="/static/css/libs/flowbite.min.css" rel="stylesheet" />
|
||||||
<title>(BSX) BasicSwap - v{{ version }}</title>
|
<link type="text/css" media="all" href="/static/css/libs/tailwind.min.css" rel="stylesheet">
|
||||||
|
<link type="text/css" media="all" href="/static/css/style.css" rel="stylesheet">
|
||||||
|
<script src="/static/js/main.js"></script>
|
||||||
|
<script src="/static/js/libs/flowbite.js"></script>
|
||||||
|
<script>
|
||||||
|
const isDarkMode =
|
||||||
|
localStorage.getItem('color-theme') === 'dark' ||
|
||||||
|
(!localStorage.getItem('color-theme') &&
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').matches);
|
||||||
|
|
||||||
|
if (!localStorage.getItem('color-theme')) {
|
||||||
|
localStorage.setItem('color-theme', isDarkMode ? 'dark' : 'light');
|
||||||
|
}
|
||||||
|
|
||||||
|
document.documentElement.classList.toggle('dark', isDarkMode);
|
||||||
|
</script>
|
||||||
|
<link rel=icon sizes="32x32" type="image/png" href="/static/images/favicon/favicon-32.png">
|
||||||
|
<title>(BSX) BasicSwap - Info</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body class="dark:bg-gray-700">
|
||||||
<h2>{{ title_str }}</h2>
|
<div class="container px-4 mx-auto">
|
||||||
<p>Info: {{ message_str }}</p>
|
<div class="text-center">
|
||||||
<p><a href="/">home</a></p>
|
<a class="inline-block mb-6" href="#">
|
||||||
|
<img src="/static/images/logos/basicswap-logo.svg" class="h-20 imageshow dark-image">
|
||||||
|
<img src="/static/images/logos/basicswap-logo-dark.svg" class="h-20 imageshow light-image">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="p-6 bg-coolGray-100 dark:bg-gray-800 rounded-lg shadow-md">
|
||||||
|
<h2 class="text-xl font-bold mb-4 text-coolGray-900 dark:text-white">INFO:</h2>
|
||||||
|
<p class="text-lg text-coolGray-500 dark:text-white mb-6">{{ message_str }}</p>
|
||||||
|
<a href="/" class="inline-block py-2 px-4 bg-blue-500 hover:bg-blue-600 text-white rounded-md transition duration-300">Home</a>
|
||||||
|
</div>
|
||||||
|
<p class="mt-10">
|
||||||
|
<span class="text-xs font-medium dark:text-white">Need help?</span>
|
||||||
|
<a class="inline-block text-xs font-medium text-blue-500 hover:text-blue-600 hover:underline" href="https://academy.particl.io/en/latest/faq/get_support.html" target="_blank">Help / Tutorials</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="text-xs font-medium text-coolGray-500 dark:text-gray-500">{{ title }}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
// Image toggling function
|
||||||
|
function toggleImages() {
|
||||||
|
const html = document.querySelector('html');
|
||||||
|
const darkImages = document.querySelectorAll('.dark-image');
|
||||||
|
const lightImages = document.querySelectorAll('.light-image');
|
||||||
|
|
||||||
|
if (html && html.classList.contains('dark')) {
|
||||||
|
toggleImageDisplay(darkImages, 'block');
|
||||||
|
toggleImageDisplay(lightImages, 'none');
|
||||||
|
} else {
|
||||||
|
toggleImageDisplay(darkImages, 'none');
|
||||||
|
toggleImageDisplay(lightImages, 'block');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleImageDisplay(images, display) {
|
||||||
|
images.forEach(img => {
|
||||||
|
img.style.display = display;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Theme toggle functionality
|
||||||
|
function setTheme(theme) {
|
||||||
|
if (theme === 'light') {
|
||||||
|
document.documentElement.classList.remove('dark');
|
||||||
|
localStorage.setItem('color-theme', 'light');
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.add('dark');
|
||||||
|
localStorage.setItem('color-theme', 'dark');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize theme
|
||||||
|
const themeToggle = document.getElementById('theme-toggle');
|
||||||
|
const themeToggleDarkIcon = document.getElementById('theme-toggle-dark-icon');
|
||||||
|
const themeToggleLightIcon = document.getElementById('theme-toggle-light-icon');
|
||||||
|
|
||||||
|
if (themeToggle && themeToggleDarkIcon && themeToggleLightIcon) {
|
||||||
|
if (localStorage.getItem('color-theme') === 'dark' || (!('color-theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
||||||
|
themeToggleLightIcon.classList.remove('hidden');
|
||||||
|
} else {
|
||||||
|
themeToggleDarkIcon.classList.remove('hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
themeToggle.addEventListener('click', () => {
|
||||||
|
if (localStorage.getItem('color-theme') === 'dark') {
|
||||||
|
setTheme('light');
|
||||||
|
} else {
|
||||||
|
setTheme('dark');
|
||||||
|
}
|
||||||
|
themeToggleDarkIcon.classList.toggle('hidden');
|
||||||
|
themeToggleLightIcon.classList.toggle('hidden');
|
||||||
|
toggleImages();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call toggleImages on load
|
||||||
|
toggleImages();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
Loading…
Reference in a new issue