Skip to content

Commit

Permalink
feat(RSS-ECOMM-4_37): display product discount (#327)
Browse files Browse the repository at this point in the history
* feat: display product discount

* fix: submit form addresses

* feat: increase the interactive area of the description button on the product card
  • Loading branch information
Kleostro authored Jun 2, 2024
1 parent 8811d8d commit 44d3edf
Show file tree
Hide file tree
Showing 11 changed files with 85 additions and 33 deletions.
32 changes: 32 additions & 0 deletions src/entities/ProductCard/view/ProductCardView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import observeStore, { selectCurrentLanguage } from '@/shared/Store/observer.ts'
import { MORE_TEXT } from '@/shared/constants/buttons.ts';
import { LANGUAGE_CHOICE } from '@/shared/constants/common.ts';
import { PAGE_ID } from '@/shared/constants/pages.ts';
import { PRODUCT_INFO_TEXT } from '@/shared/constants/product.ts';
import { LOADER_SIZE } from '@/shared/constants/sizes.ts';
import SVG_DETAILS from '@/shared/constants/svg.ts';
import { buildPathName } from '@/shared/utils/buildPathname.ts';
Expand All @@ -25,6 +26,8 @@ class ProductCardView {

private currentSize: null | string;

private discountLabel: HTMLSpanElement;

private goDetailsPageLink: LinkModel;

private moreButton: ButtonModel;
Expand All @@ -51,6 +54,7 @@ class ProductCardView {
this.goDetailsPageLink = this.createGoDetailsPageLink();
this.buttonsWrapper = this.createButtonsWrapper();
this.productImage = this.createProductImage();
this.discountLabel = this.createDiscountLabel();
this.productImageWrapper = this.createProductImageWrapper();
this.productName = this.createProductName();
this.productShortDescription = this.createProductShortDescription();
Expand Down Expand Up @@ -113,6 +117,30 @@ class ProductCardView {
return this.buttonsWrapper;
}

private createDiscountLabel(): HTMLSpanElement {
const currentVariant = this.params.variant.find(({ size }) => size === this.currentSize) ?? this.params.variant[0];
const innerContent = `${Math.round((1 - currentVariant.discount / currentVariant.price) * 100)}%`;
this.discountLabel = createBaseElement({
cssClasses: [styles.discountLabel],
innerContent,
tag: 'span',
});

const discountSpan = createBaseElement({
cssClasses: [styles.discountSpan],
innerContent: PRODUCT_INFO_TEXT[getStore().getState().currentLanguage].DISCOUNT_LABEL,
tag: 'span',
});

observeStore(selectCurrentLanguage, () => {
discountSpan.textContent = PRODUCT_INFO_TEXT[getStore().getState().currentLanguage].DISCOUNT_LABEL;
});

this.discountLabel.append(discountSpan);

return this.discountLabel;
}

private createGoDetailsPageLink(): LinkModel {
const href = `${buildPathName(PAGE_ID.PRODUCT_PAGE, this.params.key, {
size: [this.currentSize ?? this.params.variant[0].size],
Expand Down Expand Up @@ -181,6 +209,10 @@ class ProductCardView {
this.productImage.classList.remove(styles.hidden);
loader.remove();
});

if (this.params.variant.some(({ discount }) => discount)) {
this.productImageWrapper.append(this.discountLabel);
}
return this.productImageWrapper;
}

Expand Down
20 changes: 20 additions & 0 deletions src/entities/ProductCard/view/productCardView.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
width: var(--small-offset);
height: var(--small-offset);
background-color: var(--noble-gray-1000);
transition: outline 0.2s;
backdrop-filter: blur(10px);

svg {
Expand Down Expand Up @@ -148,6 +149,7 @@
flex-grow: 1;
flex-direction: column;
align-items: center;
border-radius: var(--medium-br);
padding: calc(var(--extra-small-offset) / 2) calc(var(--extra-small-offset) / 4);
width: 100%;
background-color: var(--noble-white-200);
Expand Down Expand Up @@ -189,6 +191,7 @@
order: 4;
margin-top: calc(var(--extra-small-offset) * (-0.2));
margin-right: var(--five);
padding: var(--five);
font: var(--regular-font);
letter-spacing: var(--one);
color: var(--steam-green-700);
Expand All @@ -204,3 +207,20 @@
.hidden {
display: none;
}

.discountLabel {
position: absolute;
left: 0;
top: calc(var(--two) * 5);
z-index: 1;
display: flex;
border-radius: 0 var(--five) var(--five) 0;
padding: calc(var(--tiny-offset) / 2);
font: var(--regular-font);
letter-spacing: var(--one);
text-align: center;
text-transform: uppercase;
color: var(--steam-green-400);
background-color: var(--steam-green-800);
gap: var(--two);
}
4 changes: 4 additions & 0 deletions src/entities/UserAddress/view/userAddressView.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,22 @@
}

.billing {
order: 1;
background-color: #d5e4f9;
}

.shipping {
order: 2;
background-color: #e9fffe;
}

.defaultBilling {
order: 3;
background-color: #dfd6ef;
}

.defaultShipping {
order: 4;
background-color: #fee1c9;
}

Expand Down
12 changes: 3 additions & 9 deletions src/features/AddressAdd/model/AddressAddModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,19 +154,13 @@ class AddressAddModel {
}

private setInputFieldHandlers(inputField: InputFieldModel): boolean {
if (inputField?.getView && typeof inputField.getView === 'function') {
const inputHTML = inputField.getView().getInput().getHTML();
inputHTML.addEventListener('input', () => {
this.switchSubmitFormButtonAccess();
});
}
const inputHTML = inputField.getView().getInput().getHTML();
inputHTML.addEventListener('input', () => this.switchSubmitFormButtonAccess());
return true;
}

private setPreventDefaultToForm(): boolean {
this.getHTML().addEventListener('submit', (event) => {
event.preventDefault();
});
this.getHTML().addEventListener('submit', (event) => event.preventDefault());
return true;
}

Expand Down
7 changes: 5 additions & 2 deletions src/features/AddressAdd/view/AddressAddView.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import ButtonModel from '@/shared/Button/model/ButtonModel.ts';
import getStore from '@/shared/Store/Store.ts';
import { BUTTON_TEXT } from '@/shared/constants/buttons.ts';
import { BUTTON_TEXT, BUTTON_TYPE } from '@/shared/constants/buttons.ts';
import createBaseElement from '@/shared/utils/createBaseElement.ts';

import styles from './addressAddView.module.scss';
Expand Down Expand Up @@ -31,12 +31,15 @@ class AddressAddView {
cssClasses: [styles.wrapper],
tag: 'form',
});
this.view.append(this.cancelButton.getHTML(), this.saveChangesButton.getHTML());
this.view.append(this.saveChangesButton.getHTML(), this.cancelButton.getHTML());
return this.view;
}

private createSaveChangesButton(): ButtonModel {
this.saveChangesButton = new ButtonModel({
attrs: {
type: BUTTON_TYPE.SUBMIT,
},
classes: [styles.saveChangesButton],
text: BUTTON_TEXT[getStore().getState().currentLanguage].ADD_ADDRESS,
});
Expand Down
8 changes: 2 additions & 6 deletions src/features/AddressEdit/model/AddressEditModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,12 @@ class AddressEditModel {

private setInputFieldHandlers(inputField: InputFieldModel): boolean {
const inputHTML = inputField.getView().getInput().getHTML();
inputHTML.addEventListener('input', () => {
this.switchSubmitFormButtonAccess();
});
inputHTML.addEventListener('input', () => this.switchSubmitFormButtonAccess());
return true;
}

private setPreventDefaultToForm(): boolean {
this.getHTML().addEventListener('submit', (event) => {
event.preventDefault();
});
this.getHTML().addEventListener('submit', (event) => event.preventDefault());
return true;
}

Expand Down
2 changes: 1 addition & 1 deletion src/features/AddressEdit/view/AddressEditView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class AddressEditView {
tag: 'form',
});

this.view.append(this.cancelButton.getHTML(), this.saveChangesButton.getHTML());
this.view.append(this.saveChangesButton.getHTML(), this.cancelButton.getHTML());
return this.view;
}

Expand Down
2 changes: 1 addition & 1 deletion src/features/PersonalInfoEdit/view/PersonalInfoEditView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class PersonalInfoEditView {
this.view.append(inputFieldElement.getHTML());
}

this.view.append(this.cancelButton.getHTML(), this.saveChangesButton.getHTML());
this.view.append(this.saveChangesButton.getHTML(), this.cancelButton.getHTML());
return this.view;
}

Expand Down
4 changes: 2 additions & 2 deletions src/shared/constants/forms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,12 @@ export const ADDRESS_TEXT = {
CITY: 'City: ',
COUNTRY: 'Country: ',
POSTAL_CODE: 'Postal code: ',
STREET: 'Street: ',
STREET: 'Address: ',
},
ru: {
CITY: 'Город: ',
COUNTRY: 'Страна: ',
POSTAL_CODE: 'Почтовый индекс: ',
STREET: 'Улица: ',
STREET: 'Адрес: ',
},
} as const;
24 changes: 12 additions & 12 deletions src/shared/constants/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const SERVER_MESSAGE = {
PASSWORD_CHANGED: 'Your password has been changed successfully',
PASSWORD_NOT_CHANGED: 'Your password has not been changed. Please, try again',
PERSONAL_INFO_CHANGED: 'Personal information has been changed successfully',
SUCCESSFUL_ADD_COUPON_TO_CART: 'Coupon has been added to your cart successfully',
SUCCESSFUL_ADD_COUPON_TO_CART: 'Coupon has been applied to your cart successfully',
SUCCESSFUL_ADD_PRODUCT_TO_CART: 'Product has been added successfully to your cart',
SUCCESSFUL_ADD_PRODUCT_TO_WISHLIST: 'Product has been added successfully to your wishlist',
SUCCESSFUL_COPY_TO_CLIPBOARD: 'SKU has been copied to clipboard',
Expand All @@ -39,26 +39,26 @@ export const SERVER_MESSAGE = {
USER_EXISTS: 'User with this email already exists, please check your email',
},
ru: {
ADDRESS_ADDED: 'Адрес был успешно добавлен',
ADDRESS_CHANGED: 'Адрес был успешно изменен',
ADDRESS_DELETED: 'Адрес был успешно удален',
ADDRESS_STATUS_CHANGED: 'Статус адреса был успешно изменен',
ADDRESS_ADDED: 'Адрес успешно добавлен',
ADDRESS_CHANGED: 'Адрес успешно изменен',
ADDRESS_DELETED: 'Адрес успешно удален',
ADDRESS_STATUS_CHANGED: 'Статус адреса успешно изменен',
BAD_REQUEST: 'Извините, что-то пошло не так. Попробуйте позже.',
COPY_TO_CLIPBOARD: 'SKU скопирован в буфер обмена',
GREETING: 'Здравствуйте! Добро пожаловать в наш магазин. Приятных покупок!',
INCORRECT_PASSWORD: 'Пожалуйста, введите правильный пароль',
INVALID_COUPON: 'Неверный купон',
INVALID_EMAIL: 'Пользователь с таким адресом не существует. Пожалуйста, сначала зарегистрируйтесь',
LANGUAGE_CHANGED: 'Настройки языка успешно обновлены',
PASSWORD_CHANGED: 'Ваш пароль был успешно изменен',
PASSWORD_CHANGED: 'Ваш пароль успешно изменен',
PASSWORD_NOT_CHANGED: 'Ваш пароль не был изменен. Пожалуйста, попробуйте ещё раз',
PERSONAL_INFO_CHANGED: 'Персональные данные были успешно изменены',
SUCCESSFUL_ADD_COUPON_TO_CART: 'Купон был успешно добавлен в корзину',
SUCCESSFUL_ADD_PRODUCT_TO_CART: 'Товар был успешно добавлен в корзину',
SUCCESSFUL_ADD_PRODUCT_TO_WISHLIST: 'Товар был успешно добавлен в избранное',
PERSONAL_INFO_CHANGED: 'Персональные данные успешно изменены',
SUCCESSFUL_ADD_COUPON_TO_CART: 'Купон успешно применен к корзине',
SUCCESSFUL_ADD_PRODUCT_TO_CART: 'Товар успешно добавлен в корзину',
SUCCESSFUL_ADD_PRODUCT_TO_WISHLIST: 'Товар успешно добавлен в избранное',
SUCCESSFUL_COPY_TO_CLIPBOARD: 'SKU успешно скопирован в буфер обмена',
SUCCESSFUL_DELETE_PRODUCT_FROM_CART: 'Товар был успешно удален из корзины',
SUCCESSFUL_DELETE_PRODUCT_FROM_WISHLIST: 'Товар был успешно удален из избранного',
SUCCESSFUL_DELETE_PRODUCT_FROM_CART: 'Товар успешно удален из корзины',
SUCCESSFUL_DELETE_PRODUCT_FROM_WISHLIST: 'Товар успешно удален из избранного',
SUCCESSFUL_LOGIN: 'Добро пожаловать в наш магазин. Приятных покупок!',
SUCCESSFUL_REGISTRATION: 'Регистрация прошла успешно',
USER_EXISTS: 'Пользователь с таким адресом уже существует, пожалуйста, проверьте свою почту',
Expand Down
3 changes: 3 additions & 0 deletions src/shared/constants/product.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@ export const PRODUCT_INFO_TEXT = {
en: {
CATEGORY: 'Categories: ',
DIFFICULTY: 'Difficulty: ',
DISCOUNT_LABEL: 'OFF',
FULL_DESCRIPTION: 'Full description:',
SHORT_DESCRIPTION: 'Short description:',
SIZE: 'Size:',
},
ru: {
CATEGORY: 'Категории: ',
DIFFICULTY: 'Сложность: ',
DISCOUNT_LABEL: 'Скидка',
FULL_DESCRIPTION: 'Полное описание:',
SHORT_DESCRIPTION: 'Краткое описание:',
SIZE: 'Размер:',
Expand All @@ -47,6 +49,7 @@ export const PRODUCT_INFO_TEXT = {
export const PRODUCT_INFO_TEXT_KEYS = {
CATEGORY: 'CATEGORY',
DIFFICULTY: 'DIFFICULTY',
DISCOUNT_LABEL: 'DISCOUNT_LABEL',
FULL_DESCRIPTION: 'FULL_DESCRIPTION',
SHORT_DESCRIPTION: 'SHORT_DESCRIPTION',
SIZE: 'SIZE',
Expand Down

0 comments on commit 44d3edf

Please sign in to comment.