Compare commits
2 Commits
b7420c2110
...
41b51f06e7
| Author | SHA1 | Date | |
|---|---|---|---|
| 41b51f06e7 | |||
| 526e8fa76e |
@@ -1,6 +1,5 @@
|
|||||||
export interface Product {
|
export interface Product {
|
||||||
id: number;
|
id: number;
|
||||||
tenant_codigo: string;
|
|
||||||
category_id: number;
|
category_id: number;
|
||||||
brand_id: number | null;
|
brand_id: number | null;
|
||||||
slug: string;
|
slug: string;
|
||||||
@@ -17,7 +16,7 @@ export interface ProductAttributeOption {
|
|||||||
value: string;
|
value: string;
|
||||||
label: string;
|
label: string;
|
||||||
sort_order: number;
|
sort_order: number;
|
||||||
metadata: Record<string, any> | null;
|
metadata: Record<string, unknown> | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProductAttribute {
|
export interface ProductAttribute {
|
||||||
@@ -25,19 +24,27 @@ export interface ProductAttribute {
|
|||||||
codigo: string;
|
codigo: string;
|
||||||
nombre: string;
|
nombre: string;
|
||||||
is_required: boolean;
|
is_required: boolean;
|
||||||
metadata_schema: Record<string, any> | null;
|
metadata_schema: Record<string, unknown> | null;
|
||||||
type: string;
|
type: string;
|
||||||
options: ProductAttributeOption[];
|
options: ProductAttributeOption[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProductVariant {
|
export interface ProductVariant {
|
||||||
variant_id: number;
|
id: number;
|
||||||
|
stock: number;
|
||||||
|
definitions: Record<string, string>;
|
||||||
images: string[];
|
images: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ProductVariantMap {
|
||||||
|
variant_id: number;
|
||||||
|
stock: number;
|
||||||
attributes: Record<string, string>;
|
attributes: Record<string, string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProductDetail extends Product {
|
export interface ProductDetail extends Product {
|
||||||
attributes: ProductAttribute[];
|
attributes: ProductAttribute[];
|
||||||
default_variant: ProductVariant | null;
|
variants_map: ProductVariantMap[];
|
||||||
|
variant: ProductVariant | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import { ProductDetailPageComponent } from './product-detail-page.component';
|
|||||||
describe('ProductDetailPageComponent', () => {
|
describe('ProductDetailPageComponent', () => {
|
||||||
const mockProduct: ProductDetail = {
|
const mockProduct: ProductDetail = {
|
||||||
id: 1,
|
id: 1,
|
||||||
tenant_codigo: 'test',
|
|
||||||
category_id: 10,
|
category_id: 10,
|
||||||
brand_id: null,
|
brand_id: null,
|
||||||
slug: 'auriculares-bluetooth',
|
slug: 'auriculares-bluetooth',
|
||||||
@@ -27,7 +26,8 @@ describe('ProductDetailPageComponent', () => {
|
|||||||
brand: 'Sony',
|
brand: 'Sony',
|
||||||
images: ['https://example.com/image.png'],
|
images: ['https://example.com/image.png'],
|
||||||
attributes: [],
|
attributes: [],
|
||||||
default_variant: null
|
variants_map: [],
|
||||||
|
variant: null
|
||||||
};
|
};
|
||||||
|
|
||||||
let paramMapSubject: BehaviorSubject<any>;
|
let paramMapSubject: BehaviorSubject<any>;
|
||||||
@@ -132,10 +132,11 @@ describe('ProductDetailPageComponent', () => {
|
|||||||
const detailProduct: ProductDetail = {
|
const detailProduct: ProductDetail = {
|
||||||
...mockProduct,
|
...mockProduct,
|
||||||
images: ['https://example.com/product.png'],
|
images: ['https://example.com/product.png'],
|
||||||
default_variant: {
|
variant: {
|
||||||
variant_id: 123,
|
id: 123,
|
||||||
|
stock: 10,
|
||||||
images: ['https://example.com/variant1.png', 'https://example.com/variant2.png'],
|
images: ['https://example.com/variant1.png', 'https://example.com/variant2.png'],
|
||||||
attributes: {}
|
definitions: {}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
catalogServiceStub.getProducto.mockReturnValue(of(detailProduct));
|
catalogServiceStub.getProducto.mockReturnValue(of(detailProduct));
|
||||||
@@ -152,7 +153,7 @@ describe('ProductDetailPageComponent', () => {
|
|||||||
const detailProduct: ProductDetail = {
|
const detailProduct: ProductDetail = {
|
||||||
...mockProduct,
|
...mockProduct,
|
||||||
images: ['https://example.com/product.png'],
|
images: ['https://example.com/product.png'],
|
||||||
default_variant: null
|
variant: null
|
||||||
};
|
};
|
||||||
catalogServiceStub.getProducto.mockReturnValue(of(detailProduct));
|
catalogServiceStub.getProducto.mockReturnValue(of(detailProduct));
|
||||||
|
|
||||||
@@ -168,7 +169,7 @@ describe('ProductDetailPageComponent', () => {
|
|||||||
const detailProduct: ProductDetail = {
|
const detailProduct: ProductDetail = {
|
||||||
...mockProduct,
|
...mockProduct,
|
||||||
images: [],
|
images: [],
|
||||||
default_variant: null
|
variant: null
|
||||||
};
|
};
|
||||||
catalogServiceStub.getProducto.mockReturnValue(of(detailProduct));
|
catalogServiceStub.getProducto.mockReturnValue(of(detailProduct));
|
||||||
|
|
||||||
@@ -233,10 +234,11 @@ describe('ProductDetailPageComponent', () => {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
default_variant: {
|
variant: {
|
||||||
variant_id: 123,
|
id: 123,
|
||||||
|
stock: 10,
|
||||||
images: ['https://example.com/variant1.png'],
|
images: ['https://example.com/variant1.png'],
|
||||||
attributes: {
|
definitions: {
|
||||||
color: 'beige',
|
color: 'beige',
|
||||||
material: 'Cuero'
|
material: 'Cuero'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,10 @@ import {
|
|||||||
effect,
|
effect,
|
||||||
inject,
|
inject,
|
||||||
signal,
|
signal,
|
||||||
viewChild
|
viewChild,
|
||||||
|
PLATFORM_ID
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule, isPlatformBrowser } from '@angular/common';
|
||||||
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
|
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
|
||||||
import { combineLatest, Subscription } from 'rxjs';
|
import { combineLatest, Subscription } from 'rxjs';
|
||||||
|
|
||||||
@@ -38,6 +39,8 @@ export class ProductDetailPageComponent implements OnInit, OnDestroy {
|
|||||||
private readonly catalogService = inject(CatalogService);
|
private readonly catalogService = inject(CatalogService);
|
||||||
private readonly carouselHost = viewChild<ElementRef<HTMLElement>>('carouselHost');
|
private readonly carouselHost = viewChild<ElementRef<HTMLElement>>('carouselHost');
|
||||||
private readonly descriptionBody = viewChild<ElementRef<HTMLElement>>('descriptionBody');
|
private readonly descriptionBody = viewChild<ElementRef<HTMLElement>>('descriptionBody');
|
||||||
|
private readonly platformId = inject(PLATFORM_ID);
|
||||||
|
private readonly isBrowser = isPlatformBrowser(this.platformId);
|
||||||
|
|
||||||
private routeSub: Subscription | null = null;
|
private routeSub: Subscription | null = null;
|
||||||
private productSub: Subscription | null = null;
|
private productSub: Subscription | null = null;
|
||||||
@@ -49,8 +52,8 @@ export class ProductDetailPageComponent implements OnInit, OnDestroy {
|
|||||||
protected readonly carouselImages = computed(() => {
|
protected readonly carouselImages = computed(() => {
|
||||||
const prod = this.product();
|
const prod = this.product();
|
||||||
if (!prod) return [];
|
if (!prod) return [];
|
||||||
if (prod.default_variant?.images && prod.default_variant.images.length > 0) {
|
if (prod.variant?.images && prod.variant.images.length > 0) {
|
||||||
return prod.default_variant.images;
|
return prod.variant.images;
|
||||||
}
|
}
|
||||||
if (prod.images && prod.images.length > 0) {
|
if (prod.images && prod.images.length > 0) {
|
||||||
return prod.images;
|
return prod.images;
|
||||||
@@ -82,10 +85,12 @@ export class ProductDetailPageComponent implements OnInit, OnDestroy {
|
|||||||
this.product();
|
this.product();
|
||||||
this.descriptionExpanded();
|
this.descriptionExpanded();
|
||||||
|
|
||||||
queueMicrotask(() => {
|
if (this.isBrowser) {
|
||||||
this.bindCarouselResizeObserver();
|
queueMicrotask(() => {
|
||||||
this.refreshMeasurements();
|
this.bindCarouselResizeObserver();
|
||||||
});
|
this.refreshMeasurements();
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,7 +186,7 @@ export class ProductDetailPageComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private initializeSelections(product: ProductDetail): void {
|
private initializeSelections(product: ProductDetail): void {
|
||||||
const defaultVariant = product.default_variant;
|
const defaultVariant = product.variant;
|
||||||
const selections: Record<number, number> = {};
|
const selections: Record<number, number> = {};
|
||||||
|
|
||||||
for (const attribute of product.attributes) {
|
for (const attribute of product.attributes) {
|
||||||
@@ -202,7 +207,7 @@ export class ProductDetailPageComponent implements OnInit, OnDestroy {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultValue = this.getDefaultVariantAttributeValue(attribute, variant.attributes);
|
const defaultValue = this.getDefaultVariantAttributeValue(attribute, variant.definitions);
|
||||||
if (!defaultValue) {
|
if (!defaultValue) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ describe('StoreHomePageComponent', () => {
|
|||||||
const pageOneProducts: Product[] = [
|
const pageOneProducts: Product[] = [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
tenant_codigo: 'test',
|
|
||||||
category_id: 10,
|
category_id: 10,
|
||||||
brand_id: null,
|
brand_id: null,
|
||||||
slug: 'auriculares-bluetooth',
|
slug: 'auriculares-bluetooth',
|
||||||
@@ -50,7 +49,6 @@ describe('StoreHomePageComponent', () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
tenant_codigo: 'test',
|
|
||||||
category_id: 11,
|
category_id: 11,
|
||||||
brand_id: null,
|
brand_id: null,
|
||||||
slug: 'teclado-mecanico',
|
slug: 'teclado-mecanico',
|
||||||
@@ -106,7 +104,6 @@ describe('StoreHomePageComponent', () => {
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
id: 3,
|
id: 3,
|
||||||
tenant_codigo: 'test',
|
|
||||||
category_id: 12,
|
category_id: 12,
|
||||||
brand_id: null,
|
brand_id: null,
|
||||||
slug: 'mouse-gamer',
|
slug: 'mouse-gamer',
|
||||||
|
|||||||
Reference in New Issue
Block a user