Skip to content

Commit

Permalink
refactor: separate count badge into a separate component
Browse files Browse the repository at this point in the history
  • Loading branch information
stardustmeg committed Jun 11, 2024
1 parent 96d4841 commit 5cf9a86
Show file tree
Hide file tree
Showing 11 changed files with 119 additions and 82 deletions.
3 changes: 1 addition & 2 deletions .validate-branch-namerc.cjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
module.exports = {
pattern:
/^sprint-4|^(feat|fix|hotfix|chore|refactor|revert|docs|style|test|)\(RSS-ECOMM-\d_\d{2}\)\/[a-z]+[a-zA-Z0-9]*$/,
pattern: /^(feat|fix|hotfix|chore|refactor|revert|docs|style|test|)\(RSS-ECOMM-\d_\d{2}\)\/[a-z]+[a-zA-Z0-9]*$/,
errorMsg: 'Please use correct branch name',
};

Expand Down
5 changes: 3 additions & 2 deletions src/app/App/model/AppModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import RouterModel from '@/app/Router/model/RouterModel.ts';
import modal from '@/shared/Modal/model/ModalModel.ts';
import ScrollToTopModel from '@/shared/ScrollToTop/model/ScrollToTopModel.ts';
import { PAGE_ID } from '@/shared/constants/pages.ts';
import { showErrorMessage } from '@/shared/utils/userMessage.ts';
import FooterModel from '@/widgets/Footer/model/FooterModel.ts';
import HeaderModel from '@/widgets/Header/model/HeaderModel.ts';

Expand All @@ -14,8 +15,8 @@ class AppModel {
private appView: AppView = new AppView();

constructor() {
this.initialize().catch(() => {
throw new Error('AppModel initialization error');
this.initialize().catch((error) => {
showErrorMessage(error);
});
}

Expand Down
32 changes: 32 additions & 0 deletions src/entities/CountBadge/model/CountBadgeModel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { Cart } from '@/shared/types/cart.ts';

import getCartModel from '@/shared/API/cart/model/CartModel.ts';

import CountBadgeView from '../view/CountBadgeView.ts';

class CountBadgeModel {
private view = new CountBadgeView();

constructor() {
this.init();
}

private countChangeHandler(cart: Cart): boolean {
this.view.updateBadgeCount(cart.products.reduce((acc, item) => acc + item.quantity, 0));
return true;
}

private init(): void {
this.observeCartChange();
}

private observeCartChange(): boolean {
return getCartModel().observeCartChange(this.countChangeHandler.bind(this));
}

public getHTML(): HTMLDivElement {
return this.view.getHTML();
}
}

export default CountBadgeModel;
49 changes: 49 additions & 0 deletions src/entities/CountBadge/view/CountBadgeView.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import createBaseElement from '@/shared/utils/createBaseElement.ts';

import styles from './countBadgeView.module.scss';

class CountBadgeView {
private countBadge: HTMLSpanElement;

private countBadgeWrap: HTMLDivElement;

constructor() {
this.countBadgeWrap = this.createHTML();
this.countBadge = this.createBadge();
}

private createBadge(): HTMLSpanElement {
this.countBadge = createBaseElement({
cssClasses: [styles.badge],
tag: 'span',
});
this.countBadgeWrap.append(this.countBadge);

return this.countBadge;
}

private createHTML(): HTMLDivElement {
this.countBadgeWrap = createBaseElement({
cssClasses: [styles.badgeWrap],
tag: 'div',
});

return this.countBadgeWrap;
}

public getHTML(): HTMLDivElement {
return this.countBadgeWrap;
}

public updateBadgeCount(count?: number): void {
if (!count) {
this.countBadgeWrap.classList.add(styles.hidden);
} else {
this.countBadgeWrap.classList.remove(styles.hidden);
}

this.countBadge.textContent = count ? count.toString() : '';
}
}

export default CountBadgeView;
23 changes: 23 additions & 0 deletions src/entities/CountBadge/view/countBadgeView.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.badgeWrap {
position: absolute;
right: -30%;
top: -20%;
display: flex;
align-items: center;
justify-content: center;
border: var(--one) solid var(--noble-gray-1000);
border-radius: 100%;
width: calc(var(--tiny-offset) * 2);
height: calc(var(--tiny-offset) * 2);
font: var(--regular-font);
background-color: var(--steam-green-800);
}

.badge {
display: block;
color: var(--noble-gray-200);
}

.hidden {
display: none;
}
4 changes: 2 additions & 2 deletions src/entities/ProductCard/view/ProductCardView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import * as buildPath from '@/shared/utils/buildPathname.ts';
import createBaseElement from '@/shared/utils/createBaseElement.ts';
import createSVGUse from '@/shared/utils/createSVGUse.ts';
import getCurrentLanguage from '@/shared/utils/getCurrentLanguage.ts';
import { discountText } from '@/shared/utils/messageTemplates.ts';

import styles from './productCardView.module.scss';

Expand Down Expand Up @@ -112,8 +113,7 @@ class ProductCardView {

private createDiscountLabel(): HTMLSpanElement {
const currentVariant = this.params.variant.find(({ size }) => size === this.currentSize) ?? this.params.variant[0];
// TBD replace template
const innerContent = `${Math.round((1 - currentVariant.discount / currentVariant.price) * 100)}%`;
const innerContent = discountText(currentVariant);
this.discountLabel = createBaseElement({
cssClasses: [styles.discountLabel],
innerContent,
Expand Down
2 changes: 1 addition & 1 deletion src/features/ProductSorts/view/ProductSortsView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ class ProductSortsView {
if (currentLink && initialField) {
currentLink?.getHTML().classList.toggle(styles.pass, initialDirection === SortDirection.DESC);
// TBD check hight
currentLink?.getHTML().classList.toggle(styles.hight, initialDirection === SortDirection.DESC);
// currentLink?.getHTML().classList.toggle(styles.hight, initialDirection === SortDirection.DESC);
currentLink.getHTML().dataset.field = initialField;
}

Expand Down
4 changes: 4 additions & 0 deletions src/shared/utils/messageTemplates.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { Variant } from '../types/product.ts';

import { LANGUAGE_CHOICE } from '../constants/common.ts';
import { SERVER_MESSAGE } from '../constants/messages.ts';
import { PAGE_DESCRIPTION, USER_INFO_TEXT } from '../constants/pages.ts';
Expand All @@ -14,6 +16,8 @@ export const cartPrice = (price: string): string => `$${price}`;

export const minusCartPrice = (price: string): string => `-$${price}`;

export const discountText = (currentVariant: Variant): string =>
`${Math.round((1 - currentVariant.discount / currentVariant.price) * 100)}%`;
export const productAddedToCartMessage = (name: string): string =>
textTemplate(name, SERVER_MESSAGE[getCurrentLanguage()].SUCCESSFUL_ADD_PRODUCT_TO_CART);

Expand Down
13 changes: 0 additions & 13 deletions src/widgets/Header/model/HeaderModel.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import type { Cart } from '@/shared/types/cart.ts';

import RouterModel from '@/app/Router/model/RouterModel.ts';
import NavigationModel from '@/entities/Navigation/model/NavigationModel.ts';
import getCartModel from '@/shared/API/cart/model/CartModel.ts';
import getCustomerModel, { CustomerModel } from '@/shared/API/customer/model/CustomerModel.ts';
import getStore from '@/shared/Store/Store.ts';
import { setAuthToken, setCurrentLanguage, switchIsUserLoggedIn } from '@/shared/Store/actions.ts';
Expand All @@ -15,11 +12,6 @@ import { showErrorMessage, showSuccessMessage } from '@/shared/utils/userMessage
import HeaderView from '../view/HeaderView.ts';

class HeaderModel {
private cartChangeHandler = (cart: Cart): boolean => {
this.view.updateCartCount(cart.products.reduce((acc, item) => acc + item.quantity, 0));
return true;
};

private navigation: NavigationModel;

private parent: HTMLDivElement;
Expand Down Expand Up @@ -52,7 +44,6 @@ class HeaderModel {
this.observeCurrentUser();
this.setLogoutButtonHandler();
this.setLinksHandler();
this.observeCartChange();
this.setChangeLanguageCheckboxHandler();
}

Expand All @@ -67,10 +58,6 @@ class HeaderModel {
return true;
}

private observeCartChange(): boolean {
return getCartModel().observeCartChange(this.cartChangeHandler);
}

private observeCurrentUser(): void {
observeStore(selectIsUserLoggedIn, () => {
this.checkCurrentUser();
Expand Down
42 changes: 4 additions & 38 deletions src/widgets/Header/view/HeaderView.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { LanguageChoiceType } from '@/shared/constants/common.ts';

import RouterModel from '@/app/Router/model/RouterModel.ts';
import CountBadgeModel from '@/entities/CountBadge/model/CountBadgeModel.ts';
import ButtonModel from '@/shared/Button/model/ButtonModel.ts';
import InputModel from '@/shared/Input/model/InputModel.ts';
import LinkModel from '@/shared/Link/model/LinkModel.ts';
Expand All @@ -23,9 +24,7 @@ import styles from './headerView.module.scss';
class HeaderView {
private burgerButton: ButtonModel;

private cartBadge: HTMLSpanElement;

private cartBadgeWrap: HTMLDivElement;
private countBadge = new CountBadgeModel();

private header: HTMLElement;

Expand All @@ -51,11 +50,7 @@ class HeaderView {
this.logoutButton = this.createLogoutButton();
this.linkLogo = this.createLinkLogo();
this.toCartLink = this.createToCartLink();
this.cartBadgeWrap = this.createBadgeWrap();
this.cartBadge = this.createBadge();

this.toWishlistLink = this.createToWishlistLink();

this.toProfileLink = this.createToProfileLink();
this.switchThemeCheckbox = this.createSwitchThemeCheckbox();
this.switchLanguageCheckbox = this.createSwitchLanguageCheckbox();
Expand All @@ -79,27 +74,6 @@ class HeaderView {
});
}

private createBadge(): HTMLSpanElement {
this.cartBadge = createBaseElement({
cssClasses: [styles.badge],
tag: 'span',
});
this.cartBadgeWrap.append(this.cartBadge);

return this.cartBadge;
}

private createBadgeWrap(): HTMLDivElement {
this.cartBadgeWrap = createBaseElement({
cssClasses: [styles.badgeWrap],
tag: 'div',
});

this.toCartLink.getHTML().append(this.cartBadgeWrap);

return this.cartBadgeWrap;
}

private createBurgerButton(): ButtonModel {
this.burgerButton = new ButtonModel({
classes: [styles.burgerButton],
Expand Down Expand Up @@ -279,6 +253,8 @@ class HeaderView {
.classList.toggle(styles.cartLinkActive, RouterModel.getCurrentPage() === PAGE_ID.CART_PAGE),
);

this.toCartLink.getHTML().append(this.countBadge.getHTML());

return this.toCartLink;
}

Expand Down Expand Up @@ -403,16 +379,6 @@ class HeaderView {
public showNavigationWrapper(): void {
this.navigationWrapper.classList.remove(styles.hidden);
}

public updateCartCount(count?: number): void {
if (!count) {
this.cartBadgeWrap.classList.add(styles.hide);
} else {
this.cartBadgeWrap.classList.remove(styles.hide);
}

this.cartBadge.textContent = count ? count.toString() : '';
}
}

export default HeaderView;
24 changes: 0 additions & 24 deletions src/widgets/Header/view/headerView.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -476,27 +476,3 @@
opacity: 1;
}
}

.badgeWrap {
position: absolute;
right: -30%;
top: -20%;
display: flex;
align-items: center;
justify-content: center;
border: var(--one) solid var(--noble-gray-1000);
border-radius: 100%;
width: calc(var(--tiny-offset) * 2);
height: calc(var(--tiny-offset) * 2);
font: var(--regular-font);
background-color: var(--steam-green-800);
}

.badge {
display: block;
color: var(--noble-gray-200);
}

.hide {
display: none;
}

1 comment on commit 5cf9a86

@stardustmeg
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.