395 lines
16 KiB
HTML
Executable File
395 lines
16 KiB
HTML
Executable File
{#
|
||
導航列組件
|
||
|
||
注意:目前已停用登入驗證,所有選單項目對所有人可見。
|
||
|
||
使用方式:
|
||
{% include 'components/_navbar.html' %}
|
||
#}
|
||
|
||
<style>
|
||
:root {
|
||
--momo-legacy-bg: #ebe6dc;
|
||
--momo-legacy-surface: #faf7f0;
|
||
--momo-legacy-paper: #f3eee2;
|
||
--momo-legacy-ink: #2a2520;
|
||
--momo-legacy-muted: #645c52;
|
||
--momo-legacy-accent: #d96f52;
|
||
--momo-legacy-accent-dark: #a95846;
|
||
--momo-legacy-accent-soft: rgba(201, 100, 66, 0.12);
|
||
--momo-legacy-line: rgba(42, 37, 32, 0.16);
|
||
--momo-legacy-inverse: #fff8ee;
|
||
}
|
||
|
||
body {
|
||
background-color: var(--momo-legacy-bg) !important;
|
||
color: var(--momo-legacy-ink);
|
||
}
|
||
|
||
.navbar.navbar-dark,
|
||
.navbar.bg-custom-dark,
|
||
.navbar-dark.bg-primary {
|
||
background:
|
||
radial-gradient(circle at 24px 24px, rgba(255, 248, 238, 0.16) 1px, transparent 1px),
|
||
linear-gradient(135deg, var(--momo-legacy-accent-dark), var(--momo-legacy-accent)) !important;
|
||
background-size: 10px 10px, auto;
|
||
border-bottom: 1px solid rgba(255, 248, 238, 0.18);
|
||
box-shadow: 0 10px 24px rgba(61, 38, 27, 0.16) !important;
|
||
}
|
||
|
||
.navbar .navbar-brand,
|
||
.navbar .navbar-text,
|
||
.navbar-dark .navbar-brand,
|
||
.navbar-dark .navbar-text {
|
||
color: var(--momo-legacy-inverse) !important;
|
||
}
|
||
|
||
.navbar-dark .navbar-nav .nav-link,
|
||
.navbar.bg-custom-dark .navbar-nav .nav-link {
|
||
color: rgba(255, 248, 238, 0.82) !important;
|
||
border-radius: 6px;
|
||
transition: background-color 160ms ease, color 160ms ease;
|
||
}
|
||
|
||
.navbar-dark .navbar-nav .nav-link:hover,
|
||
.navbar.bg-custom-dark .navbar-nav .nav-link:hover {
|
||
color: var(--momo-legacy-inverse) !important;
|
||
background: rgba(255, 248, 238, 0.12) !important;
|
||
}
|
||
|
||
.navbar-dark .navbar-nav .nav-link.active,
|
||
.navbar-dark .navbar-nav .nav-link.show,
|
||
.navbar.bg-custom-dark .navbar-nav .nav-link.active,
|
||
.navbar.bg-custom-dark .navbar-nav .nav-link.show {
|
||
color: var(--momo-legacy-inverse) !important;
|
||
background: rgba(255, 248, 238, 0.18) !important;
|
||
font-weight: 800;
|
||
}
|
||
|
||
.dropdown-menu {
|
||
background: var(--momo-legacy-surface);
|
||
border: 1px solid var(--momo-legacy-line);
|
||
box-shadow: 0 18px 34px rgba(61, 38, 27, 0.14);
|
||
}
|
||
|
||
.dropdown-header,
|
||
.dropdown-item {
|
||
color: var(--momo-legacy-ink);
|
||
}
|
||
|
||
.dropdown-item:hover,
|
||
.dropdown-item:focus,
|
||
.dropdown-item.active,
|
||
.dropdown-item:active {
|
||
color: var(--momo-legacy-accent-dark);
|
||
background: var(--momo-legacy-accent-soft);
|
||
}
|
||
|
||
.btn-primary,
|
||
.bg-primary,
|
||
.badge.bg-primary,
|
||
.progress-bar.bg-primary,
|
||
.nav-pills .nav-link.active,
|
||
.nav-tabs .nav-link.active,
|
||
.page-item.active .page-link,
|
||
.card-header.bg-primary {
|
||
color: var(--momo-legacy-inverse) !important;
|
||
background: linear-gradient(135deg, var(--momo-legacy-accent), var(--momo-legacy-accent-dark)) !important;
|
||
border-color: var(--momo-legacy-accent-dark) !important;
|
||
}
|
||
|
||
.btn-primary:hover,
|
||
.btn-primary:focus {
|
||
color: var(--momo-legacy-inverse) !important;
|
||
background: linear-gradient(135deg, #c65f45, #9f4f3e) !important;
|
||
border-color: #7a3520 !important;
|
||
}
|
||
|
||
.btn-outline-primary {
|
||
color: var(--momo-legacy-accent-dark) !important;
|
||
border-color: var(--momo-legacy-accent) !important;
|
||
}
|
||
|
||
.btn-outline-primary:hover,
|
||
.btn-outline-primary.active {
|
||
color: var(--momo-legacy-inverse) !important;
|
||
background: var(--momo-legacy-accent) !important;
|
||
border-color: var(--momo-legacy-accent-dark) !important;
|
||
}
|
||
|
||
.text-primary,
|
||
a,
|
||
.product-link:hover {
|
||
color: var(--momo-legacy-accent-dark) !important;
|
||
}
|
||
|
||
.spinner-border.text-primary {
|
||
color: var(--momo-legacy-accent) !important;
|
||
}
|
||
|
||
.table thead,
|
||
.table thead th,
|
||
thead.bg-light th {
|
||
background: var(--momo-legacy-paper) !important;
|
||
color: var(--momo-legacy-ink) !important;
|
||
border-color: var(--momo-legacy-line) !important;
|
||
}
|
||
|
||
.card,
|
||
.modal-content {
|
||
background: var(--momo-legacy-surface);
|
||
border-color: var(--momo-legacy-line);
|
||
}
|
||
</style>
|
||
|
||
<nav class="navbar navbar-expand-xl navbar-dark bg-custom-dark fixed-top shadow-sm">
|
||
<div class="container">
|
||
<!-- 品牌 Logo -->
|
||
<a class="navbar-brand d-flex align-items-center" href="/">
|
||
<span class="d-none d-sm-inline fw-bold" style="letter-spacing: 0;">EwoooC</span>
|
||
</a>
|
||
|
||
<!-- 手機版選單按鈕 -->
|
||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
||
<span class="navbar-toggler-icon"></span>
|
||
</button>
|
||
|
||
<div class="collapse navbar-collapse" id="navbarNav">
|
||
<ul class="navbar-nav me-auto">
|
||
<!-- 商品看板 - 所有人可見 -->
|
||
<li class="nav-item">
|
||
<a class="nav-link {% if active_page == 'dashboard' %}active{% endif %}" href="/">
|
||
<i class="fas fa-chart-line me-1"></i>商品看板
|
||
</a>
|
||
</li>
|
||
|
||
<!-- 活動看板 - 所有人可見 -->
|
||
<li class="nav-item">
|
||
<a class="nav-link {% if active_page == 'edm' %}active{% endif %}" href="/edm">
|
||
<i class="fas fa-bullhorn me-1"></i>活動看板
|
||
</a>
|
||
</li>
|
||
|
||
<!-- 分析報表 -->
|
||
<li class="nav-item dropdown">
|
||
<a class="nav-link dropdown-toggle {% if active_page in ['sales', 'daily_sales', 'monthly', 'growth'] %}active{% endif %}"
|
||
href="#" role="button" data-bs-toggle="dropdown">
|
||
<i class="fas fa-chart-bar me-1"></i>分析報表
|
||
</a>
|
||
<ul class="dropdown-menu">
|
||
<li>
|
||
<a class="dropdown-item" href="/sales_analysis">
|
||
<i class="fas fa-chart-bar me-2"></i>業績分析
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a class="dropdown-item" href="/daily_sales">
|
||
<i class="fas fa-calendar-day me-2"></i>當日業績
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a class="dropdown-item" href="/growth_analysis">
|
||
<i class="fas fa-chart-line me-2"></i>成長分析
|
||
</a>
|
||
</li>
|
||
<li><hr class="dropdown-divider"></li>
|
||
<li>
|
||
<a class="dropdown-item" href="/monthly_summary_analysis">
|
||
<i class="fas fa-table me-2"></i>月份總表數據分析
|
||
</a>
|
||
</li>
|
||
{% if metabase_url %}
|
||
<li><hr class="dropdown-divider"></li>
|
||
<li>
|
||
<a class="dropdown-item" href="{{ metabase_url }}" target="_blank">
|
||
<i class="fas fa-chart-pie me-2"></i>自訂圖表 (Metabase)
|
||
<i class="fas fa-external-link-alt ms-1 small text-muted"></i>
|
||
</a>
|
||
</li>
|
||
{% endif %}
|
||
{% if grist_url %}
|
||
<li>
|
||
<a class="dropdown-item" href="{{ grist_url }}" target="_blank">
|
||
<i class="fas fa-table me-2"></i>資料協作 (Grist)
|
||
<i class="fas fa-external-link-alt ms-1 small text-muted"></i>
|
||
</a>
|
||
</li>
|
||
{% endif %}
|
||
</ul>
|
||
</li>
|
||
|
||
<!-- 廠商缺貨 -->
|
||
<li class="nav-item">
|
||
<a class="nav-link {% if active_page == 'vendor_stockout' %}active{% endif %}" href="/vendor-stockout">
|
||
<i class="fas fa-box-open me-1"></i>廠商缺貨
|
||
</a>
|
||
</li>
|
||
|
||
<!-- AI 助手 -->
|
||
<li class="nav-item dropdown">
|
||
<a class="nav-link dropdown-toggle {% if active_page in ['ai_recommend', 'ai_history'] %}active{% endif %}"
|
||
href="#" role="button" data-bs-toggle="dropdown">
|
||
<i class="fas fa-robot me-1"></i>AI 助手
|
||
</a>
|
||
<ul class="dropdown-menu">
|
||
<li>
|
||
<a class="dropdown-item" href="/ai_recommend">
|
||
<i class="fas fa-magic me-2"></i>智慧文案生成
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a class="dropdown-item" href="/ai_history">
|
||
<i class="fas fa-history me-2"></i>生成歷史記錄
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
|
||
<!-- AI 觀測台:第一層入口,內部依任務域分組,不再平鋪在全域導航 -->
|
||
<li class="nav-item dropdown">
|
||
<a class="nav-link dropdown-toggle {% if active_page in ['obs_overview', 'obs_agent_orchestration', 'obs_business_intel', 'obs_ai_calls', 'obs_host_health', 'obs_budget', 'obs_promotion_review', 'obs_rag_queries', 'obs_quality_trend', 'obs_ppt_audit'] %}active{% endif %}"
|
||
href="#" role="button" data-bs-toggle="dropdown">
|
||
<i class="fas fa-satellite-dish me-1"></i>AI 觀測台
|
||
</a>
|
||
<ul class="dropdown-menu dropdown-menu-observability">
|
||
<li><h6 class="dropdown-header">戰情室</h6></li>
|
||
<li>
|
||
<a class="dropdown-item" href="/observability/overview">
|
||
<i class="fas fa-gauge-high me-2"></i>觀測台總覽
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a class="dropdown-item" href="/observability/agent_orchestration">
|
||
<i class="fas fa-network-wired me-2"></i>Agent 編排矩陣
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a class="dropdown-item" href="/observability/business_intel">
|
||
<i class="fas fa-briefcase me-2"></i>商業面 × AI
|
||
</a>
|
||
</li>
|
||
<li><hr class="dropdown-divider"></li>
|
||
<li><h6 class="dropdown-header">系統與成本</h6></li>
|
||
<li>
|
||
<a class="dropdown-item" href="/observability/ai_calls">
|
||
<i class="fas fa-chart-bar me-2"></i>AI 呼叫總覽
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a class="dropdown-item" href="/observability/host_health">
|
||
<i class="fas fa-heartbeat me-2"></i>主機健康監控
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a class="dropdown-item" href="/observability/budget">
|
||
<i class="fas fa-wallet me-2"></i>預算控管
|
||
</a>
|
||
</li>
|
||
<li><hr class="dropdown-divider"></li>
|
||
<li><h6 class="dropdown-header">RAG 與品質</h6></li>
|
||
<li>
|
||
<a class="dropdown-item" href="/observability/promotion_review">
|
||
<i class="fas fa-brain me-2"></i>RAG 學習晉升審核
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a class="dropdown-item" href="/observability/rag_queries">
|
||
<i class="fas fa-magnifying-glass-chart me-2"></i>RAG 召回詳情
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a class="dropdown-item" href="/observability/quality_trend">
|
||
<i class="fas fa-comments me-2"></i>Caller 反饋趨勢
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a class="dropdown-item" href="/observability/ppt_audit_history">
|
||
<i class="fas fa-search me-2"></i>PPT 視覺審核歷史
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
|
||
<!-- 雲端匯入 -->
|
||
<li class="nav-item">
|
||
<a class="nav-link {% if active_page == 'auto_import' %}active{% endif %}" href="/auto_import">
|
||
<i class="fas fa-cloud-download-alt me-1"></i>雲端匯入
|
||
</a>
|
||
</li>
|
||
|
||
<!-- 系統管理 -->
|
||
<li class="nav-item dropdown">
|
||
<a class="nav-link dropdown-toggle {% if active_page in ['settings', 'system_settings', 'logs', 'crawler', 'user_management', 'ai_automation_smoke'] %}active{% endif %}"
|
||
href="#" role="button" data-bs-toggle="dropdown">
|
||
<i class="fas fa-cog me-1"></i>系統管理
|
||
</a>
|
||
<ul class="dropdown-menu">
|
||
<li>
|
||
<a class="dropdown-item" href="/user_management">
|
||
<i class="fas fa-users-cog me-2"></i>用戶管理
|
||
</a>
|
||
</li>
|
||
<li><hr class="dropdown-divider"></li>
|
||
<li>
|
||
<a class="dropdown-item" href="/settings">
|
||
<i class="fas fa-robot me-2"></i>爬蟲管理
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a class="dropdown-item" href="/crawler_management">
|
||
<i class="fas fa-spider me-2"></i>爬蟲設定
|
||
</a>
|
||
</li>
|
||
<li><hr class="dropdown-divider"></li>
|
||
<li>
|
||
<a class="dropdown-item" href="/system_settings">
|
||
<i class="fas fa-sliders-h me-2"></i>系統設定
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a class="dropdown-item" href="/logs">
|
||
<i class="fas fa-file-alt me-2"></i>系統日誌
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a class="dropdown-item" href="/ai_automation_smoke">
|
||
<i class="fas fa-heartbeat me-2"></i>AI 自動化 Smoke
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<!-- 右側區域 -->
|
||
<div class="d-flex align-items-center">
|
||
<!-- 時間顯示 -->
|
||
<span class="navbar-text text-light small me-3">
|
||
<i class="fas fa-clock me-1"></i>
|
||
<span id="navbar-datetime">{{ datetime_now or '' }}</span>
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
|
||
<!-- 導航列時間更新腳本 -->
|
||
<script>
|
||
(function() {
|
||
function updateNavbarTime() {
|
||
const now = new Date();
|
||
const formatted = now.getFullYear() + '-' +
|
||
String(now.getMonth() + 1).padStart(2, '0') + '-' +
|
||
String(now.getDate()).padStart(2, '0') + ' ' +
|
||
String(now.getHours()).padStart(2, '0') + ':' +
|
||
String(now.getMinutes()).padStart(2, '0') + ':' +
|
||
String(now.getSeconds()).padStart(2, '0');
|
||
|
||
const el = document.getElementById('navbar-datetime');
|
||
if (el) el.textContent = formatted;
|
||
}
|
||
|
||
// 每秒更新時間
|
||
setInterval(updateNavbarTime, 1000);
|
||
})();
|
||
</script>
|