diff --git a/src/app/features/demo/components/demo1/demo1.component.css b/src/app/.demo/demo/components/demo1/demo1.component.css
similarity index 100%
rename from src/app/features/demo/components/demo1/demo1.component.css
rename to src/app/.demo/demo/components/demo1/demo1.component.css
diff --git a/src/app/features/demo/components/demo1/demo1.component.html b/src/app/.demo/demo/components/demo1/demo1.component.html
similarity index 100%
rename from src/app/features/demo/components/demo1/demo1.component.html
rename to src/app/.demo/demo/components/demo1/demo1.component.html
diff --git a/src/app/features/demo/components/demo1/demo1.component.ts b/src/app/.demo/demo/components/demo1/demo1.component.ts
similarity index 100%
rename from src/app/features/demo/components/demo1/demo1.component.ts
rename to src/app/.demo/demo/components/demo1/demo1.component.ts
diff --git a/src/app/features/demo/components/demo2/demo2.component.txt b/src/app/.demo/demo/components/demo2/demo2.component.html
similarity index 98%
rename from src/app/features/demo/components/demo2/demo2.component.txt
rename to src/app/.demo/demo/components/demo2/demo2.component.html
index 7e5143e..14b8e2d 100644
--- a/src/app/features/demo/components/demo2/demo2.component.txt
+++ b/src/app/.demo/demo/components/demo2/demo2.component.html
@@ -3,17 +3,17 @@
-
-
+ -->
diff --git a/src/app/features/demo/components/demo2/demo2.component.2.txt b/src/app/.demo/demo/components/demo2/demo2.component.ts
similarity index 63%
rename from src/app/features/demo/components/demo2/demo2.component.2.txt
rename to src/app/.demo/demo/components/demo2/demo2.component.ts
index d5504c7..c278328 100644
--- a/src/app/features/demo/components/demo2/demo2.component.2.txt
+++ b/src/app/.demo/demo/components/demo2/demo2.component.ts
@@ -9,7 +9,7 @@ import { DOCUMENT } from '@angular/common';
import { CommonModule } from '@angular/common';
import { CardComponent } from '../../../../shared/components/ui/card/card.component';
// Wir müssen KpiColor hier importieren, um es als Typ verwenden zu können
-import { KpiCardComponent } from '../../../dashboard/components/kpi-card/kpi-card.component';
+import { KpiCardComponent } from '../../../components/dashboard/kpi-card/kpi-card.component';
import { KpiColor } from '../../../../core/types/dashboard';
@@ -86,134 +86,134 @@ export class Demo2Component {
demoForm: FormGroup;
- kpiData: Kpi[] = [
- {
- value: '€ 14.750',
- label: 'Umsatz',
- color: 'green',
- iconName: 'placeholder',
- },
- {
- value: '1.284',
- label: 'Neue Nutzer',
- color: 'blue',
- iconName: 'placeholder',
- },
- {
- value: '312',
- label: 'Bestellungen',
- color: 'orange',
- iconName: 'placeholder',
- },
- {
- value: '99.8%',
- label: 'Verfügbarkeit',
- color: 'purple',
- iconName: 'placeholder',
- },
- ];
+ // kpiData: Kpi[] = [
+ // {
+ // value: '€ 14.750',
+ // label: 'Umsatz',
+ // color: 'green',
+ // iconName: 'placeholder',
+ // },
+ // {
+ // value: '1.284',
+ // label: 'Neue Nutzer',
+ // color: 'blue',
+ // iconName: 'placeholder',
+ // },
+ // {
+ // value: '312',
+ // label: 'Bestellungen',
+ // color: 'orange',
+ // iconName: 'placeholder',
+ // },
+ // {
+ // value: '99.8%',
+ // label: 'Verfügbarkeit',
+ // color: 'purple',
+ // iconName: 'placeholder',
+ // },
+ // ];
- ordersData: Order[] = [
- {
- id: '10543',
- user: {
- name: 'Max Mustermann',
- email: 'max.m@example.com',
- avatarUrl: 'https://i.pravatar.cc/40?u=max',
- },
- amount: '€ 129,99',
- status: 'success',
- statusText: 'Abgeschlossen',
- },
- {
- id: '10542',
- user: {
- name: 'Erika Mustermann',
- email: 'erika.m@example.com',
- avatarUrl: 'https://i.pravatar.cc/40?u=erika',
- },
- amount: '€ 49,50',
- status: 'warning',
- statusText: 'In Bearbeitung',
- },
- {
- id: '10541',
- user: {
- name: 'Peter Pan',
- email: 'peter.p@example.com',
- avatarUrl: 'https://i.pravatar.cc/40?u=peter',
- },
- amount: '€ 87,00',
- status: 'danger',
- statusText: 'Storniert',
- },
- {
- id: '10543',
- user: {
- name: 'Max Mustermann',
- email: 'max.m@example.com',
- avatarUrl: 'https://i.pravatar.cc/40?u=max',
- },
- amount: '€ 129,99',
- status: 'success',
- statusText: 'Abgeschlossen',
- },
- {
- id: '10542',
- user: {
- name: 'Erika Mustermann',
- email: 'erika.m@example.com',
- avatarUrl: 'https://i.pravatar.cc/40?u=erika',
- },
- amount: '€ 49,50',
- status: 'warning',
- statusText: 'In Bearbeitung',
- },
- {
- id: '10541',
- user: {
- name: 'Peter Pan',
- email: 'peter.p@example.com',
- avatarUrl: 'https://i.pravatar.cc/40?u=peter',
- },
- amount: '€ 87,00',
- status: 'danger',
- statusText: 'Storniert',
- },
- {
- id: '10543',
- user: {
- name: 'Max Mustermann',
- email: 'max.m@example.com',
- avatarUrl: 'https://i.pravatar.cc/40?u=max',
- },
- amount: '€ 129,99',
- status: 'success',
- statusText: 'Abgeschlossen',
- },
- {
- id: '10542',
- user: {
- name: 'Erika Mustermann',
- email: 'erika.m@example.com',
- avatarUrl: 'https://i.pravatar.cc/40?u=erika',
- },
- amount: '€ 49,50',
- status: 'warning',
- statusText: 'In Bearbeitung',
- },
- {
- id: '10541',
- user: {
- name: 'Peter Pan',
- email: 'peter.p@example.com',
- avatarUrl: 'https://i.pravatar.cc/40?u=peter',
- },
- amount: '€ 87,00',
- status: 'danger',
- statusText: 'Storniert',
- },
- ];
+ // ordersData: Order[] = [
+ // {
+ // id: '10543',
+ // user: {
+ // name: 'Max Mustermann',
+ // email: 'max.m@example.com',
+ // avatarUrl: 'https://i.pravatar.cc/40?u=max',
+ // },
+ // amount: '€ 129,99',
+ // status: 'success',
+ // statusText: 'Abgeschlossen',
+ // },
+ // {
+ // id: '10542',
+ // user: {
+ // name: 'Erika Mustermann',
+ // email: 'erika.m@example.com',
+ // avatarUrl: 'https://i.pravatar.cc/40?u=erika',
+ // },
+ // amount: '€ 49,50',
+ // status: 'warning',
+ // statusText: 'In Bearbeitung',
+ // },
+ // {
+ // id: '10541',
+ // user: {
+ // name: 'Peter Pan',
+ // email: 'peter.p@example.com',
+ // avatarUrl: 'https://i.pravatar.cc/40?u=peter',
+ // },
+ // amount: '€ 87,00',
+ // status: 'danger',
+ // statusText: 'Storniert',
+ // },
+ // {
+ // id: '10543',
+ // user: {
+ // name: 'Max Mustermann',
+ // email: 'max.m@example.com',
+ // avatarUrl: 'https://i.pravatar.cc/40?u=max',
+ // },
+ // amount: '€ 129,99',
+ // status: 'success',
+ // statusText: 'Abgeschlossen',
+ // },
+ // {
+ // id: '10542',
+ // user: {
+ // name: 'Erika Mustermann',
+ // email: 'erika.m@example.com',
+ // avatarUrl: 'https://i.pravatar.cc/40?u=erika',
+ // },
+ // amount: '€ 49,50',
+ // status: 'warning',
+ // statusText: 'In Bearbeitung',
+ // },
+ // {
+ // id: '10541',
+ // user: {
+ // name: 'Peter Pan',
+ // email: 'peter.p@example.com',
+ // avatarUrl: 'https://i.pravatar.cc/40?u=peter',
+ // },
+ // amount: '€ 87,00',
+ // status: 'danger',
+ // statusText: 'Storniert',
+ // },
+ // {
+ // id: '10543',
+ // user: {
+ // name: 'Max Mustermann',
+ // email: 'max.m@example.com',
+ // avatarUrl: 'https://i.pravatar.cc/40?u=max',
+ // },
+ // amount: '€ 129,99',
+ // status: 'success',
+ // statusText: 'Abgeschlossen',
+ // },
+ // {
+ // id: '10542',
+ // user: {
+ // name: 'Erika Mustermann',
+ // email: 'erika.m@example.com',
+ // avatarUrl: 'https://i.pravatar.cc/40?u=erika',
+ // },
+ // amount: '€ 49,50',
+ // status: 'warning',
+ // statusText: 'In Bearbeitung',
+ // },
+ // {
+ // id: '10541',
+ // user: {
+ // name: 'Peter Pan',
+ // email: 'peter.p@example.com',
+ // avatarUrl: 'https://i.pravatar.cc/40?u=peter',
+ // },
+ // amount: '€ 87,00',
+ // status: 'danger',
+ // statusText: 'Storniert',
+ // },
+ // ];
aktuellesPasswort: any = '';
neuesPasswort: any = '';
diff --git a/src/app/features/demo/demo.module.ts b/src/app/.demo/demo/demo.module.ts
similarity index 100%
rename from src/app/features/demo/demo.module.ts
rename to src/app/.demo/demo/demo.module.ts
diff --git a/src/app/features/demo/demo.routes.ts b/src/app/.demo/demo/demo.routes.ts
similarity index 72%
rename from src/app/features/demo/demo.routes.ts
rename to src/app/.demo/demo/demo.routes.ts
index 9bfc4a9..68ae8cc 100644
--- a/src/app/features/demo/demo.routes.ts
+++ b/src/app/.demo/demo/demo.routes.ts
@@ -1,7 +1,7 @@
import { Routes } from '@angular/router';
import { Demo1Component } from './components/demo1/demo1.component';
-// import { Demo2Component } from './components/demo2/demo2.component';
+import { Demo2Component } from './components/demo2/demo2.component';
export const DEMO_ROUTES: Routes = [
{
@@ -17,12 +17,12 @@ export const DEMO_ROUTES: Routes = [
component: Demo1Component,
title: 'Demo1',
},
- // {
- // // Diese Route passt auf '/demo/1' und lädt die Komponente genau einmal.
- // path: '2',
- // component: Demo2Component,
- // title: 'Demo2',
- // },
+ {
+ // Diese Route passt auf '/demo/1' und lädt die Komponente genau einmal.
+ path: '2',
+ component: Demo2Component,
+ title: 'Demo2',
+ },
// Hier könntest du weitere Routen wie '2', '3' etc. hinzufügen,
// die andere Komponenten laden.
// { path: '2', component: AnotherDemoComponent },
diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts
index ccae308..fc8c9a8 100644
--- a/src/app/app.routes.ts
+++ b/src/app/app.routes.ts
@@ -5,7 +5,8 @@ import { NotFoundComponent } from './core/components/not-found/not-found.compone
import { DefaultLayoutComponent } from './core/components/default-layout/default-layout.component';
-import { DashboardPageComponent } from './features/dashboard/components/dashboard-page/dashboard-page.component';
+import { DashboardPageComponent } from './features/components/dashboard/dashboard-page/dashboard-page.component';
+import { authGuard } from './core/guards/auth.guard';
export const routes: Routes = [
{
@@ -17,11 +18,13 @@ export const routes: Routes = [
{
path: 'dashboard',
component: DefaultLayoutComponent,
+ // canActivate: [authGuard],
+ // data: { requiredRole: 'Admin' },
children: [
{
path: '',
loadChildren: () =>
- import('./features/dashboard/dashboard.routes').then(
+ import('./features/components/dashboard/dashboard.routes').then(
(r) => r.DASHBOARD_ROUTES
),
},
@@ -30,12 +33,7 @@ export const routes: Routes = [
{
path: 'auth',
loadChildren: () =>
- import('./features/auth/auth.routes').then((r) => r.AUTH_ROUTES),
- },
- {
- path: 'demo',
- loadChildren: () =>
- import('./features/demo/demo.routes').then((r) => r.DEMO_ROUTES),
+ import('./features/components/auth/auth.routes').then((r) => r.AUTH_ROUTES),
},
{
path: 'access-denied',
diff --git a/src/app/core/guards/auth.guard.ts b/src/app/core/guards/auth.guard.ts
index 543fa0e..39678ca 100644
--- a/src/app/core/guards/auth.guard.ts
+++ b/src/app/core/guards/auth.guard.ts
@@ -1,5 +1,48 @@
-import { CanActivateFn } from '@angular/router';
+import { inject } from '@angular/core';
+import { CanActivateFn, Router, ActivatedRouteSnapshot } from '@angular/router';
+import { AuthService } from '../services/auth.service';
-export const authGuard: CanActivateFn = (route, state) => {
+/**
+ * Ein funktionaler Guard, der Routen schützt.
+ *
+ * Verwendung in der Routing-Konfiguration:
+ * {
+ * path: 'admin',
+ * component: AdminDashboardComponent,
+ * canActivate: [authGuard],
+ * data: { requiredRole: 'Admin' } // Die erforderliche Rolle hier übergeben
+ * }
+ * {
+ * path: 'profile',
+ * component: UserProfileComponent,
+ * canActivate: [authGuard] // Schützt nur vor nicht angemeldeten Benutzern
+ * }
+ */
+export const authGuard: CanActivateFn = (route: ActivatedRouteSnapshot) => {
+ const authService = inject(AuthService);
+ const router = inject(Router);
+
+ // 1. Prüfen, ob der Benutzer überhaupt angemeldet ist
+ if (!authService.getToken()) {
+ // Nicht angemeldet -> zum Login umleiten
+ router.navigate(['/login']);
+ return false;
+ }
+
+ // 2. Prüfen, ob die Route eine bestimmte Rolle erfordert
+ const requiredRole = route.data['requiredRole'] as string;
+ if (requiredRole) {
+ // Rolle ist erforderlich -> prüfen, ob der Benutzer sie hat
+ if (authService.hasRole(requiredRole)) {
+ // Benutzer hat die Rolle -> Zugriff erlaubt
+ return true;
+ } else {
+ // Benutzer hat die Rolle nicht -> zu einer "Zugriff verweigert"-Seite umleiten
+ router.navigate(['/access-denied']);
+ return false;
+ }
+ }
+
+ // 3. Wenn die Route nur eine Anmeldung, aber keine spezielle Rolle erfordert
return true;
-};
+};
\ No newline at end of file
diff --git a/src/app/core/models/auth.models.ts b/src/app/core/models/auth.models.ts
new file mode 100644
index 0000000..f49fba0
--- /dev/null
+++ b/src/app/core/models/auth.models.ts
@@ -0,0 +1,15 @@
+// src/app/core/models/auth.models.ts
+
+export interface LoginRequestDto {
+ email: string;
+ password: string;
+}
+
+export interface AuthResponseDto {
+ isAuthSuccessful: boolean;
+ errorMessage?: string;
+ token?: string;
+ userId?: string;
+ email?: string;
+ roles?: string[];
+}
\ No newline at end of file
diff --git a/src/app/core/services/api.service.ts b/src/app/core/services/api.service.ts
deleted file mode 100644
index e69de29..0000000
diff --git a/src/app/core/services/auth.service.ts b/src/app/core/services/auth.service.ts
new file mode 100644
index 0000000..33bf0c8
--- /dev/null
+++ b/src/app/core/services/auth.service.ts
@@ -0,0 +1,121 @@
+import { Injectable, Inject, PLATFORM_ID } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { isPlatformBrowser } from '@angular/common';
+import { Router } from '@angular/router';
+import { Observable, BehaviorSubject, of } from 'rxjs';
+import { tap, catchError } from 'rxjs/operators';
+
+import { LoginRequestDto } from '../models/auth.models';
+import { AuthResponseDto } from '../models/auth.models';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class AuthService {
+ // Basis-URL Ihrer API
+ private apiUrl = '/api/v1/Auth';
+
+ // Keys für die Speicherung im localStorage
+ private readonly tokenKey = 'auth-token';
+ private readonly userRolesKey = 'auth-user-roles';
+
+ // Ein BehaviorSubject, um den Login-Status reaktiv in der App zu teilen
+ private loggedInStatus = new BehaviorSubject
(this.hasToken());
+ public isLoggedIn$ = this.loggedInStatus.asObservable();
+
+ constructor(
+ private http: HttpClient,
+ private router: Router,
+ @Inject(PLATFORM_ID) private platformId: Object
+ ) {}
+
+ /**
+ * Meldet einen Admin-Benutzer an.
+ */
+ loginAdmin(credentials: LoginRequestDto): Observable {
+ return this.http.post(`${this.apiUrl}/login/admin`, credentials).pipe(
+ tap(response => {
+ if (response.isAuthSuccessful && response.token) {
+ this.setSession(response);
+ }
+ }),
+ catchError(error => {
+ // Fehlerbehandlung, z.B. das Token löschen, falls eines vorhanden war
+ this.logout();
+ throw error;
+ })
+ );
+ }
+
+ /**
+ * Meldet einen normalen Kunden an.
+ */
+ loginCustomer(credentials: LoginRequestDto): Observable {
+ return this.http.post(`${this.apiUrl}/login/customer`, credentials).pipe(
+ tap(response => {
+ if (response.isAuthSuccessful && response.token) {
+ this.setSession(response);
+ }
+ })
+ );
+ }
+
+ /**
+ * Meldet den Benutzer ab, entfernt die Daten aus dem Speicher und leitet um.
+ */
+ logout(): void {
+ if (isPlatformBrowser(this.platformId)) {
+ localStorage.removeItem(this.tokenKey);
+ localStorage.removeItem(this.userRolesKey);
+ }
+ this.loggedInStatus.next(false);
+ this.router.navigate(['/login']); // oder wohin auch immer Sie umleiten möchten
+ }
+
+ /**
+ * Gibt das gespeicherte JWT-Token zurück.
+ */
+ getToken(): string | null {
+ if (isPlatformBrowser(this.platformId)) {
+ return localStorage.getItem(this.tokenKey);
+ }
+ return null;
+ }
+
+ /**
+ * Gibt die Rollen des angemeldeten Benutzers zurück.
+ */
+ getUserRoles(): string[] {
+ if (isPlatformBrowser(this.platformId)) {
+ const roles = localStorage.getItem(this.userRolesKey);
+ return roles ? JSON.parse(roles) : [];
+ }
+ return [];
+ }
+
+ /**
+ * Überprüft, ob der Benutzer eine bestimmte Rolle hat.
+ */
+ hasRole(requiredRole: string): boolean {
+ const userRoles = this.getUserRoles();
+ return userRoles.includes(requiredRole);
+ }
+
+ /**
+ * Private Methode zum Speichern der Sitzungsdaten.
+ */
+ private setSession(authResponse: AuthResponseDto): void {
+ if (isPlatformBrowser(this.platformId) && authResponse.token && authResponse.roles) {
+ localStorage.setItem(this.tokenKey, authResponse.token);
+ localStorage.setItem(this.userRolesKey, JSON.stringify(authResponse.roles));
+ this.loggedInStatus.next(true);
+ }
+ }
+
+ /**
+ * Private Methode, die prüft, ob ein Token vorhanden ist (nützlich beim App-Start).
+ */
+ private hasToken(): boolean {
+ return !!this.getToken();
+ }
+}
\ No newline at end of file
diff --git a/src/app/core/services/notification.service.ts b/src/app/core/services/notification.service.ts
deleted file mode 100644
index e69de29..0000000
diff --git a/src/app/core/tokens/api-url.token.ts b/src/app/core/tokens/api-url.token.ts
new file mode 100644
index 0000000..83129fe
--- /dev/null
+++ b/src/app/core/tokens/api-url.token.ts
@@ -0,0 +1,5 @@
+// /src/app/core/tokens/api-url.token.ts
+
+import { InjectionToken } from '@angular/core';
+
+export const API_URL = new InjectionToken('api.url');
\ No newline at end of file
diff --git a/src/app/environment.ts b/src/app/environment.ts
new file mode 100644
index 0000000..9153267
--- /dev/null
+++ b/src/app/environment.ts
@@ -0,0 +1,5 @@
+// /src/environments/environment.ts
+export const environment = {
+ production: false,
+ apiUrl: 'https://shopsolution-backend.tzbre.dev/api/v1',
+};
diff --git a/src/app/features/auth/auth.module.ts b/src/app/features/auth/auth.module.ts
deleted file mode 100644
index 7be5213..0000000
--- a/src/app/features/auth/auth.module.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
-import { AuthLayoutComponent } from './components/auth-layout/auth-layout.component';
-import { LoginComponent } from './components/login/login.component';
-
-@NgModule({
- declarations: [],
- imports: [CommonModule, AuthLayoutComponent, LoginComponent],
-})
-export class AuthModule {}
diff --git a/src/app/features/auth/services/auth.service.ts b/src/app/features/auth/services/auth.service.ts
deleted file mode 100644
index e69de29..0000000
diff --git a/src/app/features/auth/components/auth-layout/auth-layout.component.css b/src/app/features/components/auth/auth-layout/auth-layout.component.css
similarity index 100%
rename from src/app/features/auth/components/auth-layout/auth-layout.component.css
rename to src/app/features/components/auth/auth-layout/auth-layout.component.css
diff --git a/src/app/features/auth/components/auth-layout/auth-layout.component.html b/src/app/features/components/auth/auth-layout/auth-layout.component.html
similarity index 100%
rename from src/app/features/auth/components/auth-layout/auth-layout.component.html
rename to src/app/features/components/auth/auth-layout/auth-layout.component.html
diff --git a/src/app/features/auth/components/auth-layout/auth-layout.component.ts b/src/app/features/components/auth/auth-layout/auth-layout.component.ts
similarity index 100%
rename from src/app/features/auth/components/auth-layout/auth-layout.component.ts
rename to src/app/features/components/auth/auth-layout/auth-layout.component.ts
diff --git a/src/app/features/auth/auth.routes.ts b/src/app/features/components/auth/auth.routes.ts
similarity index 58%
rename from src/app/features/auth/auth.routes.ts
rename to src/app/features/components/auth/auth.routes.ts
index 2a26115..ea7e91e 100644
--- a/src/app/features/auth/auth.routes.ts
+++ b/src/app/features/components/auth/auth.routes.ts
@@ -1,13 +1,13 @@
import { Routes } from '@angular/router';
// Importiere dein spezielles Layout für Auth-Seiten und alle Komponenten
-import { AuthLayoutComponent } from './components/auth-layout/auth-layout.component';
-import { LoginComponent } from './components/login/login.component';
-import { RegisterComponent } from './components/register/register.component';
-import { ForgotPasswordComponent } from './components/forgot-password/forgot-password.component';
-import { ResetPasswordComponent } from './components/reset-password/reset-password.component';
-import { VerifyEmailComponent } from './components/verify-email/verify-email.component';
-import { NotFoundComponent } from '../../core/components/not-found/not-found.component';
+import { AuthLayoutComponent } from './auth-layout/auth-layout.component';
+import { LoginComponent } from './login/login.component';
+import { RegisterComponent } from './register/register.component';
+import { ForgotPasswordComponent } from './forgot-password/forgot-password.component';
+import { ResetPasswordComponent } from './reset-password/reset-password.component';
+import { VerifyEmailComponent } from './verify-email/verify-email.component';
+import { NotFoundComponent } from '../../../core/components/not-found/not-found.component';
export const AUTH_ROUTES: Routes = [
{
diff --git a/src/app/features/auth/components/forgot-password/forgot-password.component.css b/src/app/features/components/auth/forgot-password/forgot-password.component.css
similarity index 100%
rename from src/app/features/auth/components/forgot-password/forgot-password.component.css
rename to src/app/features/components/auth/forgot-password/forgot-password.component.css
diff --git a/src/app/features/auth/components/forgot-password/forgot-password.component.html b/src/app/features/components/auth/forgot-password/forgot-password.component.html
similarity index 100%
rename from src/app/features/auth/components/forgot-password/forgot-password.component.html
rename to src/app/features/components/auth/forgot-password/forgot-password.component.html
diff --git a/src/app/features/auth/components/forgot-password/forgot-password.component.ts b/src/app/features/components/auth/forgot-password/forgot-password.component.ts
similarity index 100%
rename from src/app/features/auth/components/forgot-password/forgot-password.component.ts
rename to src/app/features/components/auth/forgot-password/forgot-password.component.ts
diff --git a/src/app/features/auth/components/login/login.component.css b/src/app/features/components/auth/login/login.component.css
similarity index 100%
rename from src/app/features/auth/components/login/login.component.css
rename to src/app/features/components/auth/login/login.component.css
diff --git a/src/app/features/auth/components/login/login.component.html b/src/app/features/components/auth/login/login.component.html
similarity index 100%
rename from src/app/features/auth/components/login/login.component.html
rename to src/app/features/components/auth/login/login.component.html
diff --git a/src/app/features/auth/components/login/login.component.ts b/src/app/features/components/auth/login/login.component.ts
similarity index 100%
rename from src/app/features/auth/components/login/login.component.ts
rename to src/app/features/components/auth/login/login.component.ts
diff --git a/src/app/features/auth/components/register/register.component.css b/src/app/features/components/auth/register/register.component.css
similarity index 100%
rename from src/app/features/auth/components/register/register.component.css
rename to src/app/features/components/auth/register/register.component.css
diff --git a/src/app/features/auth/components/register/register.component.html b/src/app/features/components/auth/register/register.component.html
similarity index 100%
rename from src/app/features/auth/components/register/register.component.html
rename to src/app/features/components/auth/register/register.component.html
diff --git a/src/app/features/auth/components/register/register.component.ts b/src/app/features/components/auth/register/register.component.ts
similarity index 100%
rename from src/app/features/auth/components/register/register.component.ts
rename to src/app/features/components/auth/register/register.component.ts
diff --git a/src/app/features/auth/components/reset-password/reset-password.component.css b/src/app/features/components/auth/reset-password/reset-password.component.css
similarity index 100%
rename from src/app/features/auth/components/reset-password/reset-password.component.css
rename to src/app/features/components/auth/reset-password/reset-password.component.css
diff --git a/src/app/features/auth/components/reset-password/reset-password.component.html b/src/app/features/components/auth/reset-password/reset-password.component.html
similarity index 100%
rename from src/app/features/auth/components/reset-password/reset-password.component.html
rename to src/app/features/components/auth/reset-password/reset-password.component.html
diff --git a/src/app/features/auth/components/reset-password/reset-password.component.ts b/src/app/features/components/auth/reset-password/reset-password.component.ts
similarity index 100%
rename from src/app/features/auth/components/reset-password/reset-password.component.ts
rename to src/app/features/components/auth/reset-password/reset-password.component.ts
diff --git a/src/app/features/auth/components/verify-email/verify-email.component.css b/src/app/features/components/auth/verify-email/verify-email.component.css
similarity index 100%
rename from src/app/features/auth/components/verify-email/verify-email.component.css
rename to src/app/features/components/auth/verify-email/verify-email.component.css
diff --git a/src/app/features/auth/components/verify-email/verify-email.component.html b/src/app/features/components/auth/verify-email/verify-email.component.html
similarity index 100%
rename from src/app/features/auth/components/verify-email/verify-email.component.html
rename to src/app/features/components/auth/verify-email/verify-email.component.html
diff --git a/src/app/features/auth/components/verify-email/verify-email.component.ts b/src/app/features/components/auth/verify-email/verify-email.component.ts
similarity index 100%
rename from src/app/features/auth/components/verify-email/verify-email.component.ts
rename to src/app/features/components/auth/verify-email/verify-email.component.ts
diff --git a/src/app/features/dashboard/components/dashboard-page/dashboard-page.component.css b/src/app/features/components/dashboard/dashboard-page/dashboard-page.component.css
similarity index 100%
rename from src/app/features/dashboard/components/dashboard-page/dashboard-page.component.css
rename to src/app/features/components/dashboard/dashboard-page/dashboard-page.component.css
diff --git a/src/app/features/components/dashboard/dashboard-page/dashboard-page.component.html b/src/app/features/components/dashboard/dashboard-page/dashboard-page.component.html
new file mode 100644
index 0000000..8f97e8a
--- /dev/null
+++ b/src/app/features/components/dashboard/dashboard-page/dashboard-page.component.html
@@ -0,0 +1,157 @@
+
+
+
+
+
+
+
Übersicht Admin-Dashboard
+
+
+
Kategorie 1: Handlungsbedarf – "Was muss ich jetzt tun?"
+
+
+
Offene Bestellungen
+
Anzahl und Liste der letzten 3-5 Bestellungen mit Status "Pending" oder "Processing".
+
Jede Zeile sollte direkt zur Detailseite der Bestellung verlinken.
+
+ - Bestellung #12345 - Kunde: Max Mustermann - Status: Pending [Details]
+ - Bestellung #12346 - Kunde: Anna Schmidt - Status: Processing [Details]
+ - Bestellung #12347 - Kunde: Peter Müller - Status: Pending [Details]
+
+
+ Datenquelle: GET /api/v1/admin/AdminOrders (clientseitig filtern)
+
+
+
+
+
Niedriger Lagerbestand
+
Warnung und Liste der Produkte mit stockQuantity unter einem kritischen Schwellenwert.
+
+ - Produkt A - Aktueller Bestand: 5
+ - Produkt B - Aktueller Bestand: 2
+ - Produkt C - Aktueller Bestand: 1
+
+
+ Datenquelle: GET /api/v1/admin/AdminAnalytics -> inventoryStatus.productsWithLowStock
+
+
+
+
+
Zu genehmigende Bewertungen
+
Anzahl der Kundenbewertungen, die auf Freigabe warten.
+
Anzahl: 7
+
+ Datenquelle: GET /api/v1/admin/AdminReviews (clientseitig nach isApproved === false filtern)
+
+
+
+
+
+
Kategorie 2: Key Performance Indicators (KPIs) – "Wie läuft mein Geschäft?"
+
+
+
Umsatz (letzte 30 Tage)
+
Wichtigste Kennzahl.
+
Betrag: 15.450,00 €
+
+ Datenquelle: GET /api/v1/admin/AdminAnalytics -> kpiSummary.totalRevenue
+
+
+
+
+
Anzahl Bestellungen (letzte 30 Tage)
+
Zeigt die allgemeine Aktivität.
+
Anzahl: 320
+
+ Datenquelle: GET /api/v1/admin/AdminAnalytics -> kpiSummary.totalOrders
+
+
+
+
+
Durchschnittlicher Bestellwert
+
Gibt Aufschluss über das Kaufverhalten.
+
Wert: 48,28 €
+
+ Datenquelle: GET /api/v1/admin/AdminAnalytics -> kpiSummary.averageOrderValue
+
+
+
+
+
Neukunden (letzte 30 Tage)
+
Wichtige Metrik für das Wachstum.
+
Anzahl: 55
+
+ Datenquelle: GET /api/v1/admin/AdminAnalytics -> kpiSummary.newCustomersThisPeriod
+
+
+
+
+
+
Kategorie 3: Jüngste Aktivitäten & Trends – "Was passiert gerade?"
+
+
+
Umsatzverlauf (Diagramm)
+
Einfaches Linien- oder Balkendiagramm, das den Umsatz der letzten 7 oder 30 Tage anzeigt.
+
+
+ [Platzhalter für Umsatzdiagramm]
+
+
+ Datenquelle: GET /api/v1/admin/AdminAnalytics -> salesOverTime
+
+
+
+
+
Letzte Bestellungen (Feed)
+
Kurze, scrollbare Liste der letzten 10 Bestellungen (unabhängig vom Status) mit Kundenname und Bestellwert.
+
+ - Bestellung #12348 - Kunde: Lisa Meier - Wert: 75,50 €
+ - Bestellung #12349 - Kunde: Tom Weber - Wert: 120,00 €
+ - Bestellung #12350 - Kunde: Sarah Bauer - Wert: 35,20 €
+ - Bestellung #12351 - Kunde: Tim Schulz - Wert: 90,00 €
+
+
+
+ Datenquelle: GET /api/v1/admin/AdminOrders
+
+
+
+
+
+
Kategorie 4: Strategische Einblicke – "Was funktioniert gut?"
+
+
+
Top 5 Produkte
+
Einfache Liste der meistverkauften Produkte im aktuellen Zeitraum (nach Umsatz oder verkauften Einheiten).
+
+ - Produkt X (Umsatz: 5000 €)
+ - Produkt Y (Umsatz: 4500 €)
+ - Produkt Z (Umsatz: 4000 €)
+ - Produkt A (Umsatz: 3800 €)
+ - Produkt B (Umsatz: 3500 €)
+
+
+ Datenquelle: GET /api/v1/admin/AdminAnalytics -> topPerformingProducts
+
+
+
+
+
diff --git a/src/app/features/dashboard/components/dashboard-page/dashboard-page.component.ts b/src/app/features/components/dashboard/dashboard-page/dashboard-page.component.ts
similarity index 100%
rename from src/app/features/dashboard/components/dashboard-page/dashboard-page.component.ts
rename to src/app/features/components/dashboard/dashboard-page/dashboard-page.component.ts
diff --git a/src/app/features/dashboard/dashboard.routes.ts b/src/app/features/components/dashboard/dashboard.routes.ts
similarity index 77%
rename from src/app/features/dashboard/dashboard.routes.ts
rename to src/app/features/components/dashboard/dashboard.routes.ts
index 646d156..4c95727 100644
--- a/src/app/features/dashboard/dashboard.routes.ts
+++ b/src/app/features/components/dashboard/dashboard.routes.ts
@@ -1,5 +1,5 @@
import { Routes } from '@angular/router';
-import { DashboardPageComponent } from './components/dashboard-page/dashboard-page.component';
+import { DashboardPageComponent } from './dashboard-page/dashboard-page.component';
// Importiere dein spezielles Layout für Auth-Seiten und alle Komponenten
export const DASHBOARD_ROUTES: Routes = [
diff --git a/src/app/features/dashboard/components/kpi-card/kpi-card.component.css b/src/app/features/components/dashboard/kpi-card/kpi-card.component.css
similarity index 100%
rename from src/app/features/dashboard/components/kpi-card/kpi-card.component.css
rename to src/app/features/components/dashboard/kpi-card/kpi-card.component.css
diff --git a/src/app/features/dashboard/components/kpi-card/kpi-card.component.html b/src/app/features/components/dashboard/kpi-card/kpi-card.component.html
similarity index 100%
rename from src/app/features/dashboard/components/kpi-card/kpi-card.component.html
rename to src/app/features/components/dashboard/kpi-card/kpi-card.component.html
diff --git a/src/app/features/dashboard/components/kpi-card/kpi-card.component.ts b/src/app/features/components/dashboard/kpi-card/kpi-card.component.ts
similarity index 100%
rename from src/app/features/dashboard/components/kpi-card/kpi-card.component.ts
rename to src/app/features/components/dashboard/kpi-card/kpi-card.component.ts
diff --git a/src/app/features/dashboard/components/dashboard-page/dashboard-page.component.html b/src/app/features/dashboard/components/dashboard-page/dashboard-page.component.html
deleted file mode 100644
index e4c3664..0000000
--- a/src/app/features/dashboard/components/dashboard-page/dashboard-page.component.html
+++ /dev/null
@@ -1,75 +0,0 @@
-
-
-
-
-Exzellente Frage! Ein gutes Dashboard ist der Schlüssel zu einem effizienten
-Admin-Panel. Es sollte auf einen Blick die wichtigsten Fragen beantworten: "Wie
-läuft mein Geschäft?" und "Was muss ich jetzt tun?". Basierend auf den
-Endpunkten und Datenmodellen, die in Ihrer Swagger-Datei verfügbar sind
-(insbesondere AdminAnalytics, AdminOrders etc.), hier eine Gliederung der
-Kerninformationen, von der höchsten zur niedrigsten Priorität: Kategorie 1:
-Handlungsbedarf – "Was muss ich jetzt tun?" Diese Sektion ist die wichtigste,
-denn sie treibt die tägliche Arbeit an. Sie sollte prominent platziert sein.
-Offene Bestellungen: Eine Zählung und eine Liste der letzten 3-5 Bestellungen
-mit dem Status Pending oder Processing. Jede Zeile sollte direkt zur Detailseite
-der Bestellung verlinken. Warum? Dies ist die primäre Aufgabe des
-Shop-Betreibers: Bestellungen bearbeiten und versenden. Datenquelle: GET
-/api/v1/admin/AdminOrders (clientseitig filtern). Niedriger Lagerbestand: Eine
-Warnung und eine Liste der Produkte, deren stockQuantity unter einen kritischen
-Schwellenwert gefallen ist. Warum? Verhindert "Out of Stock"-Situationen und
-Umsatzverluste. Ermöglicht rechtzeitige Nachbestellungen. Datenquelle: GET
-/api/v1/admin/AdminAnalytics -> inventoryStatus.productsWithLowStock. Zu
-genehmigende Bewertungen: Eine Zählung der Kundenbewertungen, die auf Freigabe
-warten. Warum? Fördert die Interaktion mit Kunden und stellt die Qualität der
-Inhalte sicher. Datenquelle: GET /api/v1/admin/AdminReviews (clientseitig nach
-isApproved === false filtern). Kategorie 2: Key Performance Indicators (KPIs) –
-"Wie läuft mein Geschäft?" Dies ist der "Auf einen Blick"-Überblick über die
-Gesundheit des Shops. Ideal als große, klare Zahlen am oberen Rand des
-Dashboards. Umsatz (letzte 30 Tage): Die wichtigste Kennzahl. Datenquelle: GET
-/api/v1/admin/AdminAnalytics -> kpiSummary.totalRevenue. Anzahl Bestellungen
-(letzte 30 Tage): Zeigt die allgemeine Aktivität. Datenquelle: GET
-/api/v1/admin/AdminAnalytics -> kpiSummary.totalOrders. Durchschnittlicher
-Bestellwert: Gibt Aufschluss über das Kaufverhalten. Datenquelle: GET
-/api/v1/admin/AdminAnalytics -> kpiSummary.averageOrderValue. Neukunden (letzte
-30 Tage): Eine wichtige Metrik für das Wachstum. Datenquelle: GET
-/api/v1/admin/AdminAnalytics -> kpiSummary.newCustomersThisPeriod. Kategorie 3:
-Jüngste Aktivitäten & Trends – "Was passiert gerade?" Diese Sektion gibt ein
-Gefühl für die aktuelle Dynamik und hilft, Muster zu erkennen. Umsatzverlauf
-(Diagramm): Ein einfaches Linien- oder Balkendiagramm, das den Umsatz der
-letzten 7 oder 30 Tage anzeigt. Warum? Visualisiert Trends, Hochs und Tiefs
-(z.B. an Wochenenden). Datenquelle: GET /api/v1/admin/AdminAnalytics ->
-salesOverTime. Letzte Bestellungen (Feed): Eine kurze, scrollbare Liste der
-letzten 10 Bestellungen (unabhängig vom Status) mit Kundenname und Bestellwert.
-Warum? Gibt dem Dashboard ein "lebendiges" Gefühl. Datenquelle: GET
-/api/v1/admin/AdminOrders. Kategorie 4: Strategische Einblicke – "Was
-funktioniert gut?" Diese Informationen helfen bei Marketing- und
-Bestandsentscheidungen. Top 5 Produkte: Eine einfache Liste der meistverkauften
-Produkte im aktuellen Zeitraum (nach Umsatz oder verkauften Einheiten). Warum?
-Zeigt, welche Produkte beworben werden sollten und wo der Lagerbestand immer
-hoch sein muss. Datenquelle: GET /api/v1/admin/AdminAnalytics ->
-topPerformingProducts. Vorschlag für ein Dashboard-Layout: Ein bewährtes Layout
-könnte so aussehen: Obere Reihe: Die 4 großen KPI-Karten (Umsatz, Bestellungen,
-Ø-Wert, Neukunden). Linke (breitere) Spalte: Ganz oben das
-Umsatzverlauf-Diagramm. Darunter die Liste der "Letzten Bestellungen". Rechte
-(schmalere) Spalte: Ganz oben die "Handlungsbedarf"-Box mit den offenen
-Bestellungen und dem niedrigen Lagerbestand. Darunter die "Top 5
-Produkte"-Liste. Mit dieser Auswahl an Informationen hat der Admin alles
-Wichtige im Blick und kann direkt die notwendigen Aktionen ausführen.
diff --git a/src/app/features/dashboard/dashboard.module.ts b/src/app/features/dashboard/dashboard.module.ts
deleted file mode 100644
index c57e32a..0000000
--- a/src/app/features/dashboard/dashboard.module.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
-
-
-@NgModule({
- declarations: [],
- imports: [CommonModule],
-})
-export class DashboardModule {}
diff --git a/src/app/modules.ts b/src/app/modules.ts
index 7cd79bf..88a8b07 100644
--- a/src/app/modules.ts
+++ b/src/app/modules.ts
@@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common';
-export const MATERIAL_MODULES = [
+export const MODULES = [
CommonModule,
];
\ No newline at end of file
diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts
deleted file mode 100644
index e69de29..0000000