styles
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
|
||||||
|
|
||||||
<div class="auth-container">
|
<div class="auth-container">
|
||||||
<div class="auth-card card">
|
<div class="auth-card card">
|
||||||
<div class="auth-header">
|
<div class="auth-header">
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { RouterOutlet } from '@angular/router';
|
import { RouterOutlet } from '@angular/router';
|
||||||
|
import { CardComponent } from '../../../../shared/components/ui/card/card.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-auth-layout',
|
selector: 'app-auth-layout',
|
||||||
imports: [
|
imports: [RouterOutlet, CardComponent],
|
||||||
RouterOutlet
|
|
||||||
],
|
|
||||||
templateUrl: './auth-layout.component.html',
|
templateUrl: './auth-layout.component.html',
|
||||||
styleUrl: './auth-layout.component.css'
|
styleUrl: './auth-layout.component.css',
|
||||||
})
|
})
|
||||||
export class AuthLayoutComponent {
|
export class AuthLayoutComponent {
|
||||||
// Diese Komponente benötigt in der Regel keine eigene Logik.
|
// Diese Komponente benötigt in der Regel keine eigene Logik.
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
/* src\app\features\auth\components\login\login.component.css */
|
|
||||||
@import '../../_auth-common.css';
|
|
||||||
|
|
||||||
/* Stile NUR für die Login-Seite */
|
|
||||||
:host { display: block; width: 100%; }
|
|
||||||
|
|
||||||
.form-actions {
|
|
||||||
text-align: right;
|
|
||||||
margin-top: -0.75rem;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
@@ -1,16 +1,26 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
// WICHTIG: ReactiveFormsModule HIER importieren
|
import {
|
||||||
import { ReactiveFormsModule, FormBuilder, Validators, FormGroup } from '@angular/forms';
|
ReactiveFormsModule,
|
||||||
|
FormBuilder,
|
||||||
|
Validators,
|
||||||
|
FormGroup,
|
||||||
|
} from '@angular/forms';
|
||||||
import { RouterLink } from '@angular/router';
|
import { RouterLink } from '@angular/router';
|
||||||
|
|
||||||
|
// Importieren der wiederverwendbaren Komponenten
|
||||||
|
import { ButtonComponent } from '../../../../shared/components/ui/button/button.component';
|
||||||
|
import { FormFieldComponent } from '../../../../shared/components/form/form-field/form-field.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-login',
|
selector: 'app-login',
|
||||||
|
standalone: true,
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
RouterLink,
|
RouterLink,
|
||||||
ReactiveFormsModule // <-- HIER IST DIE KORREKTUR. Jetzt kennt die Komponente [formGroup].
|
ButtonComponent,
|
||||||
|
FormFieldComponent,
|
||||||
],
|
],
|
||||||
templateUrl: './login.component.html',
|
templateUrl: './login.component.html',
|
||||||
styleUrl: './login.component.css',
|
styleUrl: './login.component.css',
|
||||||
|
|||||||
@@ -1,24 +1,19 @@
|
|||||||
<main>
|
<main>
|
||||||
<app-slide-toggle
|
<div class="grid-col-span-4">
|
||||||
label="Dark Mode"
|
<app-page-header></app-page-header>
|
||||||
[ngModel]="darkModeAktiv"
|
|
||||||
(ngModelChange)="onDarkModeChange($event)"
|
|
||||||
name="mainDarkModeToggle"
|
|
||||||
></app-slide-toggle>
|
|
||||||
|
|
||||||
<div class="dashboard-grid grid-col-span-4">
|
|
||||||
<app-kpi-card
|
|
||||||
*ngFor="let kpi of kpiData"
|
|
||||||
[value]="kpi.value"
|
|
||||||
[label]="kpi.label"
|
|
||||||
[color]="kpi.color"
|
|
||||||
[iconName]="kpi.iconName"
|
|
||||||
>
|
|
||||||
</app-kpi-card>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<app-kpi-card
|
||||||
|
*ngFor="let kpi of kpiData"
|
||||||
|
[value]="kpi.value"
|
||||||
|
[label]="kpi.label"
|
||||||
|
[color]="kpi.color"
|
||||||
|
[iconName]="kpi.iconName"
|
||||||
|
>
|
||||||
|
</app-kpi-card>
|
||||||
|
|
||||||
<div class="grid-col-span-4">
|
<div class="grid-col-span-4">
|
||||||
<app-form-group title="Table">
|
<app-form-group title="Data-display Components">
|
||||||
<app-orders-table
|
<app-orders-table
|
||||||
[data]="ordersData"
|
[data]="ordersData"
|
||||||
[itemsPerPage]="5"
|
[itemsPerPage]="5"
|
||||||
@@ -32,7 +27,7 @@
|
|||||||
|
|
||||||
<div class="grid-col-span-2">
|
<div class="grid-col-span-2">
|
||||||
<app-form-group
|
<app-form-group
|
||||||
title="Persönliche Daten"
|
title="Form Components 1"
|
||||||
description="Diese Informationen sind öffentlich sichtbar."
|
description="Diese Informationen sind öffentlich sichtbar."
|
||||||
>
|
>
|
||||||
<app-form-select
|
<app-form-select
|
||||||
@@ -55,7 +50,7 @@
|
|||||||
|
|
||||||
<div class="grid-col-span-2">
|
<div class="grid-col-span-2">
|
||||||
<app-form-group
|
<app-form-group
|
||||||
title="Anwendungs-Einstellungen"
|
title="Form Components 2"
|
||||||
description="Diese Informationen sind öffentlich sichtbar."
|
description="Diese Informationen sind öffentlich sichtbar."
|
||||||
>
|
>
|
||||||
<app-slide-toggle
|
<app-slide-toggle
|
||||||
@@ -80,4 +75,106 @@
|
|||||||
></app-slide-toggle>
|
></app-slide-toggle>
|
||||||
</app-form-group>
|
</app-form-group>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-col-span-2">
|
||||||
|
<app-form-group
|
||||||
|
title="Layout Components"
|
||||||
|
description="Diese Informationen sind öffentlich sichtbar."
|
||||||
|
>
|
||||||
|
<app-expansion-panel title="Weitere Details anzeigen...">
|
||||||
|
Dieser Inhalt wird jetzt von einer wiederverwendbaren Komponente
|
||||||
|
gesteuert. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||||
|
</app-expansion-panel>
|
||||||
|
</app-form-group>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-col-span-2">
|
||||||
|
<app-form-group title="Button Components" description="UI Components">
|
||||||
|
<!-- Sektion 1: Standard-Buttons -->
|
||||||
|
<div class="button-group">
|
||||||
|
<app-button buttonType="primary" tooltip="Primäre Aktion"
|
||||||
|
>Primary</app-button
|
||||||
|
>
|
||||||
|
<app-button buttonType="secondary" tooltip="Sekundäre Aktion"
|
||||||
|
>Secondary</app-button
|
||||||
|
>
|
||||||
|
<app-button buttonType="stroked" tooltip="Hervorgehoben"
|
||||||
|
>Stroked</app-button
|
||||||
|
>
|
||||||
|
<app-button buttonType="flat" tooltip="Weniger wichtige Aktion"
|
||||||
|
>Flat</app-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Sektion 2: Buttons mit Icon und Text -->
|
||||||
|
<div class="button-group">
|
||||||
|
<app-button buttonType="primary" iconName="edit">Bearbeiten</app-button>
|
||||||
|
<app-button buttonType="secondary" iconName="shopping_bag"
|
||||||
|
>Zum Warenkorb</app-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Sektion 3: Reine Icon-Buttons -->
|
||||||
|
<div class="button-group">
|
||||||
|
<app-button
|
||||||
|
buttonType="icon"
|
||||||
|
tooltip="Favorit hinzufügen"
|
||||||
|
iconName="favorite"
|
||||||
|
svgColor="red"
|
||||||
|
></app-button>
|
||||||
|
<app-button
|
||||||
|
buttonType="icon"
|
||||||
|
tooltip="Details anzeigen"
|
||||||
|
iconName="eye"
|
||||||
|
></app-button>
|
||||||
|
<app-button
|
||||||
|
buttonType="icon"
|
||||||
|
tooltip="Benutzer"
|
||||||
|
iconName="group"
|
||||||
|
></app-button>
|
||||||
|
<app-button
|
||||||
|
buttonType="icon"
|
||||||
|
tooltip="Performance"
|
||||||
|
iconName="bolt"
|
||||||
|
></app-button>
|
||||||
|
<app-button
|
||||||
|
buttonType="icon-danger"
|
||||||
|
tooltip="Löschen"
|
||||||
|
iconName="delete"
|
||||||
|
></app-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Sektion 4: Paginator Icon-Buttons (Beispiel) -->
|
||||||
|
<div class="button-group">
|
||||||
|
<app-button
|
||||||
|
buttonType="icon"
|
||||||
|
tooltip="Zurück"
|
||||||
|
iconName="chevron_backward"
|
||||||
|
></app-button>
|
||||||
|
<app-button
|
||||||
|
buttonType="icon"
|
||||||
|
tooltip="Weiter"
|
||||||
|
iconName="chevron_forward"
|
||||||
|
></app-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Sektion 5: Deaktivierte Zustände -->
|
||||||
|
<div class="button-group">
|
||||||
|
<app-button buttonType="primary" [disabled]="true"
|
||||||
|
>Deaktiviert</app-button
|
||||||
|
>
|
||||||
|
<app-button
|
||||||
|
buttonType="icon"
|
||||||
|
iconName="money"
|
||||||
|
[disabled]="true"
|
||||||
|
tooltip="Nicht verfügbar"
|
||||||
|
></app-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="chip-set">
|
||||||
|
<app-chip label="Technologie" [removable]="true"></app-chip>
|
||||||
|
<app-chip label="Angular" [active]="true" [removable]="true"></app-chip>
|
||||||
|
</div>
|
||||||
|
</app-form-group>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -32,6 +32,14 @@ import { SlideToggleComponent } from '../../../../shared/components/form/slide-t
|
|||||||
|
|
||||||
import { isPlatformBrowser } from '@angular/common';
|
import { isPlatformBrowser } from '@angular/common';
|
||||||
|
|
||||||
|
import { ExpansionPanelComponent } from '../../../../shared/components/layout/expansion-panel/expansion-panel.component';
|
||||||
|
|
||||||
|
import { PageHeaderComponent } from '../../../../shared/components/layout/page-header/page-header.component';
|
||||||
|
|
||||||
|
import { ButtonComponent } from '../../../../shared/components/ui/button/button.component';
|
||||||
|
|
||||||
|
import { ChipComponent } from '../../../../shared/components/ui/chip/chip.component';
|
||||||
|
|
||||||
// Wir definieren ein Interface für unsere KPI-Daten für Typsicherheit
|
// Wir definieren ein Interface für unsere KPI-Daten für Typsicherheit
|
||||||
interface Kpi {
|
interface Kpi {
|
||||||
value: string;
|
value: string;
|
||||||
@@ -54,6 +62,10 @@ interface Kpi {
|
|||||||
FormsModule,
|
FormsModule,
|
||||||
FormTextareaComponent,
|
FormTextareaComponent,
|
||||||
SlideToggleComponent,
|
SlideToggleComponent,
|
||||||
|
ExpansionPanelComponent,
|
||||||
|
PageHeaderComponent,
|
||||||
|
ButtonComponent,
|
||||||
|
ChipComponent
|
||||||
],
|
],
|
||||||
templateUrl: './demo2.component.html',
|
templateUrl: './demo2.component.html',
|
||||||
})
|
})
|
||||||
@@ -257,6 +269,7 @@ export class Demo2Component {
|
|||||||
this.renderer.removeClass(this.document.body, 'dark-theme');
|
this.renderer.removeClass(this.document.body, 'dark-theme');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleDeleteOrder(orderId: string): void {
|
handleDeleteOrder(orderId: string): void {
|
||||||
console.log('Lösche Bestellung mit ID:', orderId);
|
console.log('Lösche Bestellung mit ID:', orderId);
|
||||||
// Hier könnten Sie z.B. einen Bestätigungs-Dialog öffnen
|
// Hier könnten Sie z.B. einen Bestätigungs-Dialog öffnen
|
||||||
|
|||||||
@@ -93,7 +93,7 @@
|
|||||||
|
|
||||||
.actions-cell {
|
.actions-cell {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: right;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<th>Bestell-ID</th>
|
<th>Bestell-ID</th>
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
<th class="text-right">Betrag</th>
|
<th class="text-right">Betrag</th>
|
||||||
<th class="text-center">Aktionen</th>
|
<th class="text-right">Aktionen</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
}}</app-status-pill>
|
}}</app-status-pill>
|
||||||
</td>
|
</td>
|
||||||
<td class="amount">{{ order.amount }}</td>
|
<td class="amount">{{ order.amount }}</td>
|
||||||
<td class="actions-cell">
|
<td class="actions-cell text-right">
|
||||||
<app-button
|
<app-button
|
||||||
buttonType="icon"
|
buttonType="icon"
|
||||||
tooltip="Details anzeigen"
|
tooltip="Details anzeigen"
|
||||||
|
|||||||
@@ -1,73 +0,0 @@
|
|||||||
/* =================================================================================
|
|
||||||
* GEMEINSAME BASIS-STILE FÜR ALLE FORMULAR-KOMPONENTEN
|
|
||||||
* ================================================================================= */
|
|
||||||
|
|
||||||
/* Stellt sicher, dass die Host-Komponente als Block-Element gerendert wird */
|
|
||||||
:host {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Der Wrapper für das Label und das Eingabefeld */
|
|
||||||
.form-field {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Das "schwebende" Label */
|
|
||||||
.form-label {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 1rem;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
color: var(--color-text-light);
|
|
||||||
background-color: var(--color-surface);
|
|
||||||
padding: 0 0.25rem;
|
|
||||||
transition: all 0.2s ease-out;
|
|
||||||
pointer-events: none;
|
|
||||||
border-radius: var(--border-radius-sm);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Passt die Hintergrundfarbe des Labels für das Dark Theme an */
|
|
||||||
:host-context(body.dark-theme) .form-label {
|
|
||||||
background-color: var(--color-surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Gemeinsame Stile für <input>, <select> und <textarea> */
|
|
||||||
.form-input {
|
|
||||||
width: 100%;
|
|
||||||
padding: 0.85rem 1rem;
|
|
||||||
border: 1px solid var(--color-border);
|
|
||||||
border-radius: var(--border-radius-md);
|
|
||||||
background-color: var(--color-surface);
|
|
||||||
color: var(--color-text);
|
|
||||||
font-size: 1rem;
|
|
||||||
font-family: inherit; /* Stellt eine einheitliche Schriftart sicher */
|
|
||||||
transition: border-color var(--transition-speed);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fokus-Zustand für alle Eingabefelder */
|
|
||||||
.form-input:focus {
|
|
||||||
outline: none;
|
|
||||||
border-color: var(--color-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Logik, die das Label nach oben bewegt */
|
|
||||||
.form-input:focus ~ .form-label,
|
|
||||||
.form-input:not(:placeholder-shown) ~ .form-label {
|
|
||||||
top: 0;
|
|
||||||
font-size: 0.8rem;
|
|
||||||
color: var(--color-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Spezieller Fix für den Autofill-Hintergrund in Webkit-Browsern (Chrome, Edge) */
|
|
||||||
.form-input:-webkit-autofill ~ .form-label {
|
|
||||||
top: 0;
|
|
||||||
font-size: 0.8rem;
|
|
||||||
color: var(--color-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Layout-Helfer für Formulargruppen */
|
|
||||||
.form-group-inline {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
/* Verschieben Sie diese Stile aus der globalen styles.css hierher */
|
|
||||||
:host {
|
:host {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
@@ -7,20 +6,23 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 2rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* .header-left {
|
||||||
|
Platzhalter für zukünftige Elemente wie Seitentitel oder Breadcrumbs
|
||||||
|
} */
|
||||||
|
|
||||||
.header-actions {
|
.header-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 1.5rem;
|
gap: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Responsivität für den Header */
|
/* Responsivität NUR für den Header */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.main-header {
|
.main-header {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 1rem;
|
gap: 1.5rem; /* Etwas mehr Abstand für mobile Ansicht */
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,15 @@
|
|||||||
<header class="main-header">
|
<header class="main-header">
|
||||||
|
|
||||||
<!-- Linker Bereich: Hier könnte später ein Titel oder Breadcrumbs via ng-content platziert werden -->
|
|
||||||
<div class="header-left">
|
<div class="header-left">
|
||||||
<app-search-bar></app-search-bar>
|
<app-search-bar></app-search-bar>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Rechter Bereich mit den Aktionen -->
|
|
||||||
<div class="header-actions">
|
<div class="header-actions">
|
||||||
<app-theme-switcher></app-theme-switcher>
|
|
||||||
|
<app-slide-toggle
|
||||||
|
label="Dark Mode"
|
||||||
|
[ngModel]="darkModeAktiv"
|
||||||
|
(ngModelChange)="onDarkModeChange($event)"
|
||||||
|
name="mainDarkModeToggle"
|
||||||
|
></app-slide-toggle>
|
||||||
<app-user-profile></app-user-profile>
|
<app-user-profile></app-user-profile>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</header>
|
</header>
|
||||||
@@ -1,8 +1,16 @@
|
|||||||
import { Component, Input } from '@angular/core';
|
import {
|
||||||
import { CommonModule } from '@angular/common';
|
Component,
|
||||||
|
Inject,
|
||||||
|
PLATFORM_ID,
|
||||||
|
Renderer2,
|
||||||
|
OnInit,
|
||||||
|
AfterViewInit,
|
||||||
|
} from '@angular/core';
|
||||||
|
import { CommonModule, DOCUMENT, isPlatformBrowser } from '@angular/common';
|
||||||
import { SearchBarComponent } from '../search-bar/search-bar.component';
|
import { SearchBarComponent } from '../search-bar/search-bar.component';
|
||||||
import { ThemeSwitcherComponent } from '../theme-switcher/theme-switcher.component';
|
|
||||||
import { UserProfileComponent } from '../user-profile/user-profile.component';
|
import { UserProfileComponent } from '../user-profile/user-profile.component';
|
||||||
|
import { SlideToggleComponent } from '../../form/slide-toggle/slide-toggle.component';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-page-header',
|
selector: 'app-page-header',
|
||||||
@@ -10,12 +18,67 @@ import { UserProfileComponent } from '../user-profile/user-profile.component';
|
|||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
SearchBarComponent,
|
SearchBarComponent,
|
||||||
ThemeSwitcherComponent,
|
UserProfileComponent,
|
||||||
UserProfileComponent
|
SlideToggleComponent,
|
||||||
|
FormsModule,
|
||||||
],
|
],
|
||||||
templateUrl: './page-header.component.html',
|
templateUrl: './page-header.component.html',
|
||||||
styleUrl: './page-header.component.css'
|
styleUrl: './page-header.component.css',
|
||||||
})
|
})
|
||||||
export class PageHeaderComponent {
|
export class PageHeaderComponent implements OnInit, AfterViewInit {
|
||||||
// Hier könnten später z.B. der Seitentitel oder Breadcrumbs übergeben werden
|
private readonly darkModeKey = 'app-dark-mode-setting';
|
||||||
|
darkModeAktiv: boolean = false;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private renderer: Renderer2,
|
||||||
|
@Inject(DOCUMENT) private document: Document,
|
||||||
|
@Inject(PLATFORM_ID) private platformId: Object
|
||||||
|
) {}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.loadThemeSetting();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngAfterViewInit(): void {
|
||||||
|
this.updateTheme(this.darkModeAktiv);
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadThemeSetting(): void {
|
||||||
|
if (isPlatformBrowser(this.platformId)) {
|
||||||
|
try {
|
||||||
|
const storedValue = localStorage.getItem(this.darkModeKey);
|
||||||
|
// Setze den Zustand der Komponente basierend auf dem gespeicherten Wert.
|
||||||
|
this.darkModeAktiv = storedValue === 'true';
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Could not access localStorage:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Wende das Theme an - entweder den Standardwert (false) oder den geladenen Wert.
|
||||||
|
this.updateTheme(this.darkModeAktiv);
|
||||||
|
}
|
||||||
|
|
||||||
|
onDarkModeChange(isEnabled: boolean): void {
|
||||||
|
this.darkModeAktiv = isEnabled;
|
||||||
|
|
||||||
|
// --- KORREKTUR 2: Speichere die neue Einstellung ---
|
||||||
|
if (isPlatformBrowser(this.platformId)) {
|
||||||
|
try {
|
||||||
|
localStorage.setItem(this.darkModeKey, String(isEnabled));
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Could not write to localStorage:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wende die visuelle Änderung an.
|
||||||
|
this.updateTheme(isEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method is CORRECT. It just needs to be called.
|
||||||
|
private updateTheme(isEnabled: boolean): void {
|
||||||
|
if (isEnabled) {
|
||||||
|
this.renderer.addClass(this.document.body, 'dark-theme');
|
||||||
|
} else {
|
||||||
|
this.renderer.removeClass(this.document.body, 'dark-theme');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
:host {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-switcher {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 0.75rem;
|
|
||||||
color: var(--color-text-light);
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<div class="theme-switcher">
|
|
||||||
<label>Dark Mode</label>
|
|
||||||
|
|
||||||
<app-slide-toggle [(ngModel)]="isDarkMode" (ngModelChange)="toggleTheme($event)"></app-slide-toggle>
|
|
||||||
</div>
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
import { Component, Renderer2, OnInit } from '@angular/core';
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { FormsModule } from '@angular/forms'; // FormsModule importieren
|
|
||||||
import { SlideToggleComponent } from '../../form/slide-toggle/slide-toggle.component';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-theme-switcher',
|
|
||||||
standalone: true,
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
SlideToggleComponent,
|
|
||||||
FormsModule // <-- HIER IST DIE KORREKTUR
|
|
||||||
],
|
|
||||||
templateUrl: './theme-switcher.component.html',
|
|
||||||
styleUrl: './theme-switcher.component.css'
|
|
||||||
})
|
|
||||||
export class ThemeSwitcherComponent implements OnInit {
|
|
||||||
isDarkMode = false;
|
|
||||||
|
|
||||||
constructor(private renderer: Renderer2) {}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
// Hier könnte man den Zustand aus dem localStorage laden
|
|
||||||
}
|
|
||||||
|
|
||||||
// Die Methode akzeptiert jetzt direkt den neuen boolean-Wert
|
|
||||||
toggleTheme(isDarkMode: boolean): void {
|
|
||||||
this.isDarkMode = isDarkMode;
|
|
||||||
if (this.isDarkMode) {
|
|
||||||
this.renderer.addClass(document.body, 'dark-theme');
|
|
||||||
} else {
|
|
||||||
this.renderer.removeClass(document.body, 'dark-theme');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -84,14 +84,15 @@ body.no-scroll {
|
|||||||
text-align: center !important;
|
text-align: center !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dashboard-grid {
|
/* .dashboard-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(4, 1fr);
|
grid-template-columns: repeat(4, 1fr);
|
||||||
gap: 1.5rem;
|
gap: 1.5rem;
|
||||||
}
|
} */
|
||||||
|
|
||||||
main {
|
main {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
}
|
}
|
||||||
@@ -152,3 +153,16 @@ main {
|
|||||||
|
|
||||||
/* ========================================================================================== */
|
/* ========================================================================================== */
|
||||||
/* ========================================================================================== */
|
/* ========================================================================================== */
|
||||||
|
|
||||||
|
.button-group {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chip-set {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
@@ -278,12 +278,14 @@ body.dark-theme .nav-item:hover {
|
|||||||
.text-center {
|
.text-center {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-group {
|
.button-group {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 0.75rem;
|
gap: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: var(--border-radius-md);
|
border-radius: var(--border-radius-md);
|
||||||
|
|||||||
Reference in New Issue
Block a user