endpoint anpassen
This commit is contained in:
@@ -31,7 +31,36 @@ export const routes: Routes = [
|
||||
{
|
||||
path: 'auth',
|
||||
loadChildren: () =>
|
||||
import('./features/components/auth/auth.routes').then((r) => r.AUTH_ROUTES),
|
||||
import('./features/components/auth/auth.routes').then(
|
||||
(r) => r.AUTH_ROUTES
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'categories',
|
||||
canActivate: [authGuard],
|
||||
data: { requiredRole: 'Admin' },
|
||||
loadChildren: () =>
|
||||
import('./features/components/categories/categories.routes').then(
|
||||
(r) => r.CATEGORIES_ROUTES
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'discounts',
|
||||
canActivate: [authGuard],
|
||||
data: { requiredRole: 'Admin' },
|
||||
loadChildren: () =>
|
||||
import('./features/components/discounts/discounts.routes').then(
|
||||
(r) => r.DISCOUNTS_ROUTES
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'orders',
|
||||
canActivate: [authGuard],
|
||||
data: { requiredRole: 'Admin' },
|
||||
loadChildren: () =>
|
||||
import('./features/components/orders/orders.routes').then(
|
||||
(r) => r.ORDERS_ROUTES
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'access-denied',
|
||||
|
||||
10
src/app/features/components/categories/categories.routes.ts
Normal file
10
src/app/features/components/categories/categories.routes.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Routes } from '@angular/router';
|
||||
import { CategoryListComponent } from './category-list/category-list.component';
|
||||
|
||||
export const CATEGORIES_ROUTES: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: CategoryListComponent,
|
||||
title: 'Category Übersicht',
|
||||
},
|
||||
];
|
||||
@@ -1,26 +1,66 @@
|
||||
<div>
|
||||
<h1>Kategorien verwalten</h1>
|
||||
|
||||
<!-- Formular für Erstellen/Bearbeiten -->
|
||||
<form [formGroup]="categoryForm" (ngSubmit)="onSubmit()">
|
||||
<h3>{{ selectedCategoryId ? 'Kategorie bearbeiten' : 'Neue Kategorie erstellen' }}</h3>
|
||||
<input type="text" formControlName="name" placeholder="Name">
|
||||
<input type="text" formControlName="slug" placeholder="Slug">
|
||||
<textarea formControlName="description" placeholder="Beschreibung"></textarea>
|
||||
|
||||
<div>
|
||||
<label for="name">Name</label>
|
||||
<input id="name" type="text" formControlName="name" placeholder="Name">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="slug">Slug</label>
|
||||
<input id="slug" type="text" formControlName="slug" placeholder="Slug">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="parent">Übergeordnete Kategorie</label>
|
||||
<select id="parent" formControlName="parentcategorieId">
|
||||
<option [ngValue]="null">-- Keine (Hauptkategorie) --</option>
|
||||
<option *ngFor="let parent of parentCategories$ | async" [value]="parent.id">
|
||||
{{ parent.name }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="description">Beschreibung</label>
|
||||
<textarea id="description" formControlName="description" placeholder="Beschreibung"></textarea>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" formControlName="isActive"> Aktiv
|
||||
</label>
|
||||
<input type="file" (change)="onFileChange($event)">
|
||||
</div>
|
||||
|
||||
<!-- +++ NEUER BILD-MANAGEMENT-BLOCK +++ -->
|
||||
<div>
|
||||
<label for="file">Bild</label>
|
||||
<!-- Bild-Vorschau -->
|
||||
<div *ngIf="existingImageUrl">
|
||||
<img [src]="existingImageUrl" alt="Kategorie-Vorschau" style="max-width: 100px; max-height: 100px; display: block; margin-bottom: 10px;">
|
||||
<button type="button" (click)="removeImage()">Bild entfernen</button>
|
||||
</div>
|
||||
<!-- Datei-Input -->
|
||||
<input id="file" type="file" (change)="onFileChange($event)">
|
||||
</div>
|
||||
<!-- +++ ENDE NEU +++ -->
|
||||
|
||||
<br>
|
||||
|
||||
<button type="submit" [disabled]="categoryForm.invalid">{{ selectedCategoryId ? 'Aktualisieren' : 'Erstellen' }}</button>
|
||||
<button type="button" *ngIf="selectedCategoryId" (click)="clearSelection()">Abbrechen</button>
|
||||
</form>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- Liste der Kategorien -->
|
||||
<h2>Bestehende Kategorien</h2>
|
||||
<ul>
|
||||
<li *ngFor="let category of categories$ | async">
|
||||
<!-- Bild-Vorschau in der Liste -->
|
||||
<img *ngIf="category.imageUrl" [src]="category.imageUrl" alt="{{ category.name }}" style="width: 30px; height: 30px; vertical-align: middle; margin-right: 10px;">
|
||||
{{ category.name }} (Slug: {{ category.slug }}) - Aktiv: {{ category.isActive }}
|
||||
<button (click)="selectCategory(category)">Bearbeiten</button>
|
||||
<button (click)="onDelete(category.id)">Löschen</button>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Component, OnInit, inject } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Observable, map } from 'rxjs';
|
||||
import { Category } from '../../../../core/models/category.model';
|
||||
import { CategoryService } from '../../../services/category.service';
|
||||
|
||||
@@ -16,9 +16,14 @@ export class CategoryListComponent implements OnInit {
|
||||
private fb = inject(FormBuilder);
|
||||
|
||||
categories$!: Observable<Category[]>;
|
||||
parentCategories$!: Observable<Category[]>;
|
||||
categoryForm: FormGroup;
|
||||
selectedCategoryId: string | null = null;
|
||||
|
||||
// --- NEUE EIGENSCHAFTEN FÜR BILD-MANAGEMENT ---
|
||||
selectedFile: File | null = null;
|
||||
existingImageUrl: string | null = null;
|
||||
// --- ENDE NEU ---
|
||||
|
||||
constructor() {
|
||||
this.categoryForm = this.fb.group({
|
||||
@@ -26,6 +31,7 @@ export class CategoryListComponent implements OnInit {
|
||||
slug: ['', Validators.required],
|
||||
description: [''],
|
||||
isActive: [true],
|
||||
parentcategorieId: [null]
|
||||
});
|
||||
}
|
||||
|
||||
@@ -35,45 +41,74 @@ export class CategoryListComponent implements OnInit {
|
||||
|
||||
loadCategories(): void {
|
||||
this.categories$ = this.categoryService.getAll();
|
||||
this.updateParentCategoryList();
|
||||
}
|
||||
|
||||
onFileChange(event: Event): void {
|
||||
const element = event.currentTarget as HTMLInputElement;
|
||||
let fileList: FileList | null = element.files;
|
||||
if (fileList) {
|
||||
const fileList: FileList | null = element.files;
|
||||
if (fileList && fileList.length > 0) {
|
||||
this.selectedFile = fileList[0];
|
||||
// Zeige eine Vorschau des neu ausgewählten Bildes an
|
||||
this.existingImageUrl = URL.createObjectURL(this.selectedFile);
|
||||
}
|
||||
}
|
||||
|
||||
selectCategory(category: Category): void {
|
||||
this.selectedCategoryId = category.id;
|
||||
this.categoryForm.patchValue(category);
|
||||
|
||||
// --- NEU: Bild-URL speichern ---
|
||||
this.existingImageUrl = category.imageUrl || null;
|
||||
|
||||
this.updateParentCategoryList();
|
||||
}
|
||||
|
||||
clearSelection(): void {
|
||||
this.selectedCategoryId = null;
|
||||
this.categoryForm.reset({ isActive: true });
|
||||
this.categoryForm.reset({ isActive: true, parentcategorieId: null });
|
||||
|
||||
// --- NEU: Bild-Referenzen zurücksetzen ---
|
||||
this.selectedFile = null;
|
||||
this.existingImageUrl = null;
|
||||
|
||||
this.updateParentCategoryList();
|
||||
}
|
||||
|
||||
// --- NEU: Methode zum Entfernen des Bildes ---
|
||||
removeImage(): void {
|
||||
this.selectedFile = null;
|
||||
this.existingImageUrl = null;
|
||||
}
|
||||
|
||||
onSubmit(): void {
|
||||
if (this.categoryForm.invalid) return;
|
||||
|
||||
const formData = new FormData();
|
||||
Object.keys(this.categoryForm.value).forEach(key => {
|
||||
formData.append(key, this.categoryForm.value[key]);
|
||||
const formValue = this.categoryForm.value;
|
||||
|
||||
Object.keys(formValue).forEach(key => {
|
||||
const value = formValue[key] === null || formValue[key] === undefined ? '' : formValue[key];
|
||||
formData.append(key, value);
|
||||
});
|
||||
|
||||
// --- ÜBERARBEITETE BILD-LOGIK ---
|
||||
if (this.selectedFile) {
|
||||
// Nur wenn eine NEUE Datei ausgewählt wurde, wird sie gesendet.
|
||||
formData.append('ImageFile', this.selectedFile, this.selectedFile.name);
|
||||
} else if (this.existingImageUrl) {
|
||||
// Wenn keine neue Datei da ist, aber ein altes Bild existiert,
|
||||
// senden wir die URL, damit das Backend weiß, dass es erhalten bleiben soll.
|
||||
formData.append('ImageUrl', this.existingImageUrl);
|
||||
}
|
||||
// Wenn beides null ist (z.B. nach Klick auf "Bild entfernen"),
|
||||
// wird kein Bild-Parameter gesendet und das Backend sollte das Bild löschen.
|
||||
// --- ENDE ÜBERARBEITUNG ---
|
||||
|
||||
if (this.selectedCategoryId) {
|
||||
// Update
|
||||
formData.append('Id', this.selectedCategoryId);
|
||||
this.categoryService.update(this.selectedCategoryId, formData).subscribe(() => this.reset());
|
||||
} else {
|
||||
// Create
|
||||
this.categoryService.create(formData).subscribe(() => this.reset());
|
||||
}
|
||||
}
|
||||
@@ -88,4 +123,10 @@ export class CategoryListComponent implements OnInit {
|
||||
this.loadCategories();
|
||||
this.clearSelection();
|
||||
}
|
||||
|
||||
private updateParentCategoryList(): void {
|
||||
this.parentCategories$ = this.categories$.pipe(
|
||||
map(categories => categories.filter(c => c.id !== this.selectedCategoryId))
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -3,28 +3,83 @@
|
||||
|
||||
<form [formGroup]="discountForm" (ngSubmit)="onSubmit()">
|
||||
<h3>{{ selectedDiscountId ? "Rabatt bearbeiten" : "Neuer Rabatt" }}</h3>
|
||||
<input type="text" formControlName="name" placeholder="Name des Rabatts" />
|
||||
<select formControlName="discountType">
|
||||
<option *ngFor="let type of discountTypes" [value]="type">
|
||||
{{ type }}
|
||||
|
||||
<div><label for="name">Name:</label>
|
||||
<input id="name" type="text" formControlName="name" placeholder="Name des Rabatts" /></div>
|
||||
|
||||
<div><label for="desc">Beschreibung:</label>
|
||||
<textarea id="desc" formControlName="description" placeholder="Beschreibung"></textarea></div>
|
||||
|
||||
<div><label for="type">Typ:</label>
|
||||
<select id="type" formControlName="discountType">
|
||||
<option *ngFor="let type of discountTypes" [value]="type">{{ type }}</option>
|
||||
</select></div>
|
||||
|
||||
<div><label for="value">Wert:</label>
|
||||
<input id="value" type="number" formControlName="discountValue" placeholder="z.B. 10 für 10% oder 10€" /></div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div><label for="couponCode">Gutscheincode:</label>
|
||||
<input id="couponCode" type="text" formControlName="couponCode" placeholder="z.B. SOMMER2024" /></div>
|
||||
|
||||
<div><label><input type="checkbox" formControlName="requiresCouponCode" /> Code erforderlich</label></div>
|
||||
<div><label><input type="checkbox" formControlName="isActive" /> Aktiv</label></div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div><label for="startDate">Startdatum:</label>
|
||||
<input id="startDate" type="date" formControlName="startDate" /></div>
|
||||
|
||||
<div><label for="endDate">Enddatum (optional):</label>
|
||||
<input id="endDate" type="date" formControlName="endDate" /></div>
|
||||
|
||||
<div><label for="minOrder">Mindestbestellwert (optional):</label>
|
||||
<input id="minOrder" type="number" formControlName="minimumOrderAmount" placeholder="z.B. 50" /></div>
|
||||
|
||||
<div><label for="maxUsage">Maximale Nutzungen (optional):</label>
|
||||
<input id="maxUsage" type="number" formControlName="maximumUsageCount" placeholder="z.B. 100" /></div>
|
||||
|
||||
<hr>
|
||||
|
||||
<h4>Produkten zuweisen</h4>
|
||||
<div>
|
||||
<select #productSelect>
|
||||
<option [ngValue]="null">-- Produkt auswählen --</option>
|
||||
<option *ngFor="let product of allProducts$ | async" [value]="product.id">
|
||||
{{ product.name }} ({{ product.sku }})
|
||||
</option>
|
||||
</select>
|
||||
<input
|
||||
type="number"
|
||||
formControlName="discountValue"
|
||||
placeholder="Wert (z.B. 10 für 10% oder 10€)"
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
formControlName="couponCode"
|
||||
placeholder="Gutscheincode (optional)"
|
||||
/>
|
||||
<label
|
||||
><input type="checkbox" formControlName="requiresCouponCode" /> Code
|
||||
erforderlich</label
|
||||
>
|
||||
<label><input type="checkbox" formControlName="isActive" /> Aktiv</label>
|
||||
<input type="date" formControlName="startDate" />
|
||||
<button type="button" (click)="addProduct(productSelect.value)">+</button>
|
||||
</div>
|
||||
<ul>
|
||||
<li *ngFor="let control of assignedProductIds.controls; let i = index">
|
||||
{{ getProductName(control.value, (allProducts$ | async)) }}
|
||||
<button type="button" (click)="removeProduct(i)">x</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
|
||||
<h4>Kategorien zuweisen</h4>
|
||||
<div>
|
||||
<select #categorySelect>
|
||||
<option [ngValue]="null">-- Kategorie auswählen --</option>
|
||||
<option *ngFor="let category of allCategories$ | async" [value]="category.id">
|
||||
{{ category.name }}
|
||||
</option>
|
||||
</select>
|
||||
<button type="button" (click)="addCategory(categorySelect.value)">+</button>
|
||||
</div>
|
||||
<ul>
|
||||
<li *ngFor="let control of assignedCategoryIds.controls; let i = index">
|
||||
{{ getCategoryName(control.value, (allCategories$ | async)) }}
|
||||
<button type="button" (click)="removeCategory(i)">x</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<br><br>
|
||||
|
||||
<button type="submit" [disabled]="discountForm.invalid">
|
||||
{{ selectedDiscountId ? "Aktualisieren" : "Erstellen" }}
|
||||
</button>
|
||||
@@ -38,8 +93,8 @@
|
||||
<h2>Bestehende Rabatte</h2>
|
||||
<ul>
|
||||
<li *ngFor="let discount of discounts$ | async">
|
||||
{{ discount.name }} ({{ discount.discountValue
|
||||
}}{{ discount.discountType === "Percentage" ? "%" : "€" }})
|
||||
{{ discount.name }} ({{ discount.discountValue }}{{ discount.discountType === "Percentage" ? "%" : "€" }})
|
||||
- Code: {{ discount.couponCode || 'Kein Code' }}
|
||||
<button (click)="selectDiscount(discount)">Bearbeiten</button>
|
||||
<button (click)="onDelete(discount.id)">Löschen</button>
|
||||
</li>
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
import { Component, OnInit, inject } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { FormBuilder, FormGroup, FormArray, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
// Models
|
||||
import { Discount } from '../../../../core/models/discount.model';
|
||||
import { DiscountService } from '../../../services/discount.service';
|
||||
import { AdminProduct } from '../../../../core/models/product.model';
|
||||
import { Category } from '../../../../core/models/category.model';
|
||||
|
||||
import { DiscountType } from '../../../../core/enums/shared.enum';
|
||||
|
||||
// Services
|
||||
import { DiscountService } from '../../../services/discount.service';
|
||||
import { ProductService } from '../../../services/product.service';
|
||||
import { CategoryService } from '../../../services/category.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-discount-list',
|
||||
standalone: true,
|
||||
@@ -13,10 +22,18 @@ import { DiscountType } from '../../../../core/enums/shared.enum';
|
||||
templateUrl: './discount-list.component.html',
|
||||
})
|
||||
export class DiscountListComponent implements OnInit {
|
||||
// --- Service Injection ---
|
||||
private discountService = inject(DiscountService);
|
||||
private productService = inject(ProductService);
|
||||
private categoryService = inject(CategoryService);
|
||||
private fb = inject(FormBuilder);
|
||||
|
||||
// --- Data Observables ---
|
||||
discounts$!: Observable<Discount[]>;
|
||||
allProducts$!: Observable<AdminProduct[]>;
|
||||
allCategories$!: Observable<Category[]>;
|
||||
|
||||
// --- Form Properties ---
|
||||
discountForm: FormGroup;
|
||||
selectedDiscountId: string | null = null;
|
||||
discountTypes: DiscountType[] = ['Percentage', 'FixedAmount'];
|
||||
@@ -29,31 +46,87 @@ export class DiscountListComponent implements OnInit {
|
||||
couponCode: [''],
|
||||
requiresCouponCode: [false],
|
||||
isActive: [true],
|
||||
startDate: [new Date().toISOString().split('T')[0], Validators.required]
|
||||
startDate: [new Date().toISOString().split('T')[0], Validators.required],
|
||||
// +++ HIER SIND DIE FEHLENDEN FELDER +++
|
||||
endDate: [null],
|
||||
minimumOrderAmount: [null, [Validators.min(0)]],
|
||||
maximumUsageCount: [null, [Validators.min(0)]],
|
||||
description: [''],
|
||||
assignedProductIds: this.fb.array([]),
|
||||
assignedCategoryIds: this.fb.array([])
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit(): void { this.loadDiscounts(); }
|
||||
loadDiscounts(): void { this.discounts$ = this.discountService.getAll(); }
|
||||
get assignedProductIds(): FormArray {
|
||||
return this.discountForm.get('assignedProductIds') as FormArray;
|
||||
}
|
||||
|
||||
get assignedCategoryIds(): FormArray {
|
||||
return this.discountForm.get('assignedCategoryIds') as FormArray;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.loadInitialData();
|
||||
}
|
||||
|
||||
loadInitialData(): void {
|
||||
this.discounts$ = this.discountService.getAll();
|
||||
this.allProducts$ = this.productService.getAll();
|
||||
this.allCategories$ = this.categoryService.getAll();
|
||||
}
|
||||
|
||||
selectDiscount(discount: Discount): void {
|
||||
this.selectedDiscountId = discount.id;
|
||||
// Format date for the input[type=date]
|
||||
const formattedDiscount = {
|
||||
this.discountForm.patchValue({
|
||||
...discount,
|
||||
startDate: new Date(discount.startDate).toISOString().split('T')[0]
|
||||
};
|
||||
this.discountForm.patchValue(formattedDiscount);
|
||||
startDate: new Date(discount.startDate).toISOString().split('T')[0],
|
||||
endDate: discount.endDate ? new Date(discount.endDate).toISOString().split('T')[0] : null,
|
||||
});
|
||||
|
||||
this.assignedProductIds.clear();
|
||||
discount.assignedProductIds?.forEach(id => this.assignedProductIds.push(this.fb.control(id)));
|
||||
|
||||
this.assignedCategoryIds.clear();
|
||||
discount.assignedCategoryIds?.forEach(id => this.assignedCategoryIds.push(this.fb.control(id)));
|
||||
}
|
||||
|
||||
clearSelection(): void {
|
||||
this.selectedDiscountId = null;
|
||||
this.discountForm.reset({
|
||||
name: '',
|
||||
discountType: 'Percentage',
|
||||
isActive: true,
|
||||
discountValue: 0,
|
||||
couponCode: '',
|
||||
requiresCouponCode: false,
|
||||
startDate: new Date().toISOString().split('T')[0]
|
||||
isActive: true,
|
||||
startDate: new Date().toISOString().split('T')[0],
|
||||
endDate: null,
|
||||
minimumOrderAmount: null,
|
||||
maximumUsageCount: null,
|
||||
description: '',
|
||||
});
|
||||
this.assignedProductIds.clear();
|
||||
this.assignedCategoryIds.clear();
|
||||
}
|
||||
|
||||
addProduct(productId: string | null): void {
|
||||
if (productId && !this.assignedProductIds.value.includes(productId)) {
|
||||
this.assignedProductIds.push(this.fb.control(productId));
|
||||
}
|
||||
}
|
||||
|
||||
removeProduct(index: number): void {
|
||||
this.assignedProductIds.removeAt(index);
|
||||
}
|
||||
|
||||
addCategory(categoryId: string | null): void {
|
||||
if (categoryId && !this.assignedCategoryIds.value.includes(categoryId)) {
|
||||
this.assignedCategoryIds.push(this.fb.control(categoryId));
|
||||
}
|
||||
}
|
||||
|
||||
removeCategory(index: number): void {
|
||||
this.assignedCategoryIds.removeAt(index);
|
||||
}
|
||||
|
||||
onSubmit(): void {
|
||||
@@ -62,8 +135,12 @@ export class DiscountListComponent implements OnInit {
|
||||
const formValue = this.discountForm.value;
|
||||
const dataToSend: Discount = {
|
||||
...formValue,
|
||||
id: this.selectedDiscountId || '00000000-0000-0000-0000-000000000000', // Dummy ID for create
|
||||
startDate: new Date(formValue.startDate).toISOString()
|
||||
id: this.selectedDiscountId || undefined,
|
||||
startDate: new Date(formValue.startDate).toISOString(),
|
||||
endDate: formValue.endDate ? new Date(formValue.endDate).toISOString() : null,
|
||||
// Die Werte aus den FormArrays sind bereits korrekte Arrays von Strings
|
||||
assignedProductIds: this.assignedProductIds.value,
|
||||
assignedCategoryIds: this.assignedCategoryIds.value
|
||||
};
|
||||
|
||||
if (this.selectedDiscountId) {
|
||||
@@ -75,12 +152,20 @@ export class DiscountListComponent implements OnInit {
|
||||
|
||||
onDelete(id: string): void {
|
||||
if (confirm('Rabatt wirklich löschen?')) {
|
||||
this.discountService.delete(id).subscribe(() => this.loadDiscounts());
|
||||
this.discountService.delete(id).subscribe(() => this.loadInitialData());
|
||||
}
|
||||
}
|
||||
|
||||
private reset(): void {
|
||||
this.loadDiscounts();
|
||||
this.loadInitialData();
|
||||
this.clearSelection();
|
||||
}
|
||||
|
||||
getProductName(productId: string, products: AdminProduct[] | null): string {
|
||||
return products?.find(p => p.id === productId)?.name || 'Unbekanntes Produkt';
|
||||
}
|
||||
|
||||
getCategoryName(categoryId: string, categories: Category[] | null): string {
|
||||
return categories?.find(c => c.id === categoryId)?.name || 'Unbekannte Kategorie';
|
||||
}
|
||||
}
|
||||
10
src/app/features/components/discounts/discounts.routes.ts
Normal file
10
src/app/features/components/discounts/discounts.routes.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Routes } from '@angular/router';
|
||||
import { DiscountListComponent } from './discount-list/discount-list.component';
|
||||
|
||||
export const DISCOUNTS_ROUTES: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: DiscountListComponent,
|
||||
title: '',
|
||||
},
|
||||
];
|
||||
10
src/app/features/components/orders/orders.routes.ts
Normal file
10
src/app/features/components/orders/orders.routes.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Routes } from '@angular/router';
|
||||
import { OrderListComponent } from './order-list/order-list.component';
|
||||
|
||||
export const ORDERS_ROUTES: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: OrderListComponent,
|
||||
title: '',
|
||||
},
|
||||
];
|
||||
@@ -9,7 +9,7 @@ import { AnalyticsPeriod } from '../../core/enums/shared.enum';
|
||||
export class AnalyticsService {
|
||||
private http = inject(HttpClient);
|
||||
private apiUrl = inject(API_URL);
|
||||
private readonly endpoint = '/AdminAnalytics';
|
||||
private readonly endpoint = '/admin/AdminAnalytics';
|
||||
|
||||
get(period: AnalyticsPeriod): Observable<Analytics> {
|
||||
const params = new HttpParams().set('period', period);
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Category } from '../../core/models/category.model';
|
||||
export class CategoryService {
|
||||
private http = inject(HttpClient);
|
||||
private apiUrl = inject(API_URL);
|
||||
private readonly endpoint = '/AdminCategories';
|
||||
private readonly endpoint = '/admin/AdminCategories';
|
||||
|
||||
getAll(): Observable<Category[]> {
|
||||
return this.http.get<Category[]>(`${this.apiUrl}${this.endpoint}`);
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Discount } from '../../core/models/discount.model';
|
||||
export class DiscountService {
|
||||
private http = inject(HttpClient);
|
||||
private apiUrl = inject(API_URL);
|
||||
private readonly endpoint = '/AdminDiscounts';
|
||||
private readonly endpoint = '/admin/AdminDiscounts';
|
||||
|
||||
getAll(): Observable<Discount[]> {
|
||||
return this.http.get<Discount[]>(`${this.apiUrl}${this.endpoint}`);
|
||||
|
||||
@@ -8,7 +8,7 @@ import { OrderDetail, OrderSummary, UpdateOrderStatusRequest } from '../../core/
|
||||
export class OrderService {
|
||||
private http = inject(HttpClient);
|
||||
private apiUrl = inject(API_URL);
|
||||
private readonly endpoint = '/AdminOrders';
|
||||
private readonly endpoint = '/admin/AdminOrders';
|
||||
|
||||
getAll(): Observable<OrderSummary[]> {
|
||||
return this.http.get<OrderSummary[]>(`${this.apiUrl}${this.endpoint}`);
|
||||
|
||||
@@ -8,7 +8,7 @@ import { AdminPaymentMethod } from '../../core/models/payment.model';
|
||||
export class PaymentMethodService {
|
||||
private http = inject(HttpClient);
|
||||
private apiUrl = inject(API_URL);
|
||||
private readonly endpoint = '/AdminPaymentMethods';
|
||||
private readonly endpoint = '/admin/AdminPaymentMethods';
|
||||
|
||||
getAll(): Observable<AdminPaymentMethod[]> {
|
||||
return this.http.get<AdminPaymentMethod[]>(`${this.apiUrl}${this.endpoint}`);
|
||||
|
||||
@@ -8,7 +8,7 @@ import { AdminProduct } from '../../core/models/product.model';
|
||||
export class ProductService {
|
||||
private http = inject(HttpClient);
|
||||
private apiUrl = inject(API_URL);
|
||||
private readonly endpoint = '/AdminProducts';
|
||||
private readonly endpoint = '/admin/AdminProducts';
|
||||
|
||||
getAll(): Observable<AdminProduct[]> {
|
||||
return this.http.get<AdminProduct[]>(`${this.apiUrl}${this.endpoint}`);
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Review } from '../../core/models/review.model';
|
||||
export class ReviewService {
|
||||
private http = inject(HttpClient);
|
||||
private apiUrl = inject(API_URL);
|
||||
private readonly endpoint = '/AdminReviews';
|
||||
private readonly endpoint = '/admin/AdminReviews';
|
||||
|
||||
getAll(): Observable<Review[]> {
|
||||
return this.http.get<Review[]>(`${this.apiUrl}${this.endpoint}`);
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Setting } from '../../core/models/setting.model';
|
||||
export class SettingService {
|
||||
private http = inject(HttpClient);
|
||||
private apiUrl = inject(API_URL);
|
||||
private readonly endpoint = '/AdminSettings';
|
||||
private readonly endpoint = '/admin/AdminSettings';
|
||||
|
||||
getAllGrouped(): Observable<{ [group: string]: Setting[] }> {
|
||||
return this.http.get<{ [group: string]: Setting[] }>(`${this.apiUrl}${this.endpoint}`);
|
||||
|
||||
@@ -8,7 +8,7 @@ import { ShippingMethod } from '../../core/models/shipping.model';
|
||||
export class ShippingMethodService {
|
||||
private http = inject(HttpClient);
|
||||
private apiUrl = inject(API_URL);
|
||||
private readonly endpoint = '/AdminShippingMethods';
|
||||
private readonly endpoint = '/admin/AdminShippingMethods';
|
||||
|
||||
getAll(): Observable<ShippingMethod[]> {
|
||||
return this.http.get<ShippingMethod[]>(`${this.apiUrl}${this.endpoint}`);
|
||||
|
||||
@@ -8,7 +8,7 @@ import { AdminShopInfo } from '../../core/models/shop.model';
|
||||
export class ShopInfoService {
|
||||
private http = inject(HttpClient);
|
||||
private apiUrl = inject(API_URL);
|
||||
private readonly endpoint = '/AdminShopInfo';
|
||||
private readonly endpoint = '/admin/AdminShopInfo';
|
||||
|
||||
get(): Observable<AdminShopInfo> {
|
||||
return this.http.get<AdminShopInfo>(`${this.apiUrl}${this.endpoint}`);
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Supplier } from '../../core/models/supplier.model';
|
||||
export class SupplierService {
|
||||
private http = inject(HttpClient);
|
||||
private apiUrl = inject(API_URL);
|
||||
private readonly endpoint = '/AdminSuppliers';
|
||||
private readonly endpoint = '/admin/AdminSuppliers';
|
||||
|
||||
getAll(): Observable<Supplier[]> {
|
||||
return this.http.get<Supplier[]>(`${this.apiUrl}${this.endpoint}`);
|
||||
|
||||
@@ -8,7 +8,7 @@ import { User, UpdateUserRolesRequest } from '../../core/models/user.model';
|
||||
export class UserService {
|
||||
private http = inject(HttpClient);
|
||||
private apiUrl = inject(API_URL);
|
||||
private readonly endpoint = '/AdminUsers';
|
||||
private readonly endpoint = '/admin/AdminUsers';
|
||||
|
||||
getAll(): Observable<User[]> {
|
||||
return this.http.get<User[]>(`${this.apiUrl}${this.endpoint}`);
|
||||
|
||||
Reference in New Issue
Block a user