Improve side panel

This commit is contained in:
Simon Stürz 2025-11-12 16:53:28 +01:00
parent 655cdefa8f
commit 7b408be5fa

View File

@ -16,6 +16,7 @@
--muted-text-color: #3342538a; --muted-text-color: #3342538a;
--green-color: #2ecc71; --green-color: #2ecc71;
--red-color: #e30a18; --red-color: #e30a18;
--sidebar-width: clamp(200px, 22vw, 320px);
} }
* { * {
@ -30,13 +31,30 @@
min-height: 100vh; min-height: 100vh;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: auto;
}
.app-layout {
flex: 1;
display: grid;
grid-template-columns: var(--sidebar-width) minmax(0, 1fr);
grid-template-rows: auto minmax(0, 1fr) auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
column-gap: 2rem;
min-height: 100vh;
} }
header { header {
grid-area: header;
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
color: #ffffff; color: #ffffff;
padding: 2rem 1.5rem; padding: 2rem 1.5rem;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
position: relative;
z-index: 2;
} }
.header-bar { .header-bar {
@ -133,29 +151,28 @@
} }
main { main {
flex: 1; grid-area: main;
width: 100%; padding: 2rem 2.5rem;
padding: 2rem 1rem 3rem; display: flex;
} flex-direction: column;
min-height: 0;
.app-shell { overflow: visible;
width: min(1200px, 100%);
margin: 0 auto;
display: grid;
grid-template-columns: minmax(220px, 260px) 1fr;
gap: 1.5rem;
align-items: start;
} }
.side-panel { .side-panel {
grid-area: sidebar;
height: auto;
background: var(--surface-color); background: var(--surface-color);
border-radius: 18px; border-radius: 0;
padding: 1.5rem; padding: 1.5rem;
box-shadow: 0 18px 35px rgba(0, 0, 0, 0.08); box-shadow: 0 18px 35px rgba(0, 0, 0, 0.08);
border: 1px solid rgba(0, 0, 0, 0.04); border: 1px solid rgba(0, 0, 0, 0.04);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 1.5rem; gap: 1.5rem;
align-self: stretch;
overflow: visible;
min-height: 0;
} }
.side-panel-header h2 { .side-panel-header h2 {
@ -223,6 +240,10 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 1.5rem; gap: 1.5rem;
max-width: 1100px;
margin: 0 auto;
width: 100%;
flex: 1 1 auto;
} }
.content-panel { .content-panel {
@ -373,21 +394,23 @@
} }
footer { footer {
grid-area: footer;
text-align: center; text-align: center;
padding: 1.25rem 1rem; padding: 1.25rem 1rem;
background: #ffffff; background: #ffffff;
border-top: 1px solid #d3dce6; border-top: 1px solid #d3dce6;
font-size: 0.9rem; font-size: 0.9rem;
color: var(--muted-text-color); color: var(--muted-text-color);
position: relative;
z-index: 2;
} }
body.needs-auth { body.needs-auth {
background: var(--surface-color); background: var(--surface-color);
overflow: auto;
} }
body.needs-auth header, body.needs-auth .app-layout {
body.needs-auth main,
body.needs-auth footer {
display: none; display: none;
} }
@ -506,70 +529,88 @@
background: rgba(255, 255, 255, 0.12); background: rgba(255, 255, 255, 0.12);
} }
@media (max-width: 960px) { @media (max-width: 1100px) {
.app-shell { :root {
grid-template-columns: 1fr; --sidebar-width: clamp(180px, 26vw, 280px);
}
}
@media (max-width: 820px) {
:root {
--sidebar-width: clamp(160px, 34vw, 220px);
} }
.side-panel { main {
flex-direction: column; padding: 1.5rem;
}
.app-layout {
column-gap: 1.5rem;
} }
} }
@media (max-width: 640px) { @media (max-width: 640px) {
.side-nav { :root {
flex-direction: column; --sidebar-width: clamp(140px, 40vw, 200px);
}
main {
padding: 1.25rem;
}
.app-layout {
column-gap: 1rem;
} }
} }
</style> </style>
</head> </head>
<body class="needs-auth"> <body class="needs-auth">
<header> <div class="app-layout">
<div class="header-bar"> <header>
<div class="brand"> <div class="header-bar">
<img src="styles/pce/icon.svg" alt="EV Dash logo" class="brand-logo"> <div class="brand">
<div class="brand-text"> <img src="styles/pce/icon.svg" alt="EV Dash logo" class="brand-logo">
<h1>EV Dash</h1> <div class="brand-text">
<p>Monitor & troubleshoot EV chargers.</p> <h1>EV Dash</h1>
<p>Monitor & troubleshoot EV chargers.</p>
</div>
</div>
<div class="session-panel">
<p class="status-indicator">
<span id="statusDot" class="status-dot connecting" aria-hidden="true"></span>
<span id="connectionStatus">Awaiting login…</span>
</p>
<div class="session-user">
<img src="icons/user.svg" alt="" aria-hidden="true" class="session-user-icon">
<span id="sessionUsername">Awaiting login…</span>
</div>
<button type="button" id="logoutButton" class="ghost hidden">Logout</button>
</div> </div>
</div> </div>
<div class="session-panel"> </header>
<p class="status-indicator">
<span id="statusDot" class="status-dot connecting" aria-hidden="true"></span> <aside class="side-panel" aria-label="Dashboard sections">
<span id="connectionStatus">Awaiting login…</span> <div class="side-panel-header">
</p> <p class="eyebrow">Workspace</p>
<div class="session-user"> <h2>Overview</h2>
<img src="icons/user.svg" alt="" aria-hidden="true" class="session-user-icon"> <p>Switch between live status and built-in documentation.</p>
<span id="sessionUsername">Awaiting login…</span>
</div>
<button type="button" id="logoutButton" class="ghost hidden">Logout</button>
</div> </div>
</div> <nav class="side-nav" aria-label="Sections">
</header> <button type="button" class="side-nav-button active" data-panel-target="chargers" aria-pressed="true">
<span>Chargers</span>
<main> <span class="side-nav-subtitle">Live table & telemetry</span>
<div class="app-shell"> </button>
<aside class="side-panel" aria-label="Dashboard sections"> <button type="button" class="side-nav-button" data-panel-target="help" aria-pressed="false">
<div class="side-panel-header"> <span>Help</span>
<p class="eyebrow">Workspace</p> <span class="side-nav-subtitle">API contract & logs</span>
<h2>Overview</h2> </button>
<p>Switch between live status and built-in documentation.</p> </nav>
</div> <div class="side-panel-footer">
<nav class="side-nav" aria-label="Sections"> Built for nymea experience plugins.
<button type="button" class="side-nav-button active" data-panel-target="chargers" aria-pressed="true"> </div>
<span>Chargers</span> </aside>
<span class="side-nav-subtitle">Live table & telemetry</span>
</button>
<button type="button" class="side-nav-button" data-panel-target="help" aria-pressed="false">
<span>Help</span>
<span class="side-nav-subtitle">API contract & logs</span>
</button>
</nav>
<div class="side-panel-footer">
Built for nymea experience plugins.
</div>
</aside>
<main>
<section class="content-area"> <section class="content-area">
<section class="content-panel active" data-panel="chargers" aria-labelledby="chargersTitle" aria-hidden="false"> <section class="content-panel active" data-panel="chargers" aria-labelledby="chargersTitle" aria-hidden="false">
<article class="card"> <article class="card">
@ -652,8 +693,12 @@
</article> </article>
</section> </section>
</section> </section>
</div> </main>
</main>
<footer>
<span id="appVersion">EV Dash</span> · &copy; 2025 chargebyte GmbH. All rights reserved.
</footer>
</div>
<section id="loginOverlay" class="login-view" aria-labelledby="loginTitle"> <section id="loginOverlay" class="login-view" aria-labelledby="loginTitle">
<div class="login-panel"> <div class="login-panel">
@ -673,10 +718,6 @@
</div> </div>
</section> </section>
<footer>
<span id="appVersion">EV Dash</span> · &copy; 2025 chargebyte GmbH. All rights reserved.
</footer>
<script src="app.js"></script> <script src="app.js"></script>
</body> </body>
</html> </html>