commercetools-8.x-1.2-alpha1/modules/commercetools_decoupled/js/molecules/ProductListItem.js

modules/commercetools_decoupled/js/molecules/ProductListItem.js
class ProductListItem extends HTMLElement {
  connectedCallback() {
    const placeholderProduct = {
      name: 'Placeholder for title',
      slug: 'placeholder-path',
      masterVariant: {
        images: [{ url: '' }],
        price: { localizedPrice: '$1000' },
      },
      isLoading: true,
    };
    const product = this.isLoading !== true ? this.product : placeholderProduct;
    this.name = product.name;
    if (!product.slug) {
      new Drupal.Message().add(
        'The product slug value is missing for a product.',
        { type: 'error' },
      );
    }
    this.path = Drupal.url(
      `${drupalSettings.commercetoolsDecoupled.catalogPath.substring(1)}/${product.slug}`,
    );

    this.image = product?.masterVariant?.images?.[0]?.url ?? '';
    if (this.image) {
      this.image = window.commercetools.applyImageStyle(this.image);
    }

    this.price = product?.masterVariant?.price ?? {};
    this.isLoading = product.isLoading;

    const priceHtml = this.price?.discounted?.localizedPrice
      ? `${this.price?.localizedPrice ? `<del>${this.price.localizedPrice}</del>` : ''} <span class="discount text-danger">${this.price.discounted.localizedPrice}</span>`
      : this.price?.localizedPrice || '';

    this.innerHTML = /* html */ `
    <figure class="card flex-row h-100${this.isLoading ? ' placeholderify' : ''}">
      <div class="container">
        <div class="row">
          <div class="col-4">
            <a class="h-100" href="${this.path}">
              <div class="h-100 d-flex flex-wrap align-items-center">
                <img src="${this.image}" class="p-2 m-auto max-width" alt="${this.name}" style="max-height: 16rem; width: auto; max-width: 100%">
              </div>
            </a>
          </div>
          <div class="col-8 card-body d-flex flex-column">
            <h2 class="card-title fs-5 text-truncate text-primary"><a class="text-decoration-none" href="${this.path}">${this.name}</a></h2>
            <div class="border-top py-3 mb-3">
              ${
                this.isLoading || !product?.masterVariant?.attributes
                  ? ''
                  : Object.values(product.masterVariant.attributes)
                      .map((attr) => {
                        attr.key = attr.name;
                        document.dispatchEvent(
                          new CustomEvent(
                            'commercetools:productAttributeLabel',
                            { detail: attr },
                          ),
                        );
                        return `
                        <div class="fw-medium">
                          <span>${attr.label}: </span>
                          <span ${attr.name === 'color' || attr.name === 'finish' ? '' : `style="white-space: pre-wrap;"`}>${attr.labelValue}</span>
                        </div>
                      `;
                      })
                      .join('')
              }
            </div>
            <div class="border-top pt-3">
              <a href="${this.path}" class="card-btn btn btn-primary btn-sm float-end">${Drupal.t('Details')}</a>
              ${priceHtml ? `<span class="price">${priceHtml}</span>` : ''}
            </div>
          </div>
        </div>
      </div>
    </figure>
    `;
  }

  setLoadingState(state = null) {
    const stateClasses = {
      load: 'placeholderify',
      reload: 'reloadify',
    };

    this.querySelectorAll('figure.card').forEach((card) => {
      card.classList.remove(...Object.values(stateClasses));
      const stateClass = stateClasses[state];
      if (state !== null && stateClass) {
        card.classList.add(stateClass);
      }
    });
  }
}

customElements.define('ct-product-list-item', ProductListItem);

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc