Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions src/app/services/apply-promocode-to-cart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { ClientResponse, Cart } from '@commercetools/platform-sdk';
import ApiRoot from './api-root';

export default function applyPromocodeToCart(
cartId: string,
cartVersion: number,
code: string,
successCallback: (cartData: Cart) => void,
errorCallback: (message: string) => void
) {
ApiRoot.root
.carts()
.withId({ ID: cartId })
.post({
body: {
version: cartVersion,
actions: [
{
action: 'addDiscountCode',
code,
},
],
},
})
.execute()
.then((response: ClientResponse<Cart>) => {
const cartData: Cart = response.body;
successCallback(cartData);
})
.catch((error: ClientResponse<{ message: string }>) => {
errorCallback(error.body.message);
});
}
23 changes: 23 additions & 0 deletions src/app/services/get-active-promocodes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { DiscountCode } from '@commercetools/platform-sdk';
import apiRoot from './api-root';

export default function getActivePromocodes(
sucessCallback: (discountCodes: Array<DiscountCode>) => void,
errorCallback: (message: string) => void
) {
apiRoot.root
.discountCodes()
.get({
queryArgs: {
where: ['isActive=true'],
},
})
.execute()
.then((response) => {
console.log(response);
sucessCallback(response.body.results);
})
.catch((error) => {
errorCallback(error.message);
});
}
43 changes: 43 additions & 0 deletions src/app/services/remove-promocode-from-cart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {
ClientResponse,
Cart,
DiscountCodeReference,
} from '@commercetools/platform-sdk';
import ApiRoot from './api-root';

export default function removePromocodeFromCart(
cartId: string,
cartVersion: number,
successCallback: (cartData: Cart) => void,
errorCallback: (message: string) => void,
code?: DiscountCodeReference
) {
let discountCode: DiscountCodeReference;
if (!code) {
discountCode = { id: '', typeId: 'discount-code' };
} else {
discountCode = code;
}
ApiRoot.root
.carts()
.withId({ ID: cartId })
.post({
body: {
version: cartVersion,
actions: [
{
action: 'removeDiscountCode',
discountCode,
},
],
},
})
.execute()
.then((response: ClientResponse<Cart>) => {
const cartData: Cart = response.body;
successCallback(cartData);
})
.catch((error: ClientResponse<{ message: string }>) => {
errorCallback(error.body.message);
});
}
4 changes: 2 additions & 2 deletions src/app/views/about/about.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@

.logo-container {
display: flex;
justify-content: center;
max-height: 70px;
margin: 2% 2% 70px;
justify-content: center;
}

.logo-container a {
Expand All @@ -42,9 +42,9 @@
}

.standard-size {
position: relative;
display: block;
width: 100%;
position: relative;
}

.standard-size img {
Expand Down
16 changes: 16 additions & 0 deletions src/app/views/basket/basket-summary.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.basket-summary {
display: flex;
flex-direction: column;
gap: 20px;
align-items: left;
padding: 10px;

&_price {
font-size: 18px;
}

&_old-price {
color: #90a4ae;
text-decoration: line-through;
}
}
151 changes: 145 additions & 6 deletions src/app/views/basket/basket-summary.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,167 @@
import { IAttributes } from '@components/base-component';
import { ICartData } from '@models/cart';
import { BaseComponent, IAttributes } from '@components/base-component';
import {
ButtonComponent,
IButtonAttributes,
} from '@components/button-component';
import { InputFieldComponent } from '@components/input-field-component';
import { ICartData, ILineItem } from '@models/cart';
import { IFormInputField, createInputField } from '@utils/create-input-field';
import View from '@views/view';
import applyPromocodeToCart from '@services/apply-promocode-to-cart';
import { showErrorMessage } from '@utils/toast-messages';
import { createCartData } from '@services/cart-data';
import { Cart } from '@commercetools/platform-sdk';
import styles from './basket-summary.module.scss';

interface ISummary {
totalPrice: number;
discountedPrice: number;
}

export default class BasketSummaryView extends View {
protected _card = new View({});

private cartData?: ICartData | null = null;

private _totalPriceBlock = new BaseComponent({});

private _discountedPriceBlock = new BaseComponent({});

private _promocodeField = new InputFieldComponent({}, {}, {});

private _applyPromocodeButton = new ButtonComponent({});

private _summary: ISummary = {
totalPrice: 0,
discountedPrice: 0,
};

constructor(cartData: ICartData) {
const attrs: IAttributes = {
classList: ['col', 's12', 'm12', 'l4'],
};
super(attrs);
this.addCard();
this.cartData = cartData;
this.addCard();
}

addCard() {
const attrs: IAttributes = {
classList: ['card'],
content: 'Im summary and controls block',
classList: ['card', styles.basketSummary],
};
this._card = new View(attrs);
this.appendChild(this._card);
this._card.htmlElement.style.setProperty('min-height', '400px');
this.addPromocodeField();
this.addTotalPriceBlock();
this.addDiscountedPrice();
this.updateData();
}

addTotalPriceBlock() {
if (this.cartData) {
const attrs: IAttributes = {
classList: styles.basketSummaryPrice,
};
this._totalPriceBlock = new BaseComponent(attrs);
this._card.appendChild(this._totalPriceBlock);
}
}

addPromocodeField() {
const attrs: IFormInputField = {
id: 'promocode',
type: 'text',
label: 'Promocode',
required: false,
placeholder: 'Enter here',
customValidators: [],
};

this._promocodeField = createInputField(attrs);
this._promocodeField.removeClass('s6');
this._card.appendChild(this._promocodeField);

const applyButtonAttrs: IButtonAttributes = {
classList: 'waves-effect waves-light btn-small red lighten-2',
content: 'Apply',
onClick: this.applyPromocode.bind(this),
};

this._applyPromocodeButton = new ButtonComponent(applyButtonAttrs);
this._card.appendChild(this._applyPromocodeButton);
}

addDiscountedPrice() {
if (this.cartData) {
const attrs: IAttributes = {
classList: styles.basketSummaryPrice,
};
this._discountedPriceBlock = new BaseComponent(attrs);
this._card.appendChild(this._discountedPriceBlock);
}
}

updateDiscountedPrice() {
if (this.cartData) {
if (this._summary.discountedPrice !== this._summary.totalPrice) {
this._discountedPriceBlock.textContent = `Discounted price: $${this._summary.discountedPrice}`;
this._totalPriceBlock.addClass(styles.basketSummaryOldPrice);
} else {
this._discountedPriceBlock.textContent = '';
}
}
}

updateTotalPrice() {
if (this.cartData) {
this._totalPriceBlock.textContent = `Total price: $${this._summary.totalPrice}`;
}
}

applyPromocode() {
const promocode = this._promocodeField.getValue();
if (promocode.length > 0 && this.cartData) {
applyPromocodeToCart(
this.cartData.id,
this.cartData.version,
promocode,
this.updateData.bind(this),
() => {
showErrorMessage('Wrong promocode');
}
);
}
}

updateData(newCart?: Cart) {
const getTotalPrice = (lineItems: Array<ILineItem>) => {
const totalPrice =
lineItems.reduce(
(sum, currentItem) => sum + currentItem.price.value.centAmount,
0
) / 100;
return totalPrice;
};
if (newCart) {
this.cartData = createCartData(newCart);
}
if (this.cartData) {
const { lineItems } = this.cartData;
const totalPrice = getTotalPrice(lineItems);
const discountedPrice = this.cartData.totalPrice.centAmount / 100;

if (totalPrice !== this._summary.totalPrice) {
this._summary.totalPrice = totalPrice;
this.updateTotalPrice();
}

if (
discountedPrice !== this._summary.discountedPrice &&
discountedPrice
) {
this._summary.discountedPrice = discountedPrice;
this.updateDiscountedPrice();
}
}
}
}
27 changes: 12 additions & 15 deletions src/app/views/main/discount-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { IInputAttributes, InputComponent } from '@components/input-component';
import { showErrorMessage, showSucessMessage } from '@utils/toast-messages';

export default class DiscountCardComponent extends CardComponent {
private _inputComponent = new InputComponent({});

constructor(data: Partial<ICardAttributes> = {}) {
super(data);
const { inputValue = '' } = data;
Expand All @@ -23,25 +25,20 @@ export default class DiscountCardComponent extends CardComponent {
id: 'input',
};

const input = new InputComponent(inputAttr);
discountContainer.appendChild(input);
this._inputComponent = new InputComponent(inputAttr);
discountContainer.appendChild(this._inputComponent);

const buttonAttr: IButtonAttributes = {
content: 'Copy',
onClick: () => {
const inputElement = document.getElementById(
'input'
) as HTMLInputElement;
if (inputElement) {
navigator.clipboard
.writeText(inputElement.value)
.then(() => {
showSucessMessage('Text copied to clipboard');
})
.catch(() => {
showErrorMessage('Failed to copy text');
});
}
navigator.clipboard
.writeText(this._inputComponent.value)
.then(() => {
showSucessMessage('Text copied to clipboard');
})
.catch(() => {
showErrorMessage('Failed to copy text');
});
},
classList: [
'edit-profile-button',
Expand Down
Loading