681 lines
24 KiB
HTML
681 lines
24 KiB
HTML
<main class="app-shell">
|
|
<section class="component-demo card shadow-sm">
|
|
<div class="card-body">
|
|
<span class="eyebrow">Componentes reutilizables</span>
|
|
<h1>Button + Input</h1>
|
|
<p class="lead mb-4">
|
|
Pagina dedicada a probar variantes de los componentes compartidos.
|
|
</p>
|
|
|
|
<div class="button-showcase">
|
|
<div class="button-group">
|
|
<h2>Comunes</h2>
|
|
<div class="button-grid">
|
|
<app-button>Primary</app-button>
|
|
<app-button variant="secondary">Secondary</app-button>
|
|
<app-button variant="danger">Danger</app-button>
|
|
<app-button variant="danger-secondary">Danger secondary</app-button>
|
|
<app-button variant="cancel">Cancel</app-button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="button-group">
|
|
<h2>Disabled</h2>
|
|
<div class="button-grid">
|
|
<app-button [disabled]="true">Primary</app-button>
|
|
<app-button variant="secondary" [disabled]="true">Secondary</app-button>
|
|
|
|
<app-button variant="danger" [disabled]="true">Danger</app-button>
|
|
<app-button variant="danger-secondary" [disabled]="true">
|
|
Danger secondary
|
|
</app-button>
|
|
<app-button variant="cancel" [disabled]="true">Cancel</app-button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="button-group">
|
|
<h2>Una letra</h2>
|
|
<div class="button-grid button-grid--single-char">
|
|
<app-button>A</app-button>
|
|
<app-button variant="secondary">B</app-button>
|
|
<app-button variant="danger">C</app-button>
|
|
<app-button variant="danger-secondary">D</app-button>
|
|
<app-button variant="cancel">E</app-button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="button-group">
|
|
<h2>Toasts</h2>
|
|
<div class="button-grid">
|
|
<app-button (click)="triggerToast('info')">Trigger Info</app-button>
|
|
<app-button variant="secondary" (click)="triggerToast('success')">
|
|
Trigger Success
|
|
</app-button>
|
|
<app-button variant="danger" (click)="triggerToast('danger')">
|
|
Trigger Danger
|
|
</app-button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="button-group">
|
|
<h2>Toasts Persistentes (No se van)</h2>
|
|
<div class="button-grid">
|
|
<app-button (click)="triggerPersistentToast('info')">
|
|
Info Persistente
|
|
</app-button>
|
|
<app-button
|
|
variant="secondary"
|
|
(click)="triggerPersistentToast('success')"
|
|
>
|
|
Success Persistente
|
|
</app-button>
|
|
<app-button variant="danger" (click)="triggerPersistentToast('danger')">
|
|
Danger Persistente
|
|
</app-button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="button-group">
|
|
<h2>Modal</h2>
|
|
<p class="text-muted mb-0">
|
|
Demo del modal global con servicio, host y devolucion de resultado.
|
|
</p>
|
|
<div class="button-grid">
|
|
<app-button (click)="openBasicModal()">Abrir confirm modal</app-button>
|
|
<app-button variant="danger" (click)="openConfirmDeleteModal()">
|
|
Abrir confirm delete
|
|
</app-button>
|
|
<app-button variant="secondary" (click)="openLockedModal()">
|
|
Abrir modal bloqueado
|
|
</app-button>
|
|
<app-button variant="danger-secondary" (click)="openWideModal()">
|
|
Abrir modal ancho
|
|
</app-button>
|
|
<app-button (click)="openSimpleModal()">
|
|
Abrir simple modal
|
|
</app-button>
|
|
</div>
|
|
<div class="modal-showcase__result" data-testid="modal-last-result">
|
|
{{ lastModalResult }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<hr class="section-divider" />
|
|
|
|
<div class="icon-button-showcase">
|
|
<h2>Icon Buttons</h2>
|
|
<p class="text-muted mb-4">
|
|
Botones de icono pequenos con color base <code>#666666</code>,
|
|
deshabilitados con <code>#A0A0A0</code> y estados hover/active con color
|
|
de marca (a excepcion de trash que usa danger).
|
|
</p>
|
|
|
|
<div class="icon-button-showcase__grid">
|
|
<div class="icon-button-showcase__row">
|
|
<span class="icon-button-showcase__label">Disabled</span>
|
|
<div class="icon-button-showcase__items">
|
|
<app-icon-button variant="user" [disabled]="true" />
|
|
<app-icon-button variant="trash" [disabled]="true" />
|
|
<app-icon-button variant="angle-left" [disabled]="true" />
|
|
<app-icon-button variant="angle-right" [disabled]="true" />
|
|
<app-icon-button variant="angle-up" [disabled]="true" />
|
|
<app-icon-button variant="angle-down" [disabled]="true" />
|
|
<app-icon-button variant="copy" [disabled]="true" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="icon-button-showcase__row">
|
|
<span class="icon-button-showcase__label">Normal</span>
|
|
<div class="icon-button-showcase__items">
|
|
<app-icon-button variant="user" />
|
|
<app-icon-button variant="trash" />
|
|
<app-icon-button variant="angle-left" />
|
|
<app-icon-button variant="angle-right" />
|
|
<app-icon-button variant="angle-up" />
|
|
<app-icon-button variant="angle-down" />
|
|
<app-icon-button variant="copy" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="icon-button-showcase__row">
|
|
<span class="icon-button-showcase__label">Active / Hover</span>
|
|
<div class="icon-button-showcase__items">
|
|
<app-icon-button variant="user" class="hover-preview" />
|
|
<app-icon-button variant="trash" class="hover-preview" />
|
|
<app-icon-button variant="angle-left" class="hover-preview" />
|
|
<app-icon-button variant="angle-right" class="hover-preview" />
|
|
<app-icon-button variant="angle-up" class="hover-preview" />
|
|
<app-icon-button variant="angle-down" class="hover-preview" />
|
|
<app-icon-button variant="copy" class="hover-preview" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="icon-button-showcase mt-4">
|
|
<h2>Cart Icons</h2>
|
|
<p class="text-muted mb-4">
|
|
Icono de carrito con badge opcional indicando cantidad.
|
|
</p>
|
|
|
|
<div class="icon-button-showcase__grid">
|
|
<div class="icon-button-showcase__row">
|
|
<span class="icon-button-showcase__label">Disabled</span>
|
|
<div class="icon-button-showcase__items">
|
|
<app-cart-icon [disabled]="true" [quantity]="3" />
|
|
<app-cart-icon [disabled]="true" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="icon-button-showcase__row">
|
|
<span class="icon-button-showcase__label">Normal</span>
|
|
<div class="icon-button-showcase__items">
|
|
<app-cart-icon [quantity]="3" />
|
|
<app-cart-icon />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="icon-button-showcase__row">
|
|
<span class="icon-button-showcase__label">Active / Hover</span>
|
|
<div class="icon-button-showcase__items">
|
|
<app-cart-icon [quantity]="3" class="hover-preview" />
|
|
<app-cart-icon class="hover-preview" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="input-grid">
|
|
<div class="input-field">
|
|
<label for="search-input">Texto</label>
|
|
<app-input
|
|
id="search-input"
|
|
type="search"
|
|
placeholder="Buscar producto"
|
|
[(value)]="textValue"
|
|
[maxlength]="24"
|
|
/>
|
|
</div>
|
|
|
|
<div class="input-field">
|
|
<label for="number-input">Numero</label>
|
|
<app-input
|
|
id="number-input"
|
|
type="number"
|
|
placeholder="0"
|
|
[(value)]="numberValue"
|
|
/>
|
|
</div>
|
|
|
|
<div class="input-field">
|
|
<label for="email-input">Email</label>
|
|
<app-input
|
|
id="email-input"
|
|
type="email"
|
|
placeholder="mail@empresa.com"
|
|
[(value)]="email"
|
|
/>
|
|
</div>
|
|
|
|
<div class="input-field">
|
|
<label for="user-input">Usuario</label>
|
|
<app-input
|
|
id="user-input"
|
|
type="user"
|
|
placeholder="Nombre de usuario"
|
|
[(value)]="user"
|
|
/>
|
|
</div>
|
|
|
|
<div class="input-field">
|
|
<label for="password-input">Password</label>
|
|
<app-input
|
|
id="password-input"
|
|
type="password-toggle"
|
|
placeholder="********"
|
|
[(value)]="password"
|
|
/>
|
|
</div>
|
|
|
|
<div class="input-field">
|
|
<label for="date-input">Fecha</label>
|
|
<app-input id="date-input" type="date" [(value)]="date" />
|
|
</div>
|
|
|
|
<div class="input-field">
|
|
<label for="period-input">Periodo</label>
|
|
<app-input id="period-input" type="period" [(value)]="period" />
|
|
</div>
|
|
|
|
<div class="input-field">
|
|
<label for="amount-input">Moneda</label>
|
|
<app-input
|
|
id="amount-input"
|
|
type="currency"
|
|
placeholder="0"
|
|
[(value)]="amount"
|
|
/>
|
|
</div>
|
|
|
|
<div class="input-field">
|
|
<label for="percent-input">Porcentaje</label>
|
|
<app-input
|
|
id="percent-input"
|
|
type="percent"
|
|
placeholder="0"
|
|
[(value)]="percent"
|
|
/>
|
|
</div>
|
|
|
|
<div class="input-field">
|
|
<label for="disabled-input">Deshabilitado</label>
|
|
<app-input
|
|
id="disabled-input"
|
|
placeholder="Campo deshabilitado"
|
|
[value]="disabledValue"
|
|
[disabled]="true"
|
|
/>
|
|
</div>
|
|
|
|
<div class="input-field">
|
|
<label for="editable-input">Editable</label>
|
|
<app-input
|
|
id="editable-input"
|
|
type="editable"
|
|
[(value)]="editableValue"
|
|
[disabled]="editableDisabled"
|
|
(disabledChange)="editableDisabled = $event"
|
|
/>
|
|
</div>
|
|
|
|
<div class="input-field">
|
|
<label for="invalid-input">Invalido</label>
|
|
<app-input
|
|
id="invalid-input"
|
|
type="email"
|
|
placeholder="mail@empresa.com"
|
|
[(value)]="invalidEmail"
|
|
[invalid]="true"
|
|
/>
|
|
</div>
|
|
|
|
<div class="file-field">
|
|
<div class="input-field">
|
|
<label for="file-input">Archivo</label>
|
|
<app-input
|
|
id="file-input"
|
|
type="file"
|
|
accept=".pdf,.png,.jpg"
|
|
[fileName]="fileName"
|
|
[clearTrigger]="clearTrigger"
|
|
(fileChange)="onFileChange($event)"
|
|
/>
|
|
</div>
|
|
|
|
<app-button variant="secondary" (click)="clearFile()">
|
|
Limpiar archivo
|
|
</app-button>
|
|
</div>
|
|
</div>
|
|
|
|
<hr class="section-divider" />
|
|
|
|
<div class="paginator-showcase">
|
|
<h2>Paginator</h2>
|
|
<p class="text-muted mb-0">
|
|
Componente shared para navegar por paginas con primera, anterior,
|
|
siguiente y ultima.
|
|
</p>
|
|
<app-paginator
|
|
[page]="currentPage"
|
|
[totalPages]="paginatorTotalPages"
|
|
(pageChange)="currentPage = $event"
|
|
/>
|
|
</div>
|
|
|
|
<hr class="section-divider" />
|
|
|
|
<div class="stepper-showcase">
|
|
<h2>Form Stepper</h2>
|
|
<p class="text-muted mb-4">
|
|
Stepper vertical reutilizable. Cada paso maneja sus propios botones de navegacion. No se puede avanzar si el paso no es valido.
|
|
</p>
|
|
|
|
<app-stepper #demoStepper>
|
|
|
|
<!-- Paso 1: Siempre valido -->
|
|
<app-step label="Informacion Personal" [isValid]="true">
|
|
<div class="row g-3">
|
|
<div class="col-md-6 input-field">
|
|
<label for="stepper-name">Nombre</label>
|
|
<app-input id="stepper-name" placeholder="Juan Perez" [(value)]="user" />
|
|
</div>
|
|
<div class="col-md-6 input-field">
|
|
<label for="stepper-email">Email</label>
|
|
<app-input id="stepper-email" type="email" placeholder="mail@empresa.com" [(value)]="email" />
|
|
</div>
|
|
</div>
|
|
<div class="d-flex justify-content-end mt-4">
|
|
<app-button (click)="demoStepper.next()">
|
|
Siguiente <i class="fa-solid fa-arrow-right ms-1"></i>
|
|
</app-button>
|
|
</div>
|
|
</app-step>
|
|
|
|
<!-- Paso 2: Valido solo si testStep2Valid es true -->
|
|
<app-step label="Configuracion de Cuenta" [isValid]="testStep2Valid">
|
|
<div class="row g-3">
|
|
<div class="col-md-6 input-field">
|
|
<label for="stepper-password">Contraseña</label>
|
|
<app-input id="stepper-password" type="password-toggle" placeholder="********" [(value)]="password" />
|
|
</div>
|
|
<div class="col-md-6 input-field">
|
|
<label for="stepper-amount">Presupuesto mensual</label>
|
|
<app-input id="stepper-amount" type="currency" placeholder="0" [(value)]="amount" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="stepper-validity-control mt-3 d-flex align-items-center gap-3">
|
|
<span class="text-muted small">
|
|
Simular validez del paso:
|
|
</span>
|
|
<app-button
|
|
[variant]="testStep2Valid ? 'secondary' : 'primary'"
|
|
(click)="testStep2Valid = !testStep2Valid"
|
|
>
|
|
@if (testStep2Valid) {
|
|
<i class="fa-solid fa-check me-1"></i> Valido
|
|
} @else {
|
|
<i class="fa-solid fa-xmark me-1"></i> Invalido — Siguiente bloqueado
|
|
}
|
|
</app-button>
|
|
</div>
|
|
|
|
<div class="d-flex justify-content-between mt-4">
|
|
<app-button variant="secondary" (click)="demoStepper.previous()">
|
|
<i class="fa-solid fa-arrow-left me-1"></i> Volver
|
|
</app-button>
|
|
<app-button (click)="demoStepper.next()" [disabled]="!testStep2Valid">
|
|
Siguiente <i class="fa-solid fa-arrow-right ms-1"></i>
|
|
</app-button>
|
|
</div>
|
|
</app-step>
|
|
|
|
<!-- Paso 3: Revision final, siempre valido -->
|
|
<app-step label="Revision y Confirmacion" [isValid]="true">
|
|
<div class="p-3 rounded bg-light">
|
|
<p class="mb-1"><strong>Nombre:</strong> {{ user }}</p>
|
|
<p class="mb-1"><strong>Email:</strong> {{ email }}</p>
|
|
<p class="mb-0"><strong>Presupuesto:</strong> {{ amount }}</p>
|
|
</div>
|
|
<div class="d-flex justify-content-between mt-4">
|
|
<app-button variant="secondary" (click)="demoStepper.previous()">
|
|
<i class="fa-solid fa-arrow-left me-1"></i> Volver
|
|
</app-button>
|
|
<app-button (click)="triggerToast('success')">
|
|
<i class="fa-solid fa-check me-1"></i> Confirmar
|
|
</app-button>
|
|
</div>
|
|
</app-step>
|
|
|
|
</app-stepper>
|
|
</div>
|
|
|
|
<hr class="section-divider" />
|
|
|
|
<div class="cart-showcase">
|
|
<div class="cart-showcase__header">
|
|
<div>
|
|
<h2>Carrito mock</h2>
|
|
<p class="text-muted mb-0">
|
|
Demo visual aislada del carrito con scroll a partir del cuarto item.
|
|
</p>
|
|
</div>
|
|
|
|
@if (!cartVisible) {
|
|
<app-button variant="secondary" (click)="showCart()">
|
|
Volver a mostrar carrito
|
|
</app-button>
|
|
}
|
|
</div>
|
|
|
|
@if (cartVisible) {
|
|
<div class="cart-showcase__viewport">
|
|
<app-cart
|
|
[showClose]="true"
|
|
[items]="cartMockItems"
|
|
[subtotal]="366000"
|
|
[discount]="66000"
|
|
[total]="300000"
|
|
[backgroundColor]="cartBackgroundColor"
|
|
(closed)="hideCart()"
|
|
/>
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
</div>
|
|
</section>
|
|
|
|
<section class="component-demo card shadow-sm mt-4 configuracion-tennant">
|
|
<div class="card-body">
|
|
<span class="eyebrow">Tenant Configuration</span>
|
|
<h2 class="mb-4">Configuracion Tenant</h2>
|
|
|
|
<div class="row mb-4">
|
|
<div class="col-md-6 mb-3 mb-md-0">
|
|
<div class="tenant-logo-card">
|
|
<div class="tenant-logo-card__label">Logo del Header</div>
|
|
<div class="tenant-logo-card__container header-bg">
|
|
@if (tenant()?.header_logo) {
|
|
<img
|
|
[src]="tenant()?.header_logo"
|
|
alt="Header Logo"
|
|
class="tenant-logo-card__img"
|
|
/>
|
|
} @else {
|
|
<div class="tenant-logo-card__placeholder">
|
|
<i class="fa-solid fa-image mb-2"></i>
|
|
<span>Sin Logo de Header</span>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<div class="tenant-logo-card">
|
|
<div class="tenant-logo-card__label">Logo del Footer</div>
|
|
<div class="tenant-logo-card__container footer-bg">
|
|
@if (tenant()?.footer_logo) {
|
|
<img
|
|
[src]="tenant()?.footer_logo"
|
|
alt="Footer Logo"
|
|
class="tenant-logo-card__img"
|
|
/>
|
|
} @else {
|
|
<div class="tenant-logo-card__placeholder">
|
|
<i class="fa-solid fa-image mb-2"></i>
|
|
<span>Sin Logo de Footer</span>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<hr class="section-divider" />
|
|
|
|
<div class="colors-section">
|
|
<h3 class="mb-3">Colores de Marca</h3>
|
|
<div class="row">
|
|
<div class="col-md-3 mb-3">
|
|
<div class="color-swatch-card shadow-sm">
|
|
<div
|
|
class="color-swatch-card__preview"
|
|
[style.background-color]="'var(--tenant-primary)'"
|
|
></div>
|
|
<div class="color-swatch-card__body">
|
|
<span class="color-swatch-card__title">Primario</span>
|
|
<code class="color-swatch-card__value">
|
|
{{ tenant()?.primary_color || 'Default' }}
|
|
</code>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3 mb-3">
|
|
<div class="color-swatch-card shadow-sm">
|
|
<div
|
|
class="color-swatch-card__preview"
|
|
[style.background-color]="'var(--tenant-secondary)'"
|
|
></div>
|
|
<div class="color-swatch-card__body">
|
|
<span class="color-swatch-card__title">Secundario</span>
|
|
<code class="color-swatch-card__value">
|
|
{{ tenant()?.secondary_color || 'Default' }}
|
|
</code>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3 mb-3">
|
|
<div class="color-swatch-card shadow-sm">
|
|
<div
|
|
class="color-swatch-card__preview"
|
|
[style.background-color]="'var(--tenant-danger)'"
|
|
></div>
|
|
<div class="color-swatch-card__body">
|
|
<span class="color-swatch-card__title">Danger</span>
|
|
<code class="color-swatch-card__value">
|
|
{{ tenant()?.danger_color || 'Default' }}
|
|
</code>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3 mb-3">
|
|
<div class="color-swatch-card shadow-sm">
|
|
<div
|
|
class="color-swatch-card__preview"
|
|
[style.background-color]="'var(--tenant-success)'"
|
|
></div>
|
|
<div class="color-swatch-card__body">
|
|
<span class="color-swatch-card__title">Success</span>
|
|
<code class="color-swatch-card__value">
|
|
{{ tenant()?.success_color || 'Default' }}
|
|
</code>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3 mb-3">
|
|
<div class="color-swatch-card shadow-sm">
|
|
<div
|
|
class="color-swatch-card__preview"
|
|
[style.background-color]="'var(--tenant-header-bg)'"
|
|
></div>
|
|
<div class="color-swatch-card__body">
|
|
<span class="color-swatch-card__title">Header BG</span>
|
|
<code class="color-swatch-card__value">
|
|
{{ tenant()?.header_bg_color || 'Default' }}
|
|
</code>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3 mb-3">
|
|
<div class="color-swatch-card shadow-sm">
|
|
<div
|
|
class="color-swatch-card__preview"
|
|
[style.background-color]="'var(--tenant-footer-bg)'"
|
|
></div>
|
|
<div class="color-swatch-card__body">
|
|
<span class="color-swatch-card__title">Footer BG</span>
|
|
<code class="color-swatch-card__value">
|
|
{{ tenant()?.footer_bg_color || 'Default' }}
|
|
</code>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="component-demo card shadow-sm mt-4">
|
|
<div class="card-body">
|
|
<span class="eyebrow">Reusable Component</span>
|
|
<h2 class="mb-4">Tarjetas de Producto (ProductCard)</h2>
|
|
|
|
<p class="text-muted mb-4">
|
|
Las tarjetas se adaptan al tamano del contenedor padre. A continuacion se
|
|
presentan dentro de una grilla de Bootstrap.
|
|
</p>
|
|
|
|
<div class="row">
|
|
@for (product of testProducts; track product.title) {
|
|
<div class="col-12 col-md-6 col-lg-4 mb-4 d-flex align-items-stretch">
|
|
<app-product-card
|
|
[imageUrl]="product.imageUrl"
|
|
[title]="product.title"
|
|
[originalPrice]="product.originalPrice"
|
|
[discount]="product.discount"
|
|
[transferPrice]="product.transferPrice"
|
|
(buy)="onProductBuy(product.title)"
|
|
/>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="component-demo card shadow-sm mt-4">
|
|
<div class="card-body">
|
|
<span class="eyebrow">Reusable Component</span>
|
|
<h2 class="mb-4">Tarjetas de Producto (Row Layout)</h2>
|
|
|
|
<p class="text-muted mb-4">
|
|
Diseño horizontal que ocupa el 100% del ancho disponible.
|
|
</p>
|
|
|
|
<div class="row">
|
|
<div class="col-12 mb-4 d-flex align-items-stretch">
|
|
<app-product-row-card
|
|
[title]="testRowProduct.title"
|
|
[description]="testRowProduct.description"
|
|
[price]="testRowProduct.price"
|
|
[variants]="testRowProduct.variants"
|
|
(buy)="onProductBuy(testRowProduct.title)"
|
|
(addToCart)="triggerToast('success')"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<app-store-section
|
|
title="PRODUCTOS"
|
|
class="component-demo store-section-demo mt-5"
|
|
>
|
|
<div class="row">
|
|
@for (product of testProducts; track product.title) {
|
|
<div
|
|
class="col-12 col-md-6 col-lg-4 mb-4 d-flex align-items-stretch store-section-demo__item"
|
|
>
|
|
<app-product-card
|
|
[imageUrl]="product.imageUrl"
|
|
[title]="product.title"
|
|
[originalPrice]="product.originalPrice"
|
|
[discount]="product.discount"
|
|
[transferPrice]="product.transferPrice"
|
|
(buy)="onProductBuy(product.title)"
|
|
/>
|
|
</div>
|
|
}
|
|
</div>
|
|
</app-store-section>
|
|
</main>
|
|
|