diff --git a/src/app/features/componentes-test/pages/reutilizables-test-page/reutilizables-test-page.component.html b/src/app/features/componentes-test/pages/reutilizables-test-page/reutilizables-test-page.component.html index fd4cf52..831ea18 100644 --- a/src/app/features/componentes-test/pages/reutilizables-test-page/reutilizables-test-page.component.html +++ b/src/app/features/componentes-test/pages/reutilizables-test-page/reutilizables-test-page.component.html @@ -631,6 +631,30 @@ + + + Reusable Component + Tarjetas de Producto (Row Layout) + + + Diseño horizontal que ocupa el 100% del ancho disponible. + + + + + + + + + + + + + + {{ title() }} + + @if (description()) { + + {{ description() }} + + } + + + + + + + + {{ formattedPrice() }} + + + + Comprar + + + + + + + @if (variants().length > 0) { + + @for (variant of variants(); track variant.value) { + {{ variant.label }} + } + + } + + + + + + Agregar al carrito + + + + + diff --git a/src/app/shared/components/product-row-card/product-row-card.component.scss b/src/app/shared/components/product-row-card/product-row-card.component.scss new file mode 100644 index 0000000..e1dd7a7 --- /dev/null +++ b/src/app/shared/components/product-row-card/product-row-card.component.scss @@ -0,0 +1,63 @@ +:host { + display: block; + width: 100%; +} + +.product-row-card { + width: 100%; + background-color: #f8f9fa; /* slightly light bg matching the screenshot if needed, but let's use white or #f8f9fa based on the border */ + border-color: #e9ecef !important; + + &__title { + font-size: 16px; + font-weight: 700; + color: #555; /* dark grey matching screenshot */ + letter-spacing: 0.5px; + } + + &__description { + font-size: 13px; + color: #777; /* lighter grey for text */ + line-height: 1.4; + max-width: 600px; + + /* Simulate the bold text for 'Niños menores...' if it was HTML. + Since it's passed as string we just let it be, unless we parse it. */ + } + + &__price { + font-size: 20px; + font-weight: 800; + color: var(--tenant-primary, #009933) !important; /* Green matching screenshot */ + } + + &__select { + width: auto; + min-width: 150px; + font-size: 14px; + height: 38px; + color: #666; + border-color: #ccc; + cursor: pointer; + + &:focus { + border-color: var(--tenant-primary); + box-shadow: 0 0 0 0.25rem rgba(0, 153, 51, 0.25); + } + } + + &__btn-wrapper { + min-width: 160px; /* To make both buttons equal width as in screenshot */ + + app-button { + display: block; + width: 100%; + + ::ng-deep .btn { + width: 100%; + font-weight: 600; + border-radius: 4px; + } + } + } +} diff --git a/src/app/shared/components/product-row-card/product-row-card.component.ts b/src/app/shared/components/product-row-card/product-row-card.component.ts new file mode 100644 index 0000000..5a8448d --- /dev/null +++ b/src/app/shared/components/product-row-card/product-row-card.component.ts @@ -0,0 +1,55 @@ +import { ChangeDetectionStrategy, Component, computed, input, output, model } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { ButtonComponent } from '../button/button.component'; +import { QuantitySelectorComponent } from '../quantity-selector/quantity-selector.component'; + +export interface Variant { + label: string; + value: any; +} + +@Component({ + selector: 'app-product-row-card', + standalone: true, + imports: [ButtonComponent, QuantitySelectorComponent, FormsModule], + templateUrl: './product-row-card.component.html', + styleUrl: './product-row-card.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ProductRowCardComponent { + // Configurable inputs + readonly title = input(''); + readonly description = input(''); + readonly price = input(0); + readonly variants = input([]); + + // Internal state models + readonly quantity = model(1); + readonly selectedVariant = model(null); + + // Interactive events + readonly buy = output(); + readonly addToCart = output<{ quantity: number; variant: any }>(); + + // Formatted string for price: "$ 10.000" + readonly formattedPrice = computed(() => { + return this.formatCurrency(this.price()); + }); + + protected onAddToCart(): void { + this.addToCart.emit({ + quantity: this.quantity(), + variant: this.selectedVariant() + }); + } + + /** + * Helper method to format currency numbers to Argentine Pesos style "$ XX.XXX". + */ + private formatCurrency(value: number): string { + const rounded = Math.round(value); + const parts = rounded.toString().split('.'); + parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, '.'); + return `$ ${parts.join(',')}`; + } +}
+ Diseño horizontal que ocupa el 100% del ancho disponible. +
+ {{ description() }} +