From a4422dc556f1c13edfd633ea1524ddff7076b6e4 Mon Sep 17 00:00:00 2001 From: rob Date: Mon, 9 Mar 2026 14:57:14 -0300 Subject: [PATCH] Unify dialog styling with consistent gradient headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add .dialog-header CSS class with blue gradient (#3E3AF2 → #6366f1) - Add .dialog-close-btn for consistent close buttons in headers - Update all 12 dialog templates to use unified header styling - Add close buttons to all dialogs (positioned in header) - Fix trade_details and login popups (add proper header structure) - Update public strategy browser modal to match dialog style - Update indicator popup styling to match app theme - Add null checks to initializeResizablePopup for robustness - Update CLAUDE.md with wallet module documentation Co-Authored-By: Claude Opus 4.5 --- CLAUDE.md | 18 +++++ src/static/brighterStyles.css | 85 ++++++++++++++++++++-- src/static/general.js | 14 +++- src/templates/account_settings_dialog.html | 36 +++++---- src/templates/ai_strategy_dialog.html | 9 ++- src/templates/backtest_popup.html | 3 +- src/templates/exchange_config_popup.html | 5 +- src/templates/login.html | 28 +++---- src/templates/new_indicator_popup.html | 3 +- src/templates/new_signal_popup.html | 3 +- src/templates/new_strategy_popup.html | 5 +- src/templates/new_trade_popup.html | 3 +- src/templates/strategies_hud.html | 23 ++++-- src/templates/trade_details_popup.html | 19 ++++- 14 files changed, 192 insertions(+), 62 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index c494940..23c9ac4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -107,6 +107,7 @@ Flask web application with SocketIO for real-time communication, using eventlet | `mapped_strategy.py` | Backtrader strategy integration | | `shared_utilities.py` | Time/date conversion utilities | | `utils.py` | JSON serialization helpers | +| `exchange_validation.py` | Exchange requirements validation with structured error codes | ### EDM Client Module (`src/edm_client/`) @@ -127,6 +128,23 @@ Flask web application with SocketIO for real-time communication, using eventlet | `live_broker.py` | Real exchange trading via ccxt | | `factory.py` | Creates appropriate broker based on mode | +### Wallet Module (`src/wallet/`) + +Bitcoin wallet system for strategy fees with two-address custody model. + +| Module | Purpose | +|--------|---------| +| `wallet_manager.py` | Main wallet operations, credits ledger, fee accumulation/settlement | +| `bitcoin_service.py` | Bitcoin key generation, transaction creation, address validation | +| `encryption.py` | Versioned key encryption for stored private keys | +| `background_jobs.py` | Deposit detection, withdrawal processing, auto-sweep jobs | + +**Key concepts:** +- **Fee Address**: Platform-controlled address for strategy fees (private key stored encrypted) +- **Sweep Address**: User-controlled address for excess funds (we only store public address) +- **Credits Ledger**: Internal balance for instant, reliable strategy fee deduction +- **Balance Cap**: ~$50 limit before auto-sweep to user's sweep address + ### Key Paths - **Source code**: `src/` diff --git a/src/static/brighterStyles.css b/src/static/brighterStyles.css index ca9e43a..7abb73c 100644 --- a/src/static/brighterStyles.css +++ b/src/static/brighterStyles.css @@ -21,6 +21,54 @@ hr{ } /*************** Popup forms *********************/ +/* Unified dialog header */ +.dialog-header { + cursor: move; + padding: 10px; + background: linear-gradient(135deg, #3E3AF2 0%, #6366f1 100%); + color: white; + border-bottom: 1px solid #ccc; + position: relative; + width: inherit; + height: fit-content; +} + +.dialog-header h1 { + margin: 0; + font-size: 18px; + padding-right: 30px; /* Space for close button */ +} + +/* Warning variant (for wallet keys modal) */ +.dialog-header.warning { + background: linear-gradient(135deg, #c00 0%, #e53935 100%); +} + +/* Close button in header - centered vertically */ +.dialog-close-btn { + position: absolute; + right: 10px; + top: 50%; + transform: translateY(-50%); + width: 24px; + height: 24px; + border-radius: 50%; + background: rgba(255,255,255,0.2); + border: none; + color: white; + font-size: 16px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: background 0.2s; + line-height: 1; +} + +.dialog-close-btn:hover { + background: rgba(255,255,255,0.3); +} + /* The popup form */ .form-popup { /* Hidden by default. */ @@ -342,12 +390,37 @@ height: 500px; display: none; position: absolute; left: 100px; top: 50px; - width: 135px; - padding: 10px; - background-color: rgb(200,100,100); - border: solid black 1px; - text-align: justify; font-size: 12px; - z-index:99; + width: 160px; + padding: 12px; + background: linear-gradient(135deg, #3E3AF2 0%, #6366f1 100%); + border: 1px solid #ccc; + border-radius: 8px; + text-align: left; + font-size: 12px; + color: white; + z-index: 99; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); +} + +#indicators label { + color: white; + margin-left: 5px; +} + +#indicators input[type="submit"] { + margin-top: 10px; + width: 100%; + padding: 6px; + border: none; + border-radius: 4px; + background: rgba(255,255,255,0.2); + color: white; + cursor: pointer; + font-size: 12px; +} + +#indicators input[type="submit"]:hover { + background: rgba(255,255,255,0.3); } #enable_indicators{ height:20px; diff --git a/src/static/general.js b/src/static/general.js index 344fecf..2f4e44b 100644 --- a/src/static/general.js +++ b/src/static/general.js @@ -44,6 +44,10 @@ class User_Interface { this.initializeResizablePopup("withdraw_modal", null, "withdraw_header", "resize-withdraw"); this.initializeResizablePopup("credit_modal", null, "credit_header", "resize-credit"); + // Trade details and login popups + this.initializeResizablePopup("trade_details_form", null, "trade_details_header", "resize-trade-details"); + this.initializeResizablePopup("login_popup", null, "login_draggable_header", null); + // Initialize Backtesting's DOM elements this.backtesting.initialize(); } catch (error) { @@ -90,6 +94,10 @@ class User_Interface { */ initializeResizablePopup(popupId, resizeCallback = null, headerId = null, resizerId) { const popupElement = document.getElementById(popupId); + if (!popupElement) { + console.warn(`initializeResizablePopup: Element '${popupId}' not found`); + return; + } this.dragElement(popupElement, headerId); this.makeResizable(popupElement, resizeCallback, resizerId); } @@ -137,10 +145,14 @@ class User_Interface { * Make an element resizable and optionally call a resize callback (like for Blockly workspace). * @param {HTMLElement} elm - The element to make resizable. * @param {function|null} resizeCallback - Optional callback to resize specific content. - * @param {string} resizerId - The ID of the resizer handle element. + * @param {string|null} resizerId - The ID of the resizer handle element, or null to skip resizing. */ makeResizable(elm, resizeCallback = null, resizerId) { + if (!resizerId) return; // Skip if no resizer specified + const resizer = document.getElementById(resizerId); + if (!resizer) return; // Skip if resizer element not found + let originalWidth = 0; let originalHeight = 0; let originalMouseX = 0; diff --git a/src/templates/account_settings_dialog.html b/src/templates/account_settings_dialog.html index 40d693f..64238f6 100644 --- a/src/templates/account_settings_dialog.html +++ b/src/templates/account_settings_dialog.html @@ -2,8 +2,9 @@ - -
X
-