feat: TomSelect ile coin seçici

This commit is contained in:
Mukan Erkin TÖRÜK 2026-04-19 06:45:38 +03:00
parent 0ba182834b
commit 4104d82ef0

View file

@ -4,6 +4,8 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mukan Special Edition</title> <title>Mukan Special Edition</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tom-select@2/dist/css/tom-select.min.css">
<script src="https://cdn.jsdelivr.net/npm/tom-select@2/dist/js/tom-select.complete.min.js"></script>
<style> <style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root { :root {
@ -57,6 +59,12 @@
.auth-box input { background: var(--bg); border: 1px solid var(--border); border-radius: 5px; padding: 9px 12px; color: var(--text); font-size: 14px; width: 100%; } .auth-box input { background: var(--bg); border: 1px solid var(--border); border-radius: 5px; padding: 9px 12px; color: var(--text); font-size: 14px; width: 100%; }
.auth-box input:focus { outline: none; border-color: var(--accent); } .auth-box input:focus { outline: none; border-color: var(--accent); }
.auth-error { color: var(--red); font-size: 12px; display: none; } .auth-error { color: var(--red); font-size: 12px; display: none; }
.ts-wrapper .ts-control { background: var(--bg); border-color: var(--border); color: var(--text); min-height: 32px; padding: 4px 10px; border-radius: 5px; }
.ts-wrapper.focus .ts-control { border-color: var(--accent); box-shadow: none; }
.ts-dropdown { background: var(--surface); border-color: var(--border); color: var(--text); }
.ts-dropdown .option { padding: 7px 12px; }
.ts-dropdown .option.active { background: rgba(108,99,255,0.2); color: var(--text); }
.ts-wrapper .ts-control .item { color: var(--text); background: rgba(108,99,255,0.15); border-radius: 3px; padding: 1px 6px; }
</style> </style>
</head> </head>
<body> <body>
@ -89,11 +97,9 @@
<div class="section-header">Yeni Bot Ekle</div> <div class="section-header">Yeni Bot Ekle</div>
<div class="form-grid"> <div class="form-grid">
<div class="form-group"><label>İsim</label><input id="f-name" placeholder="DOGE Bot" /></div> <div class="form-group"><label>İsim</label><input id="f-name" placeholder="DOGE Bot" /></div>
<div class="form-group" style="position:relative"> <div class="form-group">
<label>Coin (USDT çifti)</label> <label>Coin (USDT çifti)</label>
<input id="f-symbol-search" placeholder="Ara: DOGE, BTC..." autocomplete="off" oninput="filterSymbols(this.value)" onfocus="showDropdown()" onblur="setTimeout(hideDropdown,150)" /> <select id="f-symbol"><option value="">Yükleniyor...</option></select>
<div id="symbol-dropdown" style="display:none;position:absolute;top:100%;left:0;right:0;background:var(--surface);border:1px solid var(--border);border-radius:5px;max-height:200px;overflow-y:auto;z-index:50;"></div>
<input type="hidden" id="f-symbol" />
</div> </div>
<div class="form-group"><label>Timeframe</label> <div class="form-group"><label>Timeframe</label>
<select id="f-timeframe"> <select id="f-timeframe">
@ -141,7 +147,7 @@
<script> <script>
let AUTH_TOKEN = localStorage.getItem('mse_token') || ''; let AUTH_TOKEN = localStorage.getItem('mse_token') || '';
let sseSource = null; let sseSource = null;
let allSymbols = []; // [{symbol, min_notional}] let symbolSelect = null;
function login() { function login() {
const t = document.getElementById('token-input').value.trim(); const t = document.getElementById('token-input').value.trim();
@ -185,46 +191,29 @@ async function loadAll() {
async function loadSymbols() { async function loadSymbols() {
const res = await api('GET', '/symbols'); const res = await api('GET', '/symbols');
allSymbols = await res.json(); const symbols = await res.json();
}
function filterSymbols(query) { symbolSelect = new TomSelect('#f-symbol', {
const q = query.toUpperCase(); valueField: 'symbol',
const matches = q labelField: 'symbol',
? allSymbols.filter(s => s.symbol.startsWith(q) || s.symbol.includes(q)).slice(0, 50) searchField: 'symbol',
: allSymbols.slice(0, 50); options: symbols,
renderDropdown(matches); placeholder: 'Ara: DOGE, BTC...',
showDropdown(); render: {
} option: (data) =>
`<div style="display:flex;justify-content:space-between;align-items:center">
function renderDropdown(items) { <strong>${data.symbol}</strong>
const dd = document.getElementById('symbol-dropdown'); <span style="color:#888;font-size:11px">min ${data.min_notional} USDT</span>
if (!items.length) { dd.innerHTML = '<div style="padding:8px 12px;color:var(--muted)">Bulunamadı</div>'; return; } </div>`,
dd.innerHTML = items.map(s => item: (data) => `<div>${data.symbol}</div>`,
`<div style="padding:7px 12px;cursor:pointer;display:flex;justify-content:space-between;align-items:center" },
onmousedown="selectSymbol('${s.symbol}',${s.min_notional})"> onChange(value) {
<strong>${s.symbol}</strong><span style="color:var(--muted);font-size:11px">min ${s.min_notional} USDT</span> const item = symbols.find(s => s.symbol === value);
</div>` if (!item) return;
).join(''); document.getElementById('f-usdt').value = item.min_notional;
} document.getElementById('f-min-label').textContent = `(min ${item.min_notional} USDT)`;
},
function selectSymbol(symbol, minNotional) { });
document.getElementById('f-symbol').value = symbol;
document.getElementById('f-symbol-search').value = symbol;
document.getElementById('f-usdt').value = minNotional;
document.getElementById('f-min-label').textContent = `(min ${minNotional} USDT)`;
hideDropdown();
}
function showDropdown() {
const dd = document.getElementById('symbol-dropdown');
if (!allSymbols.length) return;
if (!dd.innerHTML) filterSymbols(document.getElementById('f-symbol-search').value);
dd.style.display = 'block';
}
function hideDropdown() {
document.getElementById('symbol-dropdown').style.display = 'none';
} }
async function loadBots() { async function loadBots() {