mirror of
https://github.com/chrisnov-it/quantumbotx.git
synced 2026-07-28 11:17:44 +00:00
351292c26a
- Streamlined .env.example to include only essential Flask and MT5 configs for production environments - Added .vercel directory to .gitignore for clean Vercel deployments - Enabled internationalization by adding data-i18n attributes to strategy switcher UI elements - Updated MT5 setup guide and roadmap documentation for clarity and current focus This change simplifies configuration for server deployment while enhancing UI accessibility across languages.
191 lines
13 KiB
HTML
191 lines
13 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title data-i18n-key="{% block title_key %}dashboard.title{% endblock %}">{% block title %}Dashboard{% endblock %} - QuantumBotX</title>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
|
|
<!-- Toastify CSS -->
|
|
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/toastify-js/src/toastify.min.css">
|
|
{% block head_extra %}{% endblock %}
|
|
<style id="holiday-styles"></style>
|
|
</head>
|
|
<body class="bg-gray-100 font-sans">
|
|
<!-- Holiday Banner -->
|
|
<div id="holiday-banner" class="hidden bg-gradient-to-r from-blue-500 to-purple-600 text-white py-2 px-4 text-center relative">
|
|
<div class="container mx-auto flex justify-between items-center">
|
|
<div id="holiday-greeting" class="font-medium"></div>
|
|
<div id="holiday-countdown" class="text-sm opacity-90"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex h-screen overflow-hidden">
|
|
<!-- SIDEBAR -->
|
|
<div id="sidebar" class="sidebar bg-white w-64 shadow-lg flex flex-col">
|
|
<div class="p-4 flex items-center border-b">
|
|
<div class="w-10 h-10 rounded-full bg-blue-600 flex items-center justify-center text-white font-bold">QT</div>
|
|
<div class="ml-3 logo-text">
|
|
<h1 class="text-xl font-bold text-gray-800">QuantumBotX</h1>
|
|
<p class="text-xs text-gray-500">The AI-Powered Strategy Platform</p>
|
|
</div>
|
|
</div>
|
|
<div class="flex-1 overflow-y-auto">
|
|
<nav class="mt-6">
|
|
<div class="px-4 mb-4"><p class="text-xs font-semibold text-gray-500 uppercase tracking-wider sidebar-text" data-i18n="nav.section.navigation">Navigation</p></div>
|
|
<a href="/" class="nav-item flex items-center px-4 py-3 text-gray-600 hover:text-blue-600 hover:bg-blue-50 {% if active_page == 'dashboard' %}active{% endif %}"><i class="fas fa-chart-line"></i><span class="ml-3 sidebar-text" data-i18n="nav.dashboard">Dashboard</span></a>
|
|
<a href="/trading_bots" class="nav-item flex items-center px-4 py-3 text-gray-600 hover:text-blue-600 hover:bg-blue-50 {% if active_page == 'trading_bots' %}active{% endif %}"><i class="fas fa-robot"></i><span class="ml-3 sidebar-text" data-i18n="nav.bots">Trading Bots</span></a>
|
|
<a href="/portfolio" class="nav-item flex items-center px-4 py-3 text-gray-600 hover:text-blue-600 hover:bg-blue-50 {% if active_page == 'portfolio' %}active{% endif %}"><i class="fas fa-wallet"></i><span class="ml-3 sidebar-text" data-i18n="nav.portfolio">Portfolio</span></a>
|
|
<a href="/backtesting" class="nav-item flex items-center px-4 py-3 text-gray-600 hover:text-blue-600 hover:bg-blue-50 {% if active_page == 'backtesting' %}active{% endif %}"><i class="fas fa-vial"></i><span class="ml-3 sidebar-text" data-i18n="nav.backtest">Backtester</span></a>
|
|
<a href="/ai-mentor" class="nav-item flex items-center px-4 py-3 text-gray-600 hover:text-blue-600 hover:bg-blue-50 {% if active_page == 'ai_mentor' %}active{% endif %}"><i class="fas fa-brain"></i><span class="ml-3 sidebar-text" data-i18n="nav.ai_mentor">AI Mentor</span></a>
|
|
<a href="/strategy-switcher" class="nav-item flex items-center px-4 py-3 text-gray-600 hover:text-blue-600 hover:bg-blue-50 {% if active_page == 'strategy_switcher' %}active{% endif %}"><i class="fas fa-sync-alt"></i><span class="ml-3 sidebar-text" data-i18n="nav.strategy_switcher">Strategy Switcher</span></a>
|
|
<!-- Ramadan link will only be visible when Ramadan mode is active -->
|
|
<a href="/ramadan" id="ramadan-nav-link" class="nav-item flex items-center px-4 py-3 text-gray-600 hover:text-blue-600 hover:bg-blue-50 {% if active_page == 'ramadan' %}active{% endif %} hidden"><i class="fas fa-moon"></i><span class="ml-3 sidebar-text" data-i18n="nav.ramadan">Ramadan Mode</span></a>
|
|
<a href="/history" class="nav-item flex items-center px-4 py-3 text-gray-600 hover:text-blue-600 hover:bg-blue-50 {% if active_page == 'history' %}active{% endif %}"><i class="fas fa-history"></i><span class="ml-3 sidebar-text" data-i18n="nav.history">History</span></a>
|
|
<a href="/settings" class="nav-item flex items-center px-4 py-3 text-gray-600 hover:text-blue-600 hover:bg-blue-50 {% if active_page == 'settings' %}active{% endif %}"><i class="fas fa-cog"></i><span class="ml-3 sidebar-text" data-i18n="nav.settings">Settings</span></a>
|
|
<div class="px-4 mt-8 mb-4"><p class="text-xs font-semibold text-gray-500 uppercase tracking-wider sidebar-text" data-i18n="nav.section.market_data">Market Data</p></div>
|
|
<a href="/stocks" class="nav-item flex items-center px-4 py-3 text-gray-600 hover:text-blue-600 hover:bg-blue-50 {% if active_page == 'stocks' %}active{% endif %}"><i class="fas fa-chart-bar"></i><span class="ml-3 sidebar-text" data-i18n="nav.stocks">Stocks</span></a>
|
|
<a href="/forex" class="nav-item flex items-center px-4 py-3 text-gray-600 hover:text-blue-600 hover:bg-blue-50 {% if active_page == 'forex' %}active{% endif %}"><i class="fas fa-exchange-alt"></i><span class="ml-3 sidebar-text" data-i18n="nav.forex">Forex</span></a>
|
|
</nav>
|
|
</div>
|
|
<div class="p-4 border-t">
|
|
<a href="/profile" class="flex items-center group">
|
|
<div class="w-10 h-10 rounded-full bg-gray-200 flex items-center justify-center"><i class="fas fa-user text-gray-600"></i></div>
|
|
<div class="ml-3 sidebar-text "><p class="text-sm font-medium text-gray-800 group-hover:text-blue-600">Reynov Christian</p><p class="text-xs text-gray-500 group-hover:text-blue-600">Developer</p></div>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- MAIN CONTENT -->
|
|
<div class="flex-1 overflow-auto">
|
|
<header class="bg-white shadow-sm">
|
|
<div class="flex items-center justify-between px-6 py-4">
|
|
<div class="flex items-center">
|
|
<button id="sidebar-toggle" class="text-gray-500 focus:outline-none"><i class="fas fa-bars"></i></button>
|
|
<div class="ml-4 relative">
|
|
<input type="text" class="w-64 px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" placeholder="Search markets, bots..." />
|
|
<i class="fas fa-search absolute right-3 top-3 text-gray-400"></i>
|
|
</div>
|
|
</div>
|
|
<div class="flex items-center space-x-4">
|
|
<!-- Global Language Switcher -->
|
|
<div class="flex items-center space-x-1 bg-white rounded-lg shadow-sm border px-2 py-1">
|
|
<button class="lang-btn px-2 py-1 text-xs rounded font-medium hover:bg-gray-100 transition-colors" data-lang="id">ID</button>
|
|
<button class="lang-btn px-2 py-1 text-xs rounded font-medium hover:bg-gray-100 transition-colors" data-lang="en">EN</button>
|
|
</div>
|
|
<a href="/notifications" class="relative text-gray-500 hover:text-blue-600"><i class="fas fa-bell"></i><span id="notification-dot" class="absolute top-0 right-0 w-2 h-2 rounded-full bg-red-500 hidden"></span></a>
|
|
<a href="/profile" class="w-8 h-8 rounded-full bg-gray-200 flex items-center justify-center hover:bg-gray-300"><i class="fas fa-user text-gray-600"></i></a>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- Ini adalah area di mana konten unik setiap halaman akan disuntikkan -->
|
|
<main class="p-6">
|
|
{% block content %}{% endblock %}
|
|
</main>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Skrip yang dibutuhkan oleh semua halaman -->
|
|
<!-- Toastify JS -->
|
|
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/toastify-js"></script>
|
|
<!-- Internationalization (i18n) System -->
|
|
<script src="{{ url_for('static', filename='js/i18n.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='js/main.js') }}"></script>
|
|
<!-- Holiday Detection Script -->
|
|
<script>
|
|
// Function to apply holiday theme
|
|
function applyHolidayTheme(theme) {
|
|
const styleElement = document.getElementById('holiday-styles');
|
|
if (!styleElement) return;
|
|
|
|
let css = '';
|
|
if (theme.background_gradient) {
|
|
css += `body { background: ${theme.background_gradient}; }`;
|
|
}
|
|
if (theme.primary_color) {
|
|
css += `:root { --holiday-primary: ${theme.primary_color}; }`;
|
|
}
|
|
if (theme.secondary_color) {
|
|
css += `:root { --holiday-secondary: ${theme.secondary_color}; }`;
|
|
}
|
|
if (theme.accent_color) {
|
|
css += `:root { --holiday-accent: ${theme.accent_color}; }`;
|
|
}
|
|
|
|
styleElement.textContent = css;
|
|
}
|
|
|
|
// Function to check for active holidays
|
|
async function checkHolidayStatus() {
|
|
try {
|
|
const response = await fetch('/api/holiday/status');
|
|
const data = await response.json();
|
|
|
|
if (data.success && data.is_holiday) {
|
|
// Show holiday banner
|
|
const banner = document.getElementById('holiday-banner');
|
|
const greeting = document.getElementById('holiday-greeting');
|
|
const countdown = document.getElementById('holiday-countdown');
|
|
|
|
if (banner && greeting) {
|
|
greeting.textContent = data.greeting;
|
|
banner.classList.remove('hidden');
|
|
|
|
// Apply holiday theme
|
|
if (data.ui_theme) {
|
|
applyHolidayTheme(data.ui_theme);
|
|
}
|
|
|
|
// Special handling for Ramadan features
|
|
if (data.holiday_name === "Ramadan Trading Mode" && data.ramadan_features) {
|
|
// Show the Ramadan navigation link since mode is active
|
|
const ramadanLink = document.getElementById('ramadan-nav-link');
|
|
if (ramadanLink) {
|
|
ramadanLink.classList.remove('hidden');
|
|
}
|
|
|
|
// Show Iftar countdown if available
|
|
if (data.ramadan_features.iftar_countdown) {
|
|
const countdownData = data.ramadan_features.iftar_countdown;
|
|
countdown.textContent = `${countdownData.hours}h ${countdownData.minutes}m until ${countdownData.next_prayer}`;
|
|
}
|
|
}
|
|
|
|
// Special handling for Christmas features
|
|
if (data.holiday_name === "Christmas Trading Mode") {
|
|
// Show countdown if it's close to Christmas
|
|
const today = new Date();
|
|
const christmasDate = new Date(today.getFullYear(), 11, 25); // December 25
|
|
const timeDiff = christmasDate - today;
|
|
const daysDiff = Math.ceil(timeDiff / (1000 * 60 * 60 * 24));
|
|
|
|
if (daysDiff >= 0 && daysDiff <= 10) {
|
|
countdown.textContent = `${daysDiff} days until Christmas`;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// Hide Ramadan navigation link when no holiday is active
|
|
const ramadanLink = document.getElementById('ramadan-nav-link');
|
|
if (ramadanLink) {
|
|
ramadanLink.classList.add('hidden');
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('Error checking holiday status:', error);
|
|
}
|
|
}
|
|
|
|
// Check for holidays on page load
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
checkHolidayStatus();
|
|
});
|
|
</script>
|
|
<!-- Blok untuk skrip spesifik halaman -->
|
|
{% block scripts %}{% endblock %}
|
|
</body>
|
|
</html>
|