exercises

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

product-details.component.ts (2556B)


      1 import { Component, effect, inject, input, signal } from '@angular/core';
      2 import { ProductService } from './products.service';
      3 import { CommonModule } from '@angular/common';
      4 import { CartService } from '../services/cart.service';
      5 import { RouterLink } from '@angular/router';
      6 
      7 @Component({
      8   selector: 'div.product-details',
      9   templateUrl: './product-details.component.html',
     10   styleUrls: ['./product-details.component.scss'],
     11   standalone: true,
     12   imports: [CommonModule, RouterLink],
     13 })
     14 export class ProductDetailsComponent {
     15   private productService = inject(ProductService);
     16   private cartService = inject(CartService);
     17   // Input signal for productId from route parameter
     18   readonly productId = input<string>('');
     19 
     20   // State signals
     21   readonly product = signal<Product | null>(null);
     22   readonly loading = signal<boolean>(false);
     23   readonly error = signal<string | null>(null);
     24 
     25   constructor() {
     26     // Effect to load product when productId changes
     27     effect(() => {
     28       const id = this.productId();
     29       if (id) {
     30         this.loadProduct(id);
     31       }
     32     });
     33   }
     34 
     35   private loadProduct(id: string): void {
     36     this.loading.set(true);
     37     this.error.set(null);
     38 
     39     this.productService.getProduct(id).subscribe({
     40       next: (product) => {
     41         this.product.set(product);
     42         this.loading.set(false);
     43       },
     44       error: (err) => {
     45         console.error('Failed to load product:', err);
     46         this.error.set('Failed to load product details. Please try again.');
     47         this.loading.set(false);
     48       },
     49     });
     50   }
     51 
     52   get discount(): number {
     53     const product = this.product() as Product;
     54     const initial = parseFloat(product.initial_price || '0');
     55     const discount = parseFloat(product.discount || '0');
     56     return initial > 0 ? Math.round((discount / initial) * 100) : 0;
     57   }
     58 
     59   addToCart(): void {
     60     const product = this.product();
     61     if (product && product.stock > 0) {
     62       // Convert Product to ProductCard format for cart service
     63       const productCard: ProductCard = {
     64         eid: product.eid,
     65         product_name: product.product_name,
     66         description: product.description,
     67         category_name: product.category_name,
     68         final_price: product.final_price,
     69         initial_price: product.initial_price,
     70         discount: product.discount,
     71         stock: product.stock,
     72         average_rating: null, // Not available in Product interface
     73         reviews_count: null, // Not available in Product interface
     74         brand: product.brand,
     75       };
     76       this.cartService.addToCart(productCard);
     77     }
     78   }
     79 }