Spaces:
Sleeping
Sleeping
File size: 8,598 Bytes
9c90775 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | <!DOCTYPE html>
<html lang="en" class="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Multi-RAG Studio{% endblock %}</title>
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&family=Plus+Jakarta+Sans:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
<script src="https://cdn.tailwindcss.com"></script>
<script src="{{ url_for('static', path='/js/main.js') }}"></script>
{% block extra_head %}{% endblock %}
</head>
<body class="bg-slate-950 text-slate-100 flex flex-col min-h-screen relative overflow-x-hidden selection:bg-indigo-600 selection:text-white">
<!-- Ambient background glows -->
<div class="absolute top-0 left-1/4 w-[500px] h-[500px] bg-indigo-900/20 rounded-full blur-[120px] pointer-events-none -z-10 animate-pulse" style="animation-duration: 10s;"></div>
<div class="absolute bottom-0 right-1/4 w-[600px] h-[600px] bg-purple-900/10 rounded-full blur-[150px] pointer-events-none -z-10 animate-pulse" style="animation-duration: 15s;"></div>
<!-- Grid Overlay (Radial Dots grid using Tailwind-friendly inline styles) -->
<div class="absolute inset-0 pointer-events-none -z-20 opacity-20" style="background-image: radial-gradient(rgba(255,255,255,0.15) 1px, transparent 1px); background-size: 24px 24px;"></div>
<nav class="sticky top-0 z-50 bg-slate-950/45 backdrop-blur-md border-b border-white/5 shadow-lg">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex items-center justify-between h-16">
<div class="flex items-center space-x-3 cursor-pointer group">
<div class="relative">
<div class="absolute inset-0 bg-indigo-500 rounded-lg blur-md opacity-70 group-hover:opacity-100 transition-opacity"></div>
<div class="relative bg-gradient-to-tr from-indigo-600 to-purple-600 p-2 rounded-lg text-white font-extrabold tracking-wider text-sm shadow-lg">
M-RAG
</div>
</div>
<span class="font-extrabold text-xl bg-gradient-to-r from-white via-slate-200 to-slate-400 bg-clip-text text-transparent group-hover:to-white transition-all">
Multi-RAG <span class="text-xs font-bold text-indigo-400 uppercase tracking-widest ml-1 bg-indigo-500/10 px-2 py-0.5 rounded-full border border-indigo-500/20">Studio</span>
</span>
</div>
<div class="hidden md:flex space-x-8 text-sm font-semibold">
<a href="/" class="text-indigo-400 border-b-2 border-indigo-500 px-1 py-5 transition-all">Home</a>
<a href="#" class="text-slate-400 hover:text-white transition duration-200 px-1 py-5">Knowledge Base</a>
<a href="#" class="text-slate-400 hover:text-white transition duration-200 px-1 py-5">Analytics</a>
<a href="#" class="text-slate-400 hover:text-white transition duration-200 px-1 py-5">Settings</a>
</div>
<div class="flex items-center space-x-4">
<a href="#" class="text-slate-400 hover:text-white transition text-sm font-semibold hidden sm:inline-block">Docs</a>
<!-- Global session countdown timer (hidden until a session starts) -->
<div id="global-timer-wrapper" class="hidden">
<div id="global-timer-badge"
class="inline-flex items-center space-x-1.5 px-3 py-1.5 rounded-lg bg-indigo-500/20 border border-indigo-500/30 text-indigo-400 text-sm font-extrabold tabular-nums tracking-wide">
<svg class="w-3.5 h-3.5 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5">
<circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>
</svg>
<span>--:--</span>
</div>
</div>
<button class="relative group overflow-hidden bg-gradient-to-r from-indigo-600 to-purple-600 hover:from-indigo-500 hover:to-purple-500 text-white px-5 py-2 rounded-lg text-sm font-bold shadow-lg shadow-indigo-500/25 transition-all duration-300">
<span class="relative z-10">New Chat</span>
<div class="absolute inset-0 bg-white/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</button>
</div>
</div>
</div>
</nav>
<main class="flex-grow max-w-7xl w-full mx-auto px-4 sm:px-6 lg:px-8 py-10 relative z-10">
{% block main %}
I am the main body
{% endblock %}
</main>
<footer class="bg-slate-950/45 backdrop-blur-md border-t border-white/5 py-8 text-sm text-slate-500 mt-auto">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex flex-col sm:flex-row items-center justify-between space-y-4 sm:space-y-0">
<div class="flex items-center space-x-2">
<span class="font-bold text-slate-400">Multi-RAG Studio</span>
<span class="text-slate-600">|</span>
<span>© 2026. All rights reserved.</span>
</div>
<div class="flex space-x-6 text-slate-400 font-medium">
<a href="#" class="hover:text-indigo-400 transition duration-150">Documentation</a>
<a href="#" class="hover:text-indigo-400 transition duration-150">API Reference</a>
<a href="#" class="hover:text-indigo-400 transition duration-150">Privacy Policy</a>
</div>
</div>
</footer>
{% block extra_scripts %}{% endblock %}
<!-- βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
GLOBAL SESSION TIMER β runs on every page
Reads from localStorage so it survives navigation.
Upload page saves: multirag_session_start (epoch ms)
multirag_session_duration (seconds)
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ -->
<script>
(function () {
const STORAGE_START = 'multirag_session_start'; // epoch ms when login happened
const STORAGE_DURATION = 'multirag_session_duration'; // total session seconds
const wrapper = document.getElementById('global-timer-wrapper');
const badge = document.getElementById('global-timer-badge');
const badgeSpan = badge ? badge.querySelector('span') : null;
function fmtTime(s) {
if (s <= 0) return '00:00';
const h = Math.floor(s / 3600);
const m = Math.floor((s % 3600) / 60);
const sec = s % 60;
if (h > 0)
return h + ':' + String(m).padStart(2,'0') + ':' + String(sec).padStart(2,'0');
return String(m).padStart(2,'0') + ':' + String(sec).padStart(2,'0');
}
function startNavTimer() {
const start = parseInt(localStorage.getItem(STORAGE_START), 10);
const duration = parseInt(localStorage.getItem(STORAGE_DURATION), 10);
if (!start || !duration) return; // no session saved yet
const expiresAt = start + duration * 1000; // epoch ms
if (wrapper) wrapper.classList.remove('hidden');
let interval;
function tick() {
const remaining = Math.max(0, Math.round((expiresAt - Date.now()) / 1000));
if (badgeSpan) badgeSpan.textContent = fmtTime(remaining);
if (remaining <= 60) {
badge.classList.remove('bg-indigo-500/20','text-indigo-400','border-indigo-500/30');
badge.classList.add('bg-red-500/20','text-red-400','border-red-500/40');
}
if (remaining <= 0) {
clearInterval(interval);
if (badgeSpan) badgeSpan.textContent = 'EXPIRED';
badge.classList.add('opacity-60');
// clean up storage so timer doesn't haunt the next session
localStorage.removeItem(STORAGE_START);
localStorage.removeItem(STORAGE_DURATION);
}
}
tick();
interval = setInterval(tick, 1000);
}
// Auto-start on every page as soon as DOM is ready
startNavTimer();
// Also expose so upload.html can call it after saving to localStorage
window.__startNavTimer = startNavTimer;
})();
</script>
</body>
</html> |