add AddProduct component with form for product creation and associated styles

This commit is contained in:
Vincent Guillet
2025-10-14 14:53:13 +02:00
parent f04f9fd93f
commit 8c3de85f36
9 changed files with 396 additions and 24 deletions

View File

@@ -0,0 +1,163 @@
import {Component, inject, OnDestroy, OnInit} from '@angular/core';
import {
FormBuilder,
FormGroup,
FormsModule,
ReactiveFormsModule,
Validators
} from "@angular/forms";
import {MatButton} from "@angular/material/button";
import {
MatCard,
MatCardActions,
MatCardContent,
MatCardHeader,
MatCardSubtitle,
MatCardTitle
} from "@angular/material/card";
import {MatCheckbox} from "@angular/material/checkbox";
import {MatDivider} from "@angular/material/divider";
import {MatError, MatFormField, MatLabel} from "@angular/material/form-field";
import {MatInput} from "@angular/material/input";
import {MatProgressSpinner} from "@angular/material/progress-spinner";
import {MatOption, MatSelect} from '@angular/material/select';
import {Router, RouterLink} from '@angular/router';
import {Subscription} from 'rxjs';
import {BrandService} from '../../services/brand/brand.service';
import {Brand} from '../../models/brand/brand';
@Component({
selector: 'app-add-product',
standalone: true,
imports: [
FormsModule,
MatButton,
MatCard,
MatCardActions,
MatCardContent,
MatCardHeader,
MatCardSubtitle,
MatCardTitle,
MatCheckbox,
MatDivider,
MatError,
MatFormField,
MatInput,
MatLabel,
MatProgressSpinner,
ReactiveFormsModule,
MatSelect,
MatOption,
RouterLink
],
templateUrl: './add-product.component.html',
styleUrl: './add-product.component.css'
})
export class AddProductComponent implements OnInit, OnDestroy {
addProductForm: FormGroup;
isSubmitted = false;
isLoading = false;
brands: Brand[] = [];
private readonly router: Router = inject(Router);
private addProductSubscription: Subscription | null = null;
private readonly brandService: BrandService = inject(BrandService);
constructor(private readonly formBuilder: FormBuilder) {
this.addProductForm = this.formBuilder.group({
title: ['', [
Validators.required,
Validators.minLength(3),
Validators.maxLength(50),
Validators.pattern('^[a-zA-Z]+$')
]],
description: ['', [
Validators.required,
Validators.minLength(10),
Validators.maxLength(255),
Validators.pattern('^[a-zA-Z]+$')
]],
category: ['', [
Validators.required
]],
condition: ['', [
Validators.required
]],
brand: ['', [
Validators.required
]],
platform: ['', [
Validators.required
]],
complete: [true,
Validators.requiredTrue
],
manual: [true,
Validators.requiredTrue
],
price: ['', [
Validators.required,
Validators.min(0),
Validators.max(9999),
Validators.pattern('^[0-9]+$')
]],
quantity: ['', [
Validators.required,
Validators.min(1),
Validators.max(999),
Validators.pattern('^[0-9]+$')
]]
},
);
}
ngOnInit(): void {
this.brandService.getBrands().subscribe({
next: (brands) => {
this.brands = brands;
},
error: (error) => {
console.error('Error fetching brands:', error);
},
complete: () => {
console.log('Finished fetching brands:', this.brands);
}
});
}
ngOnDestroy(): void {
this.addProductSubscription?.unsubscribe();
}
onProductAdd() {
this.isSubmitted = true;
if (this.addProductForm.valid) {
this.isLoading = true;
const productData = this.addProductForm.value;
alert("Produit ajouté avec succès !");
console.log(productData);
}
}
isFieldInvalid(fieldName: string): boolean {
const field = this.addProductForm.get(fieldName);
return Boolean(field && field.invalid && (field.dirty || field.touched || this.isSubmitted));
}
getFieldError(fieldName: string): string {
const field = this.addProductForm.get(fieldName);
if (field && field.errors) {
if (field.errors['required']) return `Ce champ est obligatoire`;
if (field.errors['email']) return `Format d'email invalide`;
if (field.errors['minlength']) return `Minimum ${field.errors['minlength'].requiredLength} caractères`;
if (field.errors['maxlength']) return `Maximum ${field.errors['maxlength'].requiredLength} caractères`;
}
return '';
}
}