tuning the sidebar

This commit is contained in:
buenosairesam
2026-01-27 00:32:06 -03:00
parent fecb978a5f
commit e1f81889fc
3 changed files with 168 additions and 147 deletions

View File

@@ -41,7 +41,7 @@
flex-direction: column;
align-items: center;
padding: 1rem 0;
z-index: 1000;
z-index: 99999;
}
.sidebar-item {
width: 44px;
@@ -55,7 +55,7 @@
color: #a3a3a3;
transition: all 0.2s;
}
.sidebar-item:hover {
a.sidebar-item:hover {
background: #333;
color: white;
}
@@ -73,6 +73,19 @@
background: #333;
margin: 0.5rem 0;
}
.sidebar-icon {
width: 44px;
height: 44px;
display: flex;
align-items: center;
justify-content: center;
color: #555;
margin-bottom: 0.5rem;
}
.sidebar-icon svg {
width: 20px;
height: 20px;
}
.sidebar-item .tooltip {
position: absolute;
left: 70px;
@@ -227,30 +240,29 @@
<span class="tooltip">Soleprint</span>
</a>
<a href="/artery" class="sidebar-item" title="Artery">
<div class="sidebar-divider"></div>
<div class="sidebar-icon" title="Artery">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M12 2v8M12 10L6 18M12 10l6 8"/>
<circle cx="12" cy="10" r="2"/>
</svg>
<span class="tooltip">Artery</span>
</a>
</div>
<a href="/atlas" class="sidebar-item" title="Atlas">
<div class="sidebar-icon" title="Atlas">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="8"/>
<path d="M12 4v16M4 12h16"/>
</svg>
<span class="tooltip">Atlas</span>
</a>
</div>
<a href="/station" class="sidebar-item" title="Station">
<div class="sidebar-icon" title="Station">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="4" y="6" width="16" height="12" rx="1"/>
<circle cx="9" cy="11" r="2"/>
<circle cx="15" cy="11" r="2"/>
</svg>
<span class="tooltip">Station</span>
</a>
</div>
</nav>
{% endif %}

View File

@@ -1,73 +1,73 @@
/* Soleprint Sidebar - Injected Styles */
:root {
--spr-sidebar-width: 60px;
--spr-sidebar-width-expanded: 280px;
--spr-sidebar-bg: #1a1a1a;
--spr-sidebar-text: #e5e5e5;
--spr-sidebar-text-muted: #a3a3a3;
--spr-sidebar-border: #333;
--spr-sidebar-accent: #d4a574;
--spr-sidebar-hover: #2a2a2a;
}
/* Matches the original Jinja2 sidebar look */
/* Sidebar Container */
#spr-sidebar {
position: fixed;
left: 0;
top: 0;
width: var(--spr-sidebar-width);
left: 0;
width: 60px;
height: 100vh;
background: var(--spr-sidebar-bg);
border-right: 1px solid var(--spr-sidebar-border);
background: #1a1a1a;
border-right: 1px solid #333;
display: flex;
flex-direction: column;
align-items: center;
padding: 1rem 0;
z-index: 99999;
transition: width 0.2s ease;
font-family:
system-ui,
-apple-system,
sans-serif;
transition: width 0.2s ease;
}
#spr-sidebar.expanded {
width: var(--spr-sidebar-width-expanded);
width: 200px;
align-items: flex-start;
padding: 1rem;
}
/* Push page content */
body.spr-sidebar-active {
margin-left: var(--spr-sidebar-width) !important;
margin-left: 60px !important;
transition: margin-left 0.2s ease;
}
body.spr-sidebar-active.spr-sidebar-expanded {
margin-left: var(--spr-sidebar-width-expanded) !important;
margin-left: 200px !important;
}
/* Sidebar Items */
/* Sidebar Items (clickable) */
.spr-sidebar-item {
width: 44px;
height: 44px;
display: flex;
align-items: center;
gap: 12px;
padding: 12px 18px;
color: var(--spr-sidebar-text-muted);
justify-content: center;
border-radius: 8px;
margin-bottom: 0.5rem;
text-decoration: none;
transition: all 0.15s;
cursor: pointer;
border: none;
background: none;
color: #a3a3a3;
transition: all 0.2s;
position: relative;
flex-shrink: 0;
}
#spr-sidebar.expanded .spr-sidebar-item {
width: 100%;
text-align: left;
font-size: 14px;
justify-content: flex-start;
padding: 0 12px;
gap: 12px;
}
.spr-sidebar-item:hover {
background: var(--spr-sidebar-hover);
color: var(--spr-sidebar-text);
background: #333;
color: white;
}
.spr-sidebar-item.active {
background: var(--spr-sidebar-accent);
background: #d4a574;
color: #0a0a0a;
}
@@ -77,8 +77,10 @@ body.spr-sidebar-active.spr-sidebar-expanded {
flex-shrink: 0;
}
/* Label (hidden when collapsed) */
.spr-sidebar-item .label {
display: none;
font-size: 0.9rem;
white-space: nowrap;
}
@@ -86,76 +88,94 @@ body.spr-sidebar-active.spr-sidebar-expanded {
display: inline;
}
/* Divider */
.spr-sidebar-divider {
height: 1px;
background: var(--spr-sidebar-border);
margin: 8px 16px;
/* Tooltip (hidden when expanded) */
.spr-sidebar-item .tooltip {
position: absolute;
left: 54px;
background: #333;
color: white;
padding: 0.5rem 0.75rem;
border-radius: 4px;
font-size: 0.85rem;
white-space: nowrap;
opacity: 0;
pointer-events: none;
transition: opacity 0.2s;
}
/* Spacer */
.spr-sidebar-item:hover .tooltip {
opacity: 1;
}
#spr-sidebar.expanded .spr-sidebar-item .tooltip {
display: none;
}
/* Toggle button */
.spr-toggle {
border: none;
background: none;
cursor: pointer;
}
/* Divider */
.spr-sidebar-divider {
width: 32px;
height: 1px;
background: #333;
margin: 0.5rem 0;
}
/* Decorative icons (non-clickable) */
.spr-sidebar-icon {
width: 44px;
height: 44px;
display: flex;
align-items: center;
justify-content: center;
color: #555;
margin-bottom: 0.5rem;
}
.spr-sidebar-icon svg {
width: 20px;
height: 20px;
}
/* Spacer to push auth to bottom */
.spr-sidebar-spacer {
flex: 1;
}
/* User Section */
/* User/Auth Section */
.spr-sidebar-user {
padding: 12px 16px;
border-top: 1px solid var(--spr-sidebar-border);
font-size: 12px;
color: var(--spr-sidebar-text-muted);
}
.spr-sidebar-user .email {
display: none;
margin-top: 4px;
color: var(--spr-sidebar-text);
}
#spr-sidebar.expanded .spr-sidebar-user .email {
display: block;
margin-top: auto;
display: flex;
flex-direction: column;
align-items: center;
}
/* Login Button */
.spr-login-btn {
width: 44px;
height: 44px;
display: flex;
align-items: center;
gap: 8px;
padding: 8px 12px;
background: #4285f4;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 13px;
width: 100%;
justify-content: center;
border-radius: 8px;
background: none;
border: none;
cursor: pointer;
color: #a3a3a3;
transition: all 0.2s;
}
.spr-login-btn:hover {
background: #3367d6;
background: #333;
color: white;
}
.spr-login-btn svg {
width: 18px;
height: 18px;
}
/* Header with room name */
.spr-sidebar-header {
padding: 16px;
border-bottom: 1px solid var(--spr-sidebar-border);
}
.spr-sidebar-header .room-name {
display: none;
font-size: 12px;
text-transform: uppercase;
letter-spacing: 1px;
color: var(--spr-sidebar-accent);
margin-top: 8px;
}
#spr-sidebar.expanded .spr-sidebar-header .room-name {
display: block;
width: 24px;
height: 24px;
}

View File

@@ -1,5 +1,5 @@
// Soleprint Sidebar - Self-Injecting Script
// This script creates and manages the soleprint sidebar when injected into a managed app
// Matches the original Jinja2 sidebar look
(function () {
"use strict";
@@ -8,12 +8,14 @@
let config = null;
let user = null;
let expanded = localStorage.getItem("spr_sidebar_expanded") === "true";
// Icons as SVG strings
const icons = {
toggle: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M4 6h16M4 12h16M4 18h16"/>
<rect x="3" y="3" width="18" height="18" rx="2"/>
<path d="M9 3v18M3 9h6"/>
</svg>`,
home: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M3 12l9-9 9 9M5 10v10a1 1 0 001 1h3m10-11v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1"/>
@@ -64,14 +66,6 @@
// Create sidebar
createSidebar();
// Setup keyboard shortcut
document.addEventListener("keydown", (e) => {
if (e.ctrlKey && e.shiftKey && e.key === "S") {
e.preventDefault();
toggleSidebar();
}
});
console.log("[Soleprint] Sidebar initialized for room:", config.room);
} catch (error) {
console.error("[Soleprint] Failed to initialize sidebar:", error);
@@ -101,95 +95,90 @@
document.body.classList.add("spr-sidebar-expanded");
}
const sidebar = document.createElement("div");
const sidebar = document.createElement("nav");
sidebar.id = "spr-sidebar";
if (expanded) sidebar.classList.add("expanded");
sidebar.innerHTML = `
<div class="spr-sidebar-header">
<button class="spr-sidebar-item" onclick="sprSidebar.toggle()" title="Toggle sidebar (Ctrl+Shift+S)">
<button class="spr-sidebar-item spr-toggle" title="Toggle sidebar">
${icons.toggle}
<span class="label">Menu</span>
<span class="tooltip">Toggle</span>
</button>
<div class="room-name">${config.room}</div>
</div>
<a href="/" class="spr-sidebar-item" title="Home">
<a href="/" class="spr-sidebar-item" title="${config.room}">
${icons.home}
<span class="label">Home</span>
<span class="label">${config.room}</span>
<span class="tooltip">${config.room}</span>
</a>
<div class="spr-sidebar-divider"></div>
<a href="${SPR_BASE}/" class="spr-sidebar-item" title="Soleprint">
<a href="${SPR_BASE}/" class="spr-sidebar-item active" title="Soleprint">
${icons.soleprint}
<span class="label">Soleprint</span>
<span class="tooltip">Soleprint</span>
</a>
<a href="${config.tools.artery}" class="spr-sidebar-item" title="Artery">
<div class="spr-sidebar-divider"></div>
<div class="spr-sidebar-icon" title="Artery">
${icons.artery}
<span class="label">Artery</span>
</a>
</div>
<a href="${config.tools.atlas}" class="spr-sidebar-item" title="Atlas">
<div class="spr-sidebar-icon" title="Atlas">
${icons.atlas}
<span class="label">Atlas</span>
</a>
</div>
<a href="${config.tools.station}" class="spr-sidebar-item" title="Station">
<div class="spr-sidebar-icon" title="Station">
${icons.station}
<span class="label">Station</span>
</a>
</div>
<div class="spr-sidebar-spacer"></div>
${config.auth_enabled ? renderAuthSection() : ""}
`;
// Add toggle click handler
sidebar
.querySelector(".spr-toggle")
.addEventListener("click", toggleSidebar);
document.body.appendChild(sidebar);
}
function toggleSidebar() {
const sidebar = document.getElementById("spr-sidebar");
expanded = !expanded;
sidebar.classList.toggle("expanded", expanded);
document.body.classList.toggle("spr-sidebar-expanded", expanded);
localStorage.setItem("spr_sidebar_expanded", expanded);
}
function renderAuthSection() {
if (user) {
return `
<div class="spr-sidebar-user">
<div class="spr-sidebar-item" title="${user.email}">
${icons.user}
<span class="label">${user.email}</span>
</div>
<a href="${config.auth.logout_url}" class="spr-sidebar-item" title="Logout">
<a href="${config.auth.logout_url}" class="spr-sidebar-item" title="Logout (${user.email})">
${icons.logout}
<span class="label">Logout</span>
<span class="tooltip">Logout</span>
</a>
</div>
`;
} else {
return `
<div class="spr-sidebar-user">
<a href="${config.auth.login_url}" class="spr-sidebar-item spr-login-btn" title="Login with Google">
<a href="${config.auth.login_url}" class="spr-sidebar-item" title="Login with Google">
${icons.google}
<span class="label">Login with Google</span>
<span class="label">Login</span>
<span class="tooltip">Login</span>
</a>
</div>
`;
}
}
function toggleSidebar() {
const sidebar = document.getElementById("spr-sidebar");
expanded = !expanded;
sidebar.classList.toggle("expanded", expanded);
document.body.classList.toggle("spr-sidebar-expanded", expanded);
localStorage.setItem("spr_sidebar_expanded", expanded);
}
// Expose to global scope for onclick handlers
window.sprSidebar = {
toggle: toggleSidebar,
};
// Initialize when DOM is ready
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);