This commit is contained in:
Tizian.Breuch
2025-09-17 13:02:27 +02:00
parent 7e5939868b
commit a7d0f44d20
18 changed files with 929 additions and 149 deletions

View File

@@ -1,66 +1,152 @@
/* Verschieben Sie alle .sidebar... und .nav-item... Klassen aus styles.css hierher */
/* Globale Variablen für einfachere Wartung */
:host {
display: block;
--sidebar-width-expanded: 280px;
--sidebar-width-collapsed: 96px;
--sidebar-padding: 1rem;
--sidebar-margin: 1rem;
--transition-speed: 0.3s;
--transition-ease: ease-in-out;
}
/* 1. Der Sidebar-Container */
.sidebar {
width: 260px;
height: 100vh;
position: sticky;
top: 0;
position: relative;
display: flex;
flex-direction: column;
padding: 1.5rem;
background: var(--glass-bg);
backdrop-filter: var(--glass-backdrop-filter);
-webkit-backdrop-filter: var(--glass-backdrop-filter);
border-right: 1px solid var(--color-border);
transition: background-color var(--transition-speed),
border-color var(--transition-speed);
gap: 2rem;
width: var(--sidebar-width-expanded);
height: calc(100vh - (var(--sidebar-margin) * 2));
margin: var(--sidebar-margin);
padding: var(--sidebar-padding);
background-color: #fff;
border: 1px solid #e5e7eb; /* Helle Umrandung */
border-radius: 1rem;
transition: width var(--transition-speed) var(--transition-ease);
}
/* 2. Der Header-Bereich */
.sidebar-header {
margin-bottom: 2rem;
display: flex;
align-items: center;
gap: 0.75rem; /* Abstand zwischen Logo und Titel */
padding: 0.5rem;
}
.sidebar-logo {
flex-shrink: 0;
width: 32px;
height: 32px;
color: #111827;
}
.sidebar-title {
font-size: 1.5rem;
font-weight: 900;
margin: 0;
font-size: 1.25rem;
font-weight: 600;
white-space: nowrap;
opacity: 1;
overflow: hidden;
transition: opacity 0.2s ease-in-out,
width 0.3s ease-in-out 0.05s,
transform 0.3s ease-in-out;
}
/* ======================================================= */
/* --- HIER PASSIERT DIE MAGIE FÜR DEN BUTTON --- */
/* ======================================================= */
.sidebar-header app-button {
/* Weist den Button an, den gesamten verfügbaren Platz als linken Abstand zu nutzen */
margin-left: auto;
/* Verhindert, dass der Button schrumpft */
flex-shrink: 0;
/* Fügt eine sanfte Drehanimation hinzu */
transition: transform var(--transition-speed) var(--transition-ease);
transform: rotate(0deg); /* Startposition der Animation */
}
/* 3. Die Navigation (angepasst an das neue Design) */
.sidebar-nav {
display: flex;
flex-direction: column;
gap: 0.5rem;
flex-grow: 1;
}
.sidebar-footer {
margin-top: auto;
flex-grow: 1; /* Nimmt den restlichen vertikalen Platz ein */
}
.nav-item {
display: flex;
align-items: center;
gap: 1rem;
gap: 0.75rem;
padding: 0.75rem 1rem;
border-radius: var(--border-radius-md);
color: var(--color-text-light);
font-weight: 500;
border-radius: 0.5rem;
text-decoration: none;
transition: all var(--transition-speed);
}
.nav-item app-icon {
font-size: 20px; /* Steuert die Größe des Icons */
transition: color var(--transition-speed);
font-weight: 500;
color: #4b5563;
white-space: nowrap;
transition: background-color 0.2s, color 0.2s;
}
.nav-item:hover {
background-color: rgba(0, 0, 0, 0.05);
color: var(--color-text);
}
:host-context(body.dark-theme) .nav-item:hover {
background-color: rgba(255, 255, 255, 0.05);
background-color: #f3f4f6;
}
.nav-item.active {
background: var(--color-primary-gradient);
background-color: #3b82f6;
color: #fff;
box-shadow: 0 4px 10px rgba(52, 152, 219, 0.4);
}
.nav-item.active app-icon {
color: #fff;
.nav-item app-icon {
font-size: 1.25rem;
}
.sidebar-footer {
margin-top: auto; /* Schiebt den Footer nach unten */
}
/* ======================================================= */
/* --- Stile für den eingeklappten Zustand (.collapsed) --- */
/* ======================================================= */
.sidebar.collapsed {
width: var(--sidebar-width-collapsed);
}
.sidebar.collapsed .sidebar-header {
justify-content: center; /* Zentriert das Logo, wenn der Titel weg ist */
}
.sidebar.collapsed .sidebar-title {
opacity: 0;
width: 0; /* Wichtig: expliziter Endwert für die Breiten-Animation */
transform: translateX(-10px); /* Leichte Bewegung nach links */
pointer-events: none;
}
/* Dreht den Button um 180 Grad, wenn die Sidebar eingeklappt ist */
.sidebar.collapsed .sidebar-header app-button {
transform: rotate(180deg);
margin-left: 0; /* Setzt den Margin zurück, da 'justify-content' jetzt die Positionierung übernimmt */
}
.sidebar.collapsed .nav-item {
justify-content: center;
}
.nav-item span {
white-space: nowrap;
opacity: 1;
/* === NEU: Präzise Transition auch hier === */
overflow: hidden;
transition: opacity 0.2s ease-in-out,
width 0.3s ease-in-out 0.05s;
}
.sidebar.collapsed .nav-item span {
opacity: 0;
width: 0; /* Wichtig: expliziter Endwert für die Breiten-Animation */
pointer-events: none;
}

View File

@@ -1,13 +1,33 @@
<aside class="sidebar">
<aside class="sidebar" [class.collapsed]="isCollapsed">
<div class="sidebar-header">
<h1 class="sidebar-title">CustomDash</h1>
<div class="sidebar-logo">
<!-- Ersetzen Sie dies durch Ihr Logo, z.B. als <img> oder <svg> -->
<svg
viewBox="0 0 48 48"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
>
<path
d="M24 8C19.2 8 15.2 9.4 12 11.8C15.4 12.8 18.3 15.6 19.4 19C20.6 18.6 21.8 18.4 23 18.4C24.4 18.4 25.6 18.6 26.8 19C27.9 15.6 30.8 12.8 34.2 11.8C31 9.4 27.2 8 24 8ZM11.8 12.2C8.6 14.6 6 18.2 4.6 22.4C7.8 22.8 10.6 24.6 12.4 27.2C11.4 25.4 10.8 23.2 10.6 21C9.4 17.6 10 14.4 11.8 12.2ZM36.2 12.2C38 14.4 38.6 17.6 37.4 21C37.2 23.2 36.6 25.4 35.6 27.2C37.4 24.6 40.2 22.8 43.4 22.4C42 18.2 39.4 14.6 36.2 12.2ZM4.2 24C4 25.2 4 26.4 4 27.8C4 32.8 6 37.4 9.4 40.6C10.2 37.6 12 35 14.4 33C12 30.8 10.2 28.2 9.2 25.4C7.2 25.2 5.4 24.6 4.2 24ZM20.8 27.8C18.4 29.8 16.6 32.4 15.4 35.4C17.6 38.2 20.6 40 24 40C27.4 40 30.4 38.2 32.6 35.4C31.4 32.4 29.6 29.8 27.2 27.8C25.6 29 24.2 29.2 23.2 29.2C22.4 29.2 21.4 29 20.8 27.8ZM38.8 25.4C37.8 28.2 36 30.8 33.6 33C36 35 37.8 37.6 38.6 40.6C42 37.4 44 32.8 44 27.8C44 26.4 44 25.2 43.8 24C42.6 24.6 40.8 25.2 38.8 25.4Z"
/>
</svg>
</div>
<h1 class="sidebar-title">Wetask</h1>
<app-button
buttonType="icon"
iconName="double_arrow"
(click)="toggleSidebar()"
></app-button>
</div>
<!-- 2. Der Button zum Ein- und Ausklappen. Er ruft unsere neue Methode auf. -->
<nav class="sidebar-nav">
<a
class="nav-item"
[class.active]="activeRoute === 'dashboard'"
(click)="setActive('dashboard')"
title="Übersicht"
>
<app-icon name="placeholder"></app-icon>
<span>Übersicht</span>
@@ -17,6 +37,7 @@
class="nav-item"
[class.active]="activeRoute === 'analytics'"
(click)="setActive('analytics')"
title="Analysen"
>
<app-icon name="placeholder"></app-icon>
<span>Analysen</span>
@@ -26,6 +47,7 @@
class="nav-item"
[class.active]="activeRoute === 'reports'"
(click)="setActive('reports')"
title="Berichte"
>
<app-icon name="placeholder"></app-icon>
<span>Berichte</span>
@@ -37,6 +59,7 @@
class="nav-item"
[class.active]="activeRoute === 'settings'"
(click)="setActive('settings')"
title="Einstellungen"
>
<app-icon name="placeholder"></app-icon>
<span>Einstellungen</span>

View File

@@ -1,21 +1,29 @@
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { IconComponent } from '../../ui/icon/icon.component';
import { ButtonComponent } from '../../ui/button/button.component';
@Component({
selector: 'app-sidebar',
standalone: true,
imports: [CommonModule, IconComponent],
imports: [CommonModule, IconComponent,ButtonComponent],
templateUrl: './sidebar.component.html',
styleUrl: './sidebar.component.css'
})
export class SidebarComponent {
// Wir verwalten nur noch, welcher Link aktiv ist. 'dashboard' ist der Standard.
// Dummy-Eigenschaft für die aktive Route, damit der Code funktioniert
activeRoute = 'dashboard';
// Methode, um den aktiven Link bei einem Klick zu ändern.
// In einer echten App würde dies durch den Angular Router gesteuert werden.
// NEU: Eigenschaft, um den Zustand der Sidebar zu speichern
public isCollapsed = false;
// Dummy-Methode, damit der Code funktioniert
setActive(route: string): void {
this.activeRoute = route;
}
// NEU: Methode, um den Zustand umzuschalten
toggleSidebar(): void {
this.isCollapsed = !this.isCollapsed;
}
}