Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions html/dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,15 @@ <h3 class="text-white font-black tracking-[0.4em] uppercase text-sm mb-3">Forens
<div id="sidebarOverlay" onclick="toggleSidebar()" class="hidden fixed inset-0 bg-black/60 backdrop-blur-sm z-40 lg:hidden"></div>

<!-- Sidebar -->
<nav id="sidebar" class="fixed lg:relative -translate-x-full lg:translate-x-0 transition-transform duration-300 w-64 h-full border-r border-white/5 bg-slate-950/95 lg:bg-slate-950/50 flex flex-col p-6 shrink-0 z-50">
<div class="flex items-center gap-3 mb-10 px-2">
<i class="fas fa-shield-halved text-blue-500 text-2xl"></i>
<span class="font-black tracking-tighter uppercase italic text-lg leading-tight text-white">Evidence <br /><span class="text-blue-500 text-sm">Protector Pro</span></span>
<nav id="sidebar" class="fixed lg:relative -translate-x-full lg:translate-x-0 transition-all duration-300 w-64 h-full border-r border-white/5 bg-slate-950/95 lg:bg-slate-950/50 flex flex-col p-6 shrink-0 z-50 sidebar-expanded">
<div class="flex items-center justify-between gap-3 mb-10 px-2">
<div class="flex items-center gap-3 sidebar-header-content">
<i class="fas fa-shield-halved text-blue-500 text-2xl"></i>
<span class="font-black tracking-tighter uppercase italic text-lg leading-tight text-white">Evidence <br /><span class="text-blue-500 text-sm">Protector Pro</span></span>
</div>
<button id="sidebarToggle" onclick="toggleSidebarCollapse()" class="hidden lg:flex items-center justify-center p-2 rounded-lg bg-slate-900/50 hover:bg-slate-800 border border-white/5 hover:border-blue-500/30 transition-all duration-300 sidebar-toggle-btn" title="Toggle Sidebar">
<i class="fas fa-chevron-left text-white text-sm"></i>
</button>
</div>
<div class="space-y-1 flex-1 custom-scroll overflow-y-auto">
<p class="text-[9px] font-bold text-slate-600 uppercase tracking-widest mb-3 px-2">System Access</p>
Expand Down Expand Up @@ -403,7 +408,7 @@ <h3 class="text-sm font-black uppercase tracking-wide text-white">Governing Law<
</div>
</div>
<div class="p-5 pt-3 border-t border-white/10 bg-gradient-to-b from-transparent to-black/20">
<button onclick="closeTOS()" class="tos-accept-btn w-full py-3.5 rounded-xl font-black text-[10px] uppercase tracking-widest text-white transition-all duration-300 flex items-center justify-center gap-2">
<button onclick="acceptTOS()" class="tos-accept-btn w-full py-3.5 rounded-xl font-black text-[10px] uppercase tracking-widest text-white transition-all duration-300 flex items-center justify-center gap-2">
<i class="fas fa-check-circle text-xs"></i> Accept Terms & Continue
</button>
<p class="text-[8px] text-slate-600 text-center mt-3 font-mono">By accepting, you agree to comply with all forensic data handling regulations</p>
Expand Down
60 changes: 60 additions & 0 deletions js/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,12 @@ window.addEventListener("DOMContentLoaded", () => {

// 6. Mobile Sidebar Setup
setupMobileSidebar();

// 7. Restore Sidebar Collapse State
restoreSidebarState();

// 8. Show Terms of Service once per user
showTOSOnce();
});

function resetDashboardState() {
Expand Down Expand Up @@ -1114,6 +1120,26 @@ function closeTOS() {
document.getElementById("tosModal").classList.replace("flex", "hidden");
}

function getCurrentUsername() {
return localStorage.getItem("current_user") || sessionStorage.getItem("current_user") || "default";
}

function getTosStorageKey() {
const username = getCurrentUsername();
return `tos_accepted_${username}`;
}

function acceptTOS() {
localStorage.setItem(getTosStorageKey(), "true");
closeTOS();
}

function showTOSOnce() {
if (localStorage.getItem(getTosStorageKey()) !== "true") {
showTOS();
}
}

async function checkApiStatus() {
const indicator = document.getElementById("apiStatusIndicator");
if (!indicator) return;
Expand Down Expand Up @@ -1271,4 +1297,38 @@ function setupMobileSidebar() {
}
});
});
}

// ─── SIDEBAR COLLAPSE/EXPAND (DESKTOP) ───────────────────────────────────

function toggleSidebarCollapse() {
const sidebar = document.getElementById("sidebar");
if (!sidebar) return;

const isCollapsed = sidebar.classList.contains("sidebar-collapsed");

if (isCollapsed) {
sidebar.classList.remove("sidebar-collapsed");
sidebar.classList.add("sidebar-expanded");
localStorage.setItem("sidebar-collapsed", "false");
} else {
sidebar.classList.remove("sidebar-expanded");
sidebar.classList.add("sidebar-collapsed");
localStorage.setItem("sidebar-collapsed", "true");
}
}

function restoreSidebarState() {
const sidebar = document.getElementById("sidebar");
if (!sidebar) return;

const isCollapsed = localStorage.getItem("sidebar-collapsed") === "true";

if (isCollapsed) {
sidebar.classList.remove("sidebar-expanded");
sidebar.classList.add("sidebar-collapsed");
} else {
sidebar.classList.remove("sidebar-collapsed");
sidebar.classList.add("sidebar-expanded");
}
}
2 changes: 2 additions & 0 deletions js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ async function handleLogin() {
if (res.ok) {
const data = await res.json();
localStorage.setItem("access_token", data.access_token);
localStorage.setItem("current_user", u);
if (loginBtn) {
loginBtn.innerText = "UPLINK ESTABLISHED";
loginBtn.classList.replace("bg-blue-600", "bg-emerald-600");
Expand Down Expand Up @@ -233,6 +234,7 @@ async function handleRegister() {

if (res.ok) {
localStorage.setItem("access_token", data.access_token);
localStorage.setItem("current_user", u);
if (regBtn) {
regBtn.innerText = "UPLINK ESTABLISHED";
regBtn.classList.replace("bg-emerald-600", "bg-blue-600");
Expand Down
204 changes: 203 additions & 1 deletion styles/dashboard.css
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ html[data-theme="light"] #sidebar .border-b {

/* ── Header ──────────────────────────────────────────────────────────────── */
header {
background: var(--bg-header) !important;
background: #0a1628 !important;
border-color: var(--border-subtle) !important;
transition: background 0.3s ease;
}
Expand Down Expand Up @@ -789,6 +789,208 @@ html[data-theme="light"] #progressBarFill {
50% { opacity: 0.4; }
}

/* ── Sidebar Collapse/Expand Animation ─────────────────────────────────── */
@keyframes rotateChevron {
from {
transform: rotate(0deg);
}
to {
transform: rotate(180deg);
}
}

#sidebar {
transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

#sidebar.sidebar-expanded {
width: 16rem; /* w-64 */
}

#sidebar.sidebar-collapsed {
width: 5rem; /* w-20 */
}

.sidebar-header-content {
transition: opacity 0.3s ease, visibility 0.3s ease;
}

#sidebar.sidebar-collapsed .sidebar-header-content {
opacity: 0;
visibility: hidden;
width: 0;
}

.sidebar-toggle-btn i {
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

#sidebar.sidebar-collapsed .sidebar-toggle-btn i {
transform: rotate(180deg);
}

/* Hide text labels when collapsed */
#sidebar.sidebar-collapsed .nav-item {
justify-content: center;
align-items: center;
width: 100% !important;
padding: 0.75rem !important;
gap: 0 !important;
font-size: 0 !important;
min-height: 2.75rem;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

#sidebar.sidebar-collapsed .nav-item:hover {
transform: translateY(-4px) scale(1.05);
box-shadow: 0 8px 20px rgba(59, 130, 246, 0.25);
background: rgba(59, 130, 246, 0.15) !important;
}

#sidebar.sidebar-collapsed .nav-item.active {
box-shadow: 0 8px 20px rgba(59, 130, 246, 0.35);
}

#sidebar.sidebar-collapsed .nav-item i {
font-size: 1rem !important;
margin: 0 !important;
width: auto !important;
display: flex !important;
align-items: center;
justify-content: center;
transition: color 0.3s ease;
}

/* Reduce spacing in nav container - remove flex-1 to eliminate page slider */
#sidebar.sidebar-collapsed .space-y-1 {
gap: 0.25rem !important;
flex: 0 0 auto !important;
flex-grow: 0 !important;
height: auto !important;
max-height: none !important;
overflow-y: visible !important;
}

/* Hide all section headings */
#sidebar.sidebar-collapsed > div > p {
display: none !important;
}

/* Hide case count badge */
#sidebar.sidebar-collapsed #case-count-badge {
display: none !important;
}

/* Hide Terms of Service button and its container completely */
#sidebar.sidebar-collapsed .px-2.mb-4 {
display: none !important;
}

/* Hide logout button text, show only icon - centered like nav items */
#sidebar.sidebar-collapsed button[onclick="logout()"] {
justify-content: center;
align-items: center;
width: 100% !important;
gap: 0 !important;
padding: 0.75rem !important;
font-size: 0 !important;
min-height: 2.75rem;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
margin-top: 1rem !important;
}

#sidebar.sidebar-collapsed button[onclick="logout()"]:hover {
transform: translateY(-4px) scale(1.05);
box-shadow: 0 8px 20px rgba(239, 68, 68, 0.25);
background: rgba(239, 68, 68, 0.15) !important;
}

#sidebar.sidebar-collapsed button[onclick="logout()"] i {
font-size: 1rem !important;
margin: 0 !important;
display: flex !important;
align-items: center;
justify-content: center;
}

/* Adjust sidebar padding when collapsed */
#sidebar.sidebar-collapsed {
padding: 1rem 0.75rem;
}

/* Reduce spacing in nav container */
#sidebar.sidebar-collapsed .space-y-1 {
gap: 0.25rem !important;
}

/* Adjust sidebar padding and spacing when collapsed */
#sidebar.sidebar-collapsed {
padding: 1rem 0.75rem;
}

#sidebar.sidebar-collapsed .space-y-1 {
gap: 0.5rem;
flex-grow: 0 !important;
}

/* Position toggle button appropriately */
.sidebar-toggle-btn {
width: 32px;
height: 32px;
padding: 0.5rem;
flex-shrink: 0;
}

html[data-theme="light"] .sidebar-toggle-btn {
background: rgba(59, 130, 246, 0.14) !important;
border-color: rgba(59, 130, 246, 0.28) !important;
color: #ffffff !important;
}

html[data-theme="light"] .sidebar-toggle-btn i {
color: #ffffff !important;
}

html[data-theme="light"] .sidebar-toggle-btn:hover {
background: rgba(59, 130, 246, 0.2) !important;
border-color: rgba(37, 99, 235, 0.4) !important;
}

/* Light mode sidebar collapse styles */
html[data-theme="light"] #sidebar.sidebar-collapsed {
background: #ffffff !important;
border-right: 1px solid #dde3ed !important;
}

html[data-theme="light"] #sidebar.sidebar-collapsed .nav-item {
border-left: none !important;
border-radius: 8px !important;
}

html[data-theme="light"] #sidebar.sidebar-collapsed .nav-item:hover {
background: #e0e9ff !important;
box-shadow: 0 8px 20px rgba(37, 99, 235, 0.2) !important;
transform: translateY(-4px) scale(1.05) !important;
}

html[data-theme="light"] #sidebar.sidebar-collapsed .nav-item.active {
background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%) !important;
box-shadow: 0 8px 20px rgba(37, 99, 235, 0.3) !important;
}

html[data-theme="light"] #sidebar.sidebar-collapsed button[onclick="logout()"]:hover {
background: #fee2e2 !important;
box-shadow: 0 8px 20px rgba(220, 38, 38, 0.2) !important;
transform: translateY(-4px) scale(1.05) !important;
}

/* Dark mode - match light mode animations */
#sidebar.sidebar-collapsed .nav-item:hover {
transform: translateY(-4px) scale(1.05);
box-shadow: 0 8px 20px rgba(59, 130, 246, 0.25);
background: rgba(59, 130, 246, 0.15) !important;
}

.uplink-bar {
width: 300px;
height: 2px;
Expand Down
5 changes: 4 additions & 1 deletion users.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@
"test_op_99": "$2b$12$RHRPdICLvuwcRBnQo.cS7epruKw1qM/L505OxKzpEDtb18q8VWUWu",
"Sandra": "$2b$12$jGTUc3vSzfYcytmqdasHI.Tkxc.hgQ5FFo2ySou1AQ393Bq/AkLDi",
"sanku": "$2b$12$mXT4AQ2ee4SNviZTzAsOlORRvez6gjO5wmp.Z75/kgQjoCNybQRcS",
"operator_test": "$2b$12$.koSl9O1HQ79kyiBjG40QOomL.ydisrvaYJC19k.dA9UmlxvyHsUy"
"operator_test": "$2b$12$.koSl9O1HQ79kyiBjG40QOomL.ydisrvaYJC19k.dA9UmlxvyHsUy",
"Vinay": "$2b$12$fH773zgW8KlptLX472EUeOUQ/QBDqssqdDHdrQERYAhof3s46f3l2",
"yaniv": "$2b$12$m4wqMTEZyqJxUnMf2XDGaeuT5cqqARTflhe20.6e4CDU9iCgcZlra",
"david": "$2b$12$gFxmxpAH4XK0qWl5vFL8eOvdSAElZjDyac447CjglI4.BbLeRmNJ6"
}