diff --git a/package-lock.json b/package-lock.json
index a31296a..3dc0ea2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -917,7 +917,6 @@
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=12"
},
diff --git a/src/components/Sidebar.js b/src/components/Sidebar.js
new file mode 100644
index 0000000..19e3a21
--- /dev/null
+++ b/src/components/Sidebar.js
@@ -0,0 +1,48 @@
+export function createSidebar(pages, currentPage) {
+ const sidebar = document.createElement('aside');
+ sidebar.className = 'sidebar';
+ sidebar.id = 'sidebar';
+
+ const sidebarHeader = document.createElement('div');
+ sidebarHeader.className = 'sidebar-header';
+ sidebarHeader.innerHTML = /*html*/`
+
This is a test page to verify sidebar navigation functionality.
+
+
The sidebar should be visible and allow navigation between different pages.
+
+
+ `;
+
+ container.querySelector('#test-btn').addEventListener('click', () => {
+ alert('Test button clicked!');
+ });
+
+ return container;
+}
diff --git a/src/router.js b/src/router.js
index a565ba9..6ecda04 100644
--- a/src/router.js
+++ b/src/router.js
@@ -1,12 +1,16 @@
import { auth } from './services/auth.js';
import { renderLoginPage } from './pages/LoginPage.js';
import { renderDashboard } from './pages/DashboardPage.js';
+import { renderTestPage } from './pages/test.js';
+import { createSidebar } from './components/Sidebar.js';
+import { getAvailablePages } from './pages/pagesRegistry.js';
export function initRouter() {
const app = document.querySelector('#app');
function navigate() {
const hash = window.location.hash || '#login';
+ const route = hash.substring(1); // Remove the # symbol
if (!auth.checkAuth() && hash !== '#login') {
window.location.hash = '#login';
@@ -15,17 +19,48 @@ export function initRouter() {
app.innerHTML = '';
- switch (hash) {
- case '#login':
- app.appendChild(renderLoginPage(() => {
+ // For authenticated routes, add sidebar and main content wrapper
+ if (auth.checkAuth() && hash !== '#login') {
+ const layout = document.createElement('div');
+ layout.className = 'app-layout';
+
+ // Create sidebar
+ const pages = getAvailablePages(true);
+ const sidebar = createSidebar(pages, route);
+
+ // Create main content area
+ const mainContent = document.createElement('main');
+ mainContent.className = 'main-content';
+
+ let pageContent;
+ switch (hash) {
+ case '#dashboard':
+ pageContent = renderDashboard();
+ break;
+ case '#test':
+ pageContent = renderTestPage();
+ break;
+ default:
+ // For unregistered routes, redirect to dashboard
window.location.hash = '#dashboard';
- }));
- break;
- case '#dashboard':
- app.appendChild(renderDashboard());
- break;
- default:
- window.location.hash = '#login';
+ return;
+ }
+
+ mainContent.appendChild(pageContent);
+ layout.appendChild(sidebar);
+ layout.appendChild(mainContent);
+ app.appendChild(layout);
+ } else {
+ // For login page, no sidebar
+ switch (hash) {
+ case '#login':
+ app.appendChild(renderLoginPage(() => {
+ window.location.hash = '#dashboard';
+ }));
+ break;
+ default:
+ window.location.hash = '#login';
+ }
}
}
diff --git a/src/style.css b/src/style.css
index 16aad82..17b2db5 100644
--- a/src/style.css
+++ b/src/style.css
@@ -37,8 +37,6 @@ a:hover {
body {
margin: 0;
- display: flex;
- place-items: center;
min-width: 320px;
min-height: 100vh;
}
@@ -49,10 +47,8 @@ h1 {
}
#app {
- max-width: 1280px;
- margin: 0 auto;
- padding: 2rem;
- text-align: center;
+ width: 100%;
+ min-height: 100vh;
}
.logo {
@@ -283,3 +279,198 @@ button:focus-visible {
.card-stat.negative .card-stat-value {
color: var(--danger);
}
+
+/* App Layout with Sidebar */
+.app-layout {
+ display: flex;
+ min-height: 100vh;
+ width: 100%;
+}
+
+/* Sidebar Styles */
+.sidebar {
+ width: 250px;
+ background-color: var(--card-bg);
+ border-right: 1px solid var(--border-color);
+ display: flex;
+ flex-direction: column;
+ transition: width 0.3s ease, transform 0.3s ease;
+ position: relative;
+ z-index: 100;
+}
+
+.sidebar-header {
+ padding: 1.5rem 1rem;
+ border-bottom: 1px solid var(--border-color);
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.sidebar-header h2 {
+ margin: 0;
+ font-size: 1.5rem;
+ color: var(--text-primary);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.sidebar-toggle {
+ background: transparent;
+ border: none;
+ cursor: pointer;
+ padding: 0.5rem;
+ color: var(--text-secondary);
+ font-size: 1.25rem;
+ border-radius: 4px;
+ transition: background-color 0.2s;
+}
+
+.sidebar-toggle:hover {
+ background-color: var(--border-color);
+ border-color: transparent;
+}
+
+.sidebar-nav {
+ flex: 1;
+ overflow-y: auto;
+ padding: 1rem 0;
+}
+
+.sidebar-menu {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.sidebar-menu li {
+ margin: 0;
+}
+
+.sidebar-link {
+ display: flex;
+ align-items: center;
+ padding: 0.75rem 1rem;
+ color: var(--text-secondary);
+ text-decoration: none;
+ transition: background-color 0.2s, color 0.2s;
+ cursor: pointer;
+}
+
+.sidebar-link:hover {
+ background-color: var(--border-color);
+ color: var(--text-primary);
+}
+
+.sidebar-link.active {
+ background-color: rgba(37, 99, 235, 0.1);
+ color: var(--primary);
+ border-left: 3px solid var(--primary);
+}
+
+.sidebar-icon {
+ font-size: 1.25rem;
+ margin-right: 0.75rem;
+ min-width: 1.5rem;
+ text-align: center;
+}
+
+.sidebar-text {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+/* Collapsed Sidebar State */
+.sidebar.collapsed {
+ width: 70px;
+}
+
+.sidebar.collapsed .sidebar-header h2,
+.sidebar.collapsed .sidebar-text {
+ opacity: 0;
+ width: 0;
+ overflow: hidden;
+}
+
+.sidebar.collapsed .sidebar-icon {
+ margin-right: 0;
+}
+
+/* Main Content Area */
+.main-content {
+ flex: 1;
+ overflow-y: auto;
+ background-color: #f8fafc;
+}
+
+.main-content > div {
+ max-width: 1280px;
+ margin: 0 auto;
+ padding: 2rem;
+}
+
+/* Responsive Design */
+@media (max-width: 768px) {
+ .sidebar {
+ position: fixed;
+ left: 0;
+ top: 0;
+ bottom: 0;
+ z-index: 1000;
+ transform: translateX(0);
+ }
+
+ .sidebar.collapsed {
+ transform: translateX(-100%);
+ width: 250px;
+ }
+
+ .main-content {
+ margin-left: 0;
+ }
+}
+
+/* Test Page Styles */
+.test-page {
+ padding: 2rem;
+}
+
+.test-page h1 {
+ color: var(--text-primary);
+ margin-bottom: 1rem;
+ font-size: 2rem;
+}
+
+.test-content {
+ background: var(--card-bg);
+ padding: 2rem;
+ border-radius: 12px;
+ border: 1px solid var(--border-color);
+ margin-top: 1rem;
+}
+
+.test-button {
+ background-color: var(--success);
+ color: white;
+ padding: 0.5rem 1rem;
+ border: none;
+ border-radius: 6px;
+ cursor: pointer;
+ margin-top: 1rem;
+}
+
+.test-button:hover {
+ background-color: var(--success-hover);
+ border-color: transparent;
+}
+
+/* Adjust dashboard and login for new layout */
+.login-container {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ min-height: 100vh;
+ width: 100%;
+}