Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import {
- Widget,
- WidgetInterface
- } from '@shop-builder/core/widget';
- import { findOneById, findAll, findOneAttributeById } from '@api/services/products';
- import { findOneStandardOfVoiceData } from '@api/services/tariff';
- import { findOneStandardOfData } from '@api/services/tariff';
- import { findOneByComponentSet } from '@api/services/offers';
- import { getHexcodeByColor } from '@api/utils';
- import { Configurator } from '@api/services/configurator';
- import { formatEuro } from '@api/utils';
- import { scrollTo } from '@api/utils';
- import { preloadImages } from '@api/utils';
- import { getWidget } from '@api/utils';
- import { DeviceDetailColor } from './device-detail-color';
- import { DeviceDetailCapacity } from './device-detail-capacity';
- import Flickity from 'flickity';
- import { SERVICE_TYPE_PROMO_BUBBLE } from '@api/schema/offer';
- import { BUNDLE_DESCRIPTION_ATTRIBUTE } from '@api/schema/product';
- import { BasketAssistant } from '@api/services/basket';
- declare var jQuery: any;
- @Widget({
- name: 'device-detail'
- })
- export class DeviceDetailWidget {
- public getElement: Function;
- public product;
- public offer;
- public topSmartphoneDealElement;
- public standardTariff;
- public flkty;
- public currentSlideIndex: number = 0;
- private checkboxTimeout;
- private colorComponents: Array<DeviceDetailColor> = [];
- private capacityComponents: Array<DeviceDetailCapacity> = [];
- private currentImages: string = '';
- public async didMount (): Promise<void> {
- this.showContainer();
- await this.loadProduct();
- this.registerEventListeners();
- }
- public registerEventListeners () {
- this.getElement().querySelector('.tariff-cta').addEventListener('click', scrollTo.bind(null, 'tariff-slider'));
- this.getElement().querySelector('.more-details').addEventListener('click', (e) => {
- e.preventDefault();
- const widget = getWidget('device-detail-tabs');
- if (widget) {
- widget.switchToTechnicalDetails();
- scrollTo('device-detail-tabs');
- }
- });
- }
- public async setOffer () {
- this.offer = Configurator.getOffer();
- this.setPrice(this.offer.getOnetimePrice());
- if (this.product.currentVersionContainsBundle()) {
- this.setSubTitle(this.product.getAttributeById(BUNDLE_DESCRIPTION_ATTRIBUTE).value);
- } else {
- this.setSubTitle('');
- }
- const child = this.product.getCurrentVersion();
- const deliveryTime = child.additional.deliveryTime;
- this.getElement().querySelector('.delivery-time').innerHTML = deliveryTime;
- if (Configurator.getTariff()) {
- const tariff = Configurator.getTariff();
- this.setWhichTariff(tariff.label);
- // Check if top smartphone deal is possible with current tariff
- if (Configurator.getTariff().topSmartphoneDeals.indexOf(this.product.id) > -1) {
- this.showTopSmartphoneDeal();
- if (!this.product.usesTopSmartphoneDeal() && this.topSmartphoneDealChecked()) {
- this.uncheckTopSmartphoneDeal();
- }
- } else {
- this.hideTopSmartphoneDeal();
- }
- }
- const promoFlags = this.offer.getServicesByType(SERVICE_TYPE_PROMO_BUBBLE);
- if (promoFlags.length) {
- this.showPromoBubble(promoFlags[promoFlags.length - 1].description.additional.image);
- } else {
- this.hidePromoBubble();
- }
- this.setPreview();
- }
- public async loadProduct () {
- let product = await Configurator.getProduct();
- this.product = product;
- let deviceId = 0;
- if (product) {
- deviceId = product.getId();
- if (this.product.currentVersionContainsBundle()) {
- this.setSubTitle(this.product.getAttributeById(BUNDLE_DESCRIPTION_ATTRIBUTE).value);
- } else {
- this.setSubTitle('');
- }
- }
- if (this.getElement().dataset.device && !Configurator.hasExternalProduct()) {
- if (this.getElement().dataset.device.length > 0) {
- deviceId = parseInt(this.getElement().dataset.device, 10);
- product = await findOneById(deviceId);
- await Configurator.setProduct(product);
- this.product = product;
- }
- }
- if (this.product.getSubsidizedWith() === 'voice') {
- this.standardTariff = await findOneStandardOfVoiceData();
- } else {
- this.standardTariff = await findOneStandardOfData();
- }
- if (Configurator.getOffer()) {
- await this.setOffer();
- }
- if (!Configurator.getTariff()) {
- await Configurator.setTariff(this.standardTariff);
- }
- if (product.hasTopSmartphoneDeal()) {
- this.displayTopSmartphoneDeal();
- }
- if (product.hasTopSmartphoneDeal() && !Configurator.hasExternalProduct()) {
- this.setWhichTariff(Configurator.getTariff().label);
- this.checkTopSmartphoneDeal();
- } else if (product.hasTopSmartphoneDeal()) {
- if (product.usesTopSmartphoneDeal()) {
- setTimeout(() => {
- this.checkTopSmartphoneDeal();
- }, 1000);
- }
- }
- this.setPreview();
- this.setTopFeatures(product.getTopFeatures());
- if (product.getColors().length > 0) {
- await this.setColors(product.getColors(), product.getAllColors());
- }
- if (product.getCapacities().length > 0) {
- await this.setCapacities(product.getCapacities(), product.getAllCapacities());
- }
- if (product.getColors().length > 0) {
- await this.selectColor(product.getCurrentColor());
- }
- if (product.getColors().length > 0) {
- await this.selectCapacity(product.getCurrentCapacity());
- }
- Configurator.subscribe('offerChanged', this.setOffer.bind(this));
- if (Configurator.getOffer()) {
- await this.setOffer();
- }
- setTimeout(() => {
- this.show();
- }, 250);
- }
- public setSubTitle (label: string) {
- if (label.length > 0) {
- if (this.getElement().querySelector('.title .sub-headline')) {
- this.getElement().querySelector('.title .sub-headline').innerHTML = label;
- } else {
- const subHeadlineElement = document.createElement('h3');
- subHeadlineElement.className = 'sub-headline loaded';
- subHeadlineElement.innerHTML = label;
- this.getElement().querySelector('.title').appendChild(subHeadlineElement);
- }
- } else if (this.getElement().querySelector('.title .sub-headline')) {
- this.getElement().querySelector('.title .sub-headline').remove();
- }
- }
- public async setPreview () {
- let images = this.product.getShowcaseImages();
- if (images.length === 0) {
- images = ['https://www.vodafone.de' + this.product.getImages().large];
- }
- if (this.currentImages === JSON.stringify(images)) {
- return;
- } else {
- this.currentImages = JSON.stringify(images);
- }
- const preview = document.createElement('div');
- preview.innerHTML = '';
- preview.classList.add('product-preview');
- preview.classList.add('main-carousel');
- preview.dataset.preview = '';
- preview.style.opacity = '0';
- preview.style.display = 'none';
- await preloadImages(images);
- for (const url of images) {
- const wrap = document.createElement('div');
- wrap.classList.add('carousel-cell');
- const image = document.createElement('img');
- image.setAttribute('src', url);
- wrap.appendChild(image);
- preview.appendChild(wrap);
- }
- this.getElement().querySelector('.product-image').innerHTML = '';
- this.getElement().querySelector('.product-image').appendChild(preview);
- this.flkty = new Flickity(preview, {
- pageDots: false,
- accessibility: false,
- resize: true,
- wrapAround: true,
- cellAlign: 'center',
- initialIndex: typeof images[this.currentSlideIndex] !== 'undefined' ? this.currentSlideIndex : 0
- });
- this.flkty.on('change', i => this.currentSlideIndex = i);
- preview.style.display = 'block';
- setTimeout(() => {
- preview.style.opacity = '1';
- this.flkty.resize();
- }, 250);
- }
- public async setColors (colors: any, allColors: any) {
- const preview = this.getElement()
- .querySelector('[data-colorChoices]')
- .querySelector('.choices');
- preview.innerHTML = '';
- const currentColor = Configurator.getProduct().getCurrentColor();
- Configurator.getProduct().stopEventListeners();
- for (const color of allColors) {
- const hexcode = getHexcodeByColor(color);
- const colorComponent = new DeviceDetailColor(hexcode, color);
- this.colorComponents.push(colorComponent);
- if (colors.indexOf(color) > -1) {
- Configurator.getProduct().selectColor(color);
- try {
- const sampleOffer = await findOneByComponentSet([this.standardTariff, Configurator.getProduct()]);
- if (sampleOffer) {
- if (color === currentColor) {
- colorComponent.activate();
- }
- }
- }
- catch (e) {
- colorComponent.disable();
- }
- } else {
- colorComponent.disable();
- }
- colorComponent.onClick(this.selectColor.bind(this, color));
- preview.appendChild(colorComponent.render());
- }
- Configurator.getProduct().selectColor(currentColor);
- Configurator.getProduct().resumeEventListeners();
- if (colors.length > 0) {
- this.getElement()
- .querySelector('[data-colorChoices]')
- .className = 'item';
- this.activateConfiguration();
- }
- }
- public async updateColorComponents () {
- const currentColor = Configurator.getProduct().getCurrentColor();
- Configurator.getProduct().stopEventListeners();
- for (const colorComponent of this.colorComponents) {
- const match = Configurator.getProduct().selectColor(colorComponent.getValue());
- try {
- const sampleOffer = await findOneByComponentSet([this.standardTariff, Configurator.getProduct()]);
- if (sampleOffer && match) {
- if (currentColor === colorComponent.getValue()) {
- colorComponent.activate();
- } else {
- colorComponent.enable();
- }
- } else {
- colorComponent.disable();
- }
- }
- catch (e) {
- colorComponent.disable();
- }
- }
- Configurator.getProduct().selectColor(currentColor);
- Configurator.getProduct().resumeEventListeners();
- }
- public async selectColor (color: string) {
- let colorElement = this.getElement().querySelector(`[data-color="${color}"]`);
- if (!colorElement) {
- colorElement = this.getElement().querySelectorAll('[data-color]')[0];
- color = colorElement.dataset.color;
- }
- if (colorElement.className.indexOf('inactive') > -1) {
- return;
- }
- for (const element of this.getElement().querySelectorAll('.color-choice')) {
- element.classList.remove('active');
- }
- colorElement.querySelector('.color-choice').className = 'color-choice active';
- this
- .getElement()
- .querySelector('[data-colorChoices] .item-title span')
- .innerHTML = color;
- this.product.selectColor(color);
- this.setPreview();
- await this.updateCapacityComponents();
- }
- public async setCapacities (capacities: any, allCapacities: any) {
- const preview = this.getElement()
- .querySelector('[data-capacityChoices]')
- .querySelector('.choices');
- preview.innerHTML = '';
- const currentCapacity = Configurator.getProduct().getCurrentCapacity();
- Configurator.getProduct().stopEventListeners();
- for (const capacity of allCapacities) {
- const capacityComponent = new DeviceDetailCapacity(capacity);
- this.capacityComponents.push(capacityComponent);
- if (capacities.indexOf(capacity) > -1) {
- Configurator.getProduct().selectCapacity(capacity);
- try {
- const sampleOffer = await findOneByComponentSet([this.standardTariff, Configurator.getProduct()]);
- if (sampleOffer) {
- if (capacity === currentCapacity) {
- capacityComponent.activate();
- } else {
- capacityComponent.enable();
- }
- } else {
- capacityComponent.disable();
- }
- }
- catch (e) {
- capacityComponent.disable();
- }
- } else {
- capacityComponent.disable();
- }
- capacityComponent.onClick(this.selectCapacity.bind(this, capacity));
- preview.appendChild(capacityComponent.render());
- }
- Configurator.getProduct().selectCapacity(currentCapacity);
- Configurator.getProduct().resumeEventListeners();
- if (capacities.length > 0) {
- this.getElement()
- .querySelector('[data-capacityChoices]')
- .className = 'item';
- this.activateConfiguration();
- }
- }
- public async updateCapacityComponents () {
- const currentCapacity = Configurator.getProduct().getCurrentCapacity();
- Configurator.getProduct().stopEventListeners();
- for (const capacityComponent of this.capacityComponents) {
- const match = Configurator.getProduct().selectCapacity(capacityComponent.getCapacity());
- try {
- const sampleOffer = await findOneByComponentSet([this.standardTariff, Configurator.getProduct()]);
- if (sampleOffer && match) {
- if (currentCapacity === capacityComponent.getCapacity()) {
- capacityComponent.activate();
- } else {
- capacityComponent.enable();
- }
- } else {
- capacityComponent.disable();
- }
- }
- catch (e) {
- capacityComponent.disable();
- }
- }
- Configurator.getProduct().selectCapacity(currentCapacity);
- Configurator.getProduct().resumeEventListeners();
- }
- public async selectCapacity (capacity: string) {
- let capacityElement = this.getElement().querySelector(`[data-capacity="${capacity}"]`);
- if (!capacityElement) {
- capacityElement = this.getElement().querySelectorAll('[data-capacity]')[0];
- capacity = capacityElement.dataset.capacity;
- }
- if (capacityElement.className.indexOf('inactive') > -1) {
- return;
- }
- for (const element of this.getElement().querySelectorAll('.capacity-choice')) {
- element.classList.remove('active');
- }
- capacityElement.querySelector('.capacity-choice').className = 'capacity-choice active';
- this
- .getElement()
- .querySelector('[data-capacityChoices] .item-title span')
- .innerHTML = capacity;
- this.product.selectCapacity(capacity);
- this.setPreview();
- await this.updateColorComponents();
- }
- public activateConfiguration () {
- const configurationElement = this.getElement().querySelector('.configuration');
- configurationElement.className = 'configuration';
- }
- public setTopFeatures (features: Array<string>) {
- const featuresElement = this.getElement().querySelector('.top-features ul');
- featuresElement.innerHTML = '';
- for (const feature of features) {
- const element = document.createElement('li');
- element.innerHTML = feature;
- featuresElement.appendChild(element);
- }
- }
- public setPrice (price: number) {
- const priceElement = this.getElement().querySelector('.price');
- priceElement.innerHTML = formatEuro(price);
- }
- public setWhichTariff (label: string) {
- const whichTariffElement = this.getElement().querySelector('.pricing .description');
- const descriptionLabel = 'Gerätepreis im Tarif ';
- const whichTariff = `<span class="which-tariff">${label} </span>`;
- const topSmartphoneDealUsed = `<span class="premium-smartphone">mit <b>Premium-Smartphone-Deal</b></span>`;
- whichTariffElement.innerHTML = descriptionLabel + whichTariff;
- if (this.product.usesTopSmartphoneDeal()) {
- whichTariffElement.innerHTML += topSmartphoneDealUsed;
- }
- }
- public displayTopSmartphoneDeal () {
- const smartphoneDealTemplate = `
- <div class="fm-check option">
- <input type="checkbox" name="checkbox" id="checkbox" value="checkbox" ${this.product.usesTopSmartphoneDeal() ? 'checked' : ''}>
- <label for="checkbox" class="${this.product.usesTopSmartphoneDeal() ? 'checked' : ''}">
- <div class="bgdiv"></div>
- <span>Premium-Smartphone-Deal</span>
- </label>
- </div>
- <a href="#" class="tsd-overlay-trigger nsf-info-icon">
- <svg class="i-xsml">
- <use xlink:href="/simplicity/svgdefs.svg#i-tooltip-invert-lrg"></use>
- </svg>
- <svg class="i-xsml">
- <use xlink:href="/simplicity/svgdefs.svg#i-tooltip-lrg"></use>
- </svg>
- </a>
- `;
- const element = document.createElement('div');
- element.className = 'premium-smartphone-deal';
- element.innerHTML = smartphoneDealTemplate;
- this.topSmartphoneDealElement = element;
- element.addEventListener('click', this.toggleTopSmartphoneDeal.bind(this));
- this.getElement().querySelector('.pricing-box').appendChild(element);
- this.getElement().querySelector('.tsd-overlay-trigger').addEventListener('click', (e) => {
- e.preventDefault();
- const triggerElement = this.getElement().querySelector('.premium-smartphone-deal-link');
- triggerElement.click();
- this.updateTopSmartphoneDealOverlay();
- });
- }
- public async updateTopSmartphoneDealOverlay () {
- const overlay = document.getElementById('tariffDetails');
- if ( overlay.offsetHeight === 0 ) {
- setTimeout(() => {
- this.updateTopSmartphoneDealOverlay();
- }, 100);
- }
- const deviceimg = '<img src="https://www.vodafone.de/' + this.product.getImages().large + '">';
- const devicetitle = this.product.label;
- let topSmartphoneDealActive = false;
- if (this.product.usesTopSmartphoneDeal()) {
- topSmartphoneDealActive = true;
- }
- Configurator.getProduct().stopEventListeners();
- Configurator.getProduct().enableTopSmartphoneDeal();
- let reducedprice = await findOneByComponentSet([Configurator.getTariff(), Configurator.getProduct()]);
- reducedprice = formatEuro( reducedprice.getOnetimePrice() );
- Configurator.getProduct().disableTopSmartphoneDeal();
- let price = await findOneByComponentSet([Configurator.getTariff(), Configurator.getProduct()]);
- price = formatEuro( price.getOnetimePrice() );
- if (topSmartphoneDealActive) {
- Configurator.getProduct().enableTopSmartphoneDeal();
- } else {
- Configurator.getProduct().disableTopSmartphoneDeal();
- }
- Configurator.getProduct().resumeEventListeners();
- jQuery(overlay).find('[data-sub20img]').html(deviceimg);
- jQuery(overlay).find('[data-devicetitle]').html(devicetitle);
- jQuery(overlay).find('[data-reducedprice]').html(reducedprice);
- jQuery(overlay).find('[data-price]').html(price);
- }
- public hideTopSmartphoneDeal () {
- if (this.topSmartphoneDealElement) {
- this.topSmartphoneDealElement.style.display = 'none';
- }
- }
- public showTopSmartphoneDeal () {
- if (this.topSmartphoneDealElement) {
- this.topSmartphoneDealElement.style.display = 'inline-block';
- }
- }
- public topSmartphoneDealChecked () {
- if (!this.topSmartphoneDealElement) {
- return false;
- }
- const checkbox = this.topSmartphoneDealElement.querySelector('input');
- return checkbox.checked;
- }
- public checkTopSmartphoneDeal () {
- const checkbox = this.topSmartphoneDealElement.querySelector('input');
- checkbox.checked = true;
- this.topSmartphoneDealElement.querySelector('label').classList.add('checked');
- }
- public uncheckTopSmartphoneDeal () {
- const checkbox = this.topSmartphoneDealElement.querySelector('input');
- if (checkbox.checked) {
- checkbox.checked = false;
- this.topSmartphoneDealElement.querySelector('label').classList.remove('checked');
- }
- }
- public toggleTopSmartphoneDeal () {
- clearTimeout(this.checkboxTimeout);
- this.checkboxTimeout = setTimeout(() => {
- const checkbox = this.topSmartphoneDealElement.querySelector('input');
- if (checkbox.checked) {
- this.product.enableTopSmartphoneDeal();
- } else {
- this.product.disableTopSmartphoneDeal();
- }
- }, 10);
- }
- public async showContainer () {
- const mainContainer = this.getElement().querySelector('.professional-article');
- const innerContainer = this.getElement().querySelector('.professional-article .inner-container');
- mainContainer.className += ' loaded';
- innerContainer.className += ' loaded';
- }
- public async show () {
- const mainHeadline = this.getElement().querySelector('.main-headline');
- const subHeadline = this.getElement().querySelector('.sub-headline');
- const loadingIndicator = this.getElement().querySelector('[data-loading-indicator]');
- const configurator = this.getElement().querySelector('.configurator');
- if (mainHeadline) {
- mainHeadline.className += ' loaded';
- }
- if (subHeadline) {
- setTimeout(() => {
- subHeadline.className += ' loaded';
- }, 50);
- }
- setTimeout(() => {
- loadingIndicator.className += ' loaded';
- configurator.className += ' loaded';
- }, 100);
- setTimeout(() => {
- loadingIndicator.parentNode.removeChild(loadingIndicator);
- }, 200);
- }
- public showPromoBubble (imageUrl: string): void {
- let promoBubbleElement = this.getElement().querySelector('.promo-bubble');
- if (!promoBubbleElement) {
- promoBubbleElement = document.createElement('div');
- promoBubbleElement.className = 'promo-bubble';
- this.getElement().querySelector('.top-features').appendChild(promoBubbleElement);
- }
- promoBubbleElement.style.display = 'block';
- promoBubbleElement.innerHTML = `<img src="${imageUrl}">`;
- }
- public hidePromoBubble (): void {
- const promoBubbleElement = this.getElement().querySelector('.promo-bubble');
- if (promoBubbleElement) {
- promoBubbleElement.style.display = 'none';
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement