Files
basicswap/basicswap/templates/unlock.html
T
gerlofvanek afae62ae38 Litewallets
2026-01-28 16:05:52 +01:00

254 lines
11 KiB
HTML

{% from 'style.html' import circular_info_messages_svg, green_cross_close_svg, red_cross_close_svg, circular_error_messages_svg %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% if refresh %}
<meta http-equiv="refresh" content="{{ refresh }}">
{% endif %}
<title>(BSX) BasicSwap - v{{ version }}</title>
<link rel="icon" sizes="32x32" type="image/png" href="/static/images/favicon/favicon-32.png">
<link type="text/css" media="all" href="/static/css/libs/flowbite.min.css" rel="stylesheet">
<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>
(function() {
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', 'dark');
}
document.documentElement.classList.toggle('dark', isDarkMode);
})();
</script>
</head>
<body class="bg-gray-50 dark:bg-gray-900 min-h-screen flex items-center justify-center">
<div class="w-full max-w-md px-6">
<div class="bg-white dark:bg-gray-800 rounded-xl dark:shadow-lg p-8">
<div class="text-center mb-8">
<div class="mb-6">
<img src="/static/images/logos/basicswap-logo.svg" class="h-16 mx-auto imageshow dark-image">
<img src="/static/images/logos/basicswap-logo-dark.svg" class="h-16 mx-auto imageshow light-image">
</div>
<h1 class="text-2xl font-bold text-gray-900 dark:text-white mb-2">Unlock BasicSwap</h1>
<p class="text-gray-600 dark:text-gray-400">Enter your password to access your wallets</p>
</div>
{% for m in messages %}
<div class="mb-4 p-4 bg-green-50 border border-green-500 rounded-lg dark:bg-gray-500 dark:text-green-400" role="alert">
<div class="flex items-start">
<div class="flex-shrink-0">
<svg class="w-5 h-5 text-green-600 dark:text-green-400" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd"></path>
</svg>
</div>
<div class="ml-3">
<p class="text-sm font-medium text-green-800 dark:text-green-400">
This will unlock the system for all users!
</p>
</div>
</div>
</div>
{% endfor %}
{% for m in err_messages %}
<div class="mb-4 p-4 bg-red-50 border border-red-400 rounded-lg dark:bg-gray-500 dark:text-red-400" role="alert">
<div class="flex items-start">
<div class="flex-shrink-0">
<svg class="w-5 h-5 text-red-600 dark:text-red-400" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"></path>
</svg>
</div>
<div class="ml-3">
<p class="text-sm font-medium text-red-800 dark:text-red-400">
{{ m[1] }}
</p>
</div>
</div>
</div>
{% endfor %}
<form method="post" autocomplete="off" id="unlock-form">
<div class="mb-6">
<label for="password" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Password
</label>
<div class="relative">
<input
type="password"
id="password"
name="password"
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-400 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 focus:ring-0"
placeholder="Enter your password"
autocomplete="current-password"
required
autofocus
/>
<button
type="button"
id="toggle-password"
class="absolute inset-y-0 right-0 flex items-center pr-3 text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300 transition-colors"
aria-label="Toggle password visibility"
>
<svg id="eye-open" class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
</svg>
<svg id="eye-closed" class="w-5 h-5 hidden" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.878 9.878L3 3m6.878 6.878L21 21"></path>
</svg>
</button>
</div>
<div id="caps-warning" class="hidden mt-2 text-sm text-red-600 dark:text-white flex items-center">
<svg class="w-4 h-4 mr-1" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path>
</svg>
Caps Lock is on
</div>
</div>
<button
type="submit"
name="unlock"
value="Unlock"
id="unlock-btn"
class="w-full bg-blue-600 hover:bg-blue-700 disabled:bg-blue-400 text-white font-medium py-3 px-4 rounded-lg transition-colors focus:outline-none disabled:cursor-not-allowed"
>
<span id="unlock-text">Unlock</span>
<svg id="unlock-spinner" class="hidden animate-spin ml-2 h-5 w-5 text-white inline" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
</button>
<input type="hidden" name="formid" value="{{ form_id }}">
</form>
<div class="mt-8 text-center space-y-2">
<p class="text-sm text-gray-600 dark:text-gray-400">
Need help?
<a href="https://docs.basicswapdex.com/docs/intro/"
target="_blank"
class="text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300 underline">
View tutorials
</a>
</p>
<p class="text-xs text-gray-500 dark:text-gray-500">
{{ title }}
</p>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const passwordInput = document.getElementById('password');
const toggleButton = document.getElementById('toggle-password');
const eyeOpen = document.getElementById('eye-open');
const eyeClosed = document.getElementById('eye-closed');
const capsWarning = document.getElementById('caps-warning');
const unlockForm = document.getElementById('unlock-form');
const unlockBtn = document.getElementById('unlock-btn');
const unlockText = document.getElementById('unlock-text');
const unlockSpinner = document.getElementById('unlock-spinner');
if (toggleButton && passwordInput) {
toggleButton.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
const isPassword = passwordInput.type === 'password';
const cursorPosition = passwordInput.selectionStart;
const inputValue = passwordInput.value;
passwordInput.type = isPassword ? 'text' : 'password';
passwordInput.value = inputValue;
setTimeout(() => {
passwordInput.setSelectionRange(cursorPosition, cursorPosition);
}, 0);
if (isPassword) {
eyeOpen.classList.add('hidden');
eyeClosed.classList.remove('hidden');
} else {
eyeOpen.classList.remove('hidden');
eyeClosed.classList.add('hidden');
}
});
toggleButton.addEventListener('mousedown', function(e) {
e.preventDefault();
});
}
if (passwordInput && capsWarning) {
passwordInput.addEventListener('keydown', function(e) {
const capsLockOn = e.getModifierState && e.getModifierState('CapsLock');
if (capsLockOn) {
capsWarning.classList.remove('hidden');
} else {
capsWarning.classList.add('hidden');
}
});
passwordInput.addEventListener('keyup', function(e) {
const capsLockOn = e.getModifierState && e.getModifierState('CapsLock');
if (!capsLockOn) {
capsWarning.classList.add('hidden');
}
});
}
if (unlockForm) {
unlockForm.addEventListener('submit', function(e) {
if (unlockBtn && unlockText && unlockSpinner) {
unlockBtn.disabled = true;
unlockText.textContent = 'Unlocking...';
unlockSpinner.classList.remove('hidden');
}
});
}
const errorMessages = document.querySelectorAll('[role="alert"]');
if (errorMessages.length > 0 && passwordInput) {
passwordInput.value = '';
passwordInput.focus();
}
if (passwordInput) {
passwordInput.addEventListener('keydown', function(e) {
if (e.key === 'Enter' && unlockForm) {
unlockForm.submit();
}
});
}
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;
});
}
toggleImages();
});
</script>
</body>
</html>