diff --git a/src/app/App/model/AppModel.ts b/src/app/App/model/AppModel.ts index aed626f4..24a0814e 100644 --- a/src/app/App/model/AppModel.ts +++ b/src/app/App/model/AppModel.ts @@ -68,6 +68,12 @@ class AppModel { ); return new RegistrationPageModel(this.appView.getHTML()); }, + [PAGE_ID.USER_ADDRESSES_PAGE]: async (): Promise => { + const { default: UserAddressesPageModel } = await import( + '@/pages/UserAddressesPage/model/UserAddressesPageModel.ts' + ); + return new UserAddressesPageModel(this.appView.getHTML()); + }, [PAGE_ID.USER_PROFILE_PAGE]: async (): Promise => { const { default: UserProfilePageModel } = await import('@/pages/UserProfilePage/model/UserProfilePageModel.ts'); return new UserProfilePageModel(this.appView.getHTML()); diff --git a/src/entities/UserAddress/model/UserAddressModel.ts b/src/entities/UserAddress/model/UserAddressModel.ts index e9ac9cd7..9bd80bb7 100644 --- a/src/entities/UserAddress/model/UserAddressModel.ts +++ b/src/entities/UserAddress/model/UserAddressModel.ts @@ -19,21 +19,13 @@ import { showErrorMessage, showSuccessMessage } from '@/shared/utils/userMessage import UserAddressView from '../view/UserAddressView.ts'; class UserAddressModel { - private callback: (isDisabled: boolean) => void; - private currentAddress: Address; private labels: Map; private view: UserAddressView; - constructor( - address: Address, - activeTypes: AddressTypeType[], - callback: (isDisabled: boolean) => void, - inactiveTypes?: AddressTypeType[], - ) { - this.callback = callback; + constructor(address: Address, activeTypes: AddressTypeType[], inactiveTypes?: AddressTypeType[]) { this.currentAddress = address; this.view = new UserAddressView(address, activeTypes, inactiveTypes); this.labels = this.view.getLabels(); @@ -87,7 +79,6 @@ class UserAddressModel { private async labelClickHandler(activeType: AddressTypeType, inactive?: boolean): Promise { const loader = new LoaderModel(LOADER_SIZE.MEDIUM); loader.setAbsolutePosition(); - this.callback(true); this.view.toggleState(true); this.getHTML().append(loader.getHTML()); try { diff --git a/src/features/WishlistButton/view/WishlistButtonView.ts b/src/features/WishlistButton/view/WishlistButtonView.ts index 084151e7..d711321c 100644 --- a/src/features/WishlistButton/view/WishlistButtonView.ts +++ b/src/features/WishlistButton/view/WishlistButtonView.ts @@ -17,7 +17,7 @@ class WishlistButtonView { }); const svg = document.createElementNS(SVG_DETAILS.SVG_URL, 'svg'); - svg.append(createSVGUse(SVG_DETAILS.FILL_HEART)); + svg.append(createSVGUse(SVG_DETAILS.HEART)); this.switchToWishListButton.getHTML().append(svg); return this.switchToWishListButton; diff --git a/src/pages/UserAddressesPage/model/UserAddressesPageModel.ts b/src/pages/UserAddressesPage/model/UserAddressesPageModel.ts new file mode 100644 index 00000000..4e0be40d --- /dev/null +++ b/src/pages/UserAddressesPage/model/UserAddressesPageModel.ts @@ -0,0 +1,54 @@ +import type { Page } from '@/shared/types/page.ts'; + +import RouterModel from '@/app/Router/model/RouterModel.ts'; +import getCustomerModel from '@/shared/API/customer/model/CustomerModel.ts'; +import getStore from '@/shared/Store/Store.ts'; +import { setCurrentPage } from '@/shared/Store/actions.ts'; +import { SERVER_MESSAGE_KEYS } from '@/shared/constants/messages.ts'; +import { PAGE_ID } from '@/shared/constants/pages.ts'; +import createBaseElement from '@/shared/utils/createBaseElement.ts'; +import { showErrorMessage } from '@/shared/utils/userMessage.ts'; +import UserAddressesModel from '@/widgets/UserAddresses/model/UserAddressesModel.ts'; + +import UserAddressesPageView from '../view/UserAddressesPageView.ts'; + +class UserAddressesPageModel implements Page { + private addresses: UserAddressesModel | null = null; + + private view: UserAddressesPageView | null = null; + + constructor(parent: HTMLDivElement) { + const { isUserLoggedIn } = getStore().getState(); + if (!isUserLoggedIn) { + RouterModel.getInstance().navigateTo(PAGE_ID.LOGIN_PAGE); + showErrorMessage(SERVER_MESSAGE_KEYS.NEED_LOGIN); + } else { + this.view = new UserAddressesPageView(parent); + this.init().catch(showErrorMessage); + } + } + + private async init(): Promise { + try { + const user = await getCustomerModel().getCurrentUser(); + if (user) { + this.addresses = new UserAddressesModel(user); + this.view?.getHTML().append(this.addresses.getHTML()); + getStore().dispatch(setCurrentPage(PAGE_ID.USER_ADDRESSES_PAGE)); + } + } catch (error) { + showErrorMessage(SERVER_MESSAGE_KEYS.NEED_LOGIN); + } + } + + public getHTML(): HTMLDivElement { + if (this.view) { + return this.view.getHTML(); + } + return createBaseElement({ + tag: 'div', + }); + } +} + +export default UserAddressesPageModel; diff --git a/src/pages/UserAddressesPage/view/UserAddressesPageView.ts b/src/pages/UserAddressesPage/view/UserAddressesPageView.ts new file mode 100644 index 00000000..dd5f03b5 --- /dev/null +++ b/src/pages/UserAddressesPage/view/UserAddressesPageView.ts @@ -0,0 +1,33 @@ +import clearOutElement from '@/shared/utils/clearOutElement.ts'; +import createBaseElement from '@/shared/utils/createBaseElement.ts'; + +import styles from './userAddressesPageView.module.scss'; + +class UserAddressesPageView { + private page: HTMLDivElement; + + private parent: HTMLDivElement; + + constructor(parent: HTMLDivElement) { + this.parent = parent; + clearOutElement(this.parent); + this.page = this.createHTML(); + window.scrollTo(0, 0); + } + + private createHTML(): HTMLDivElement { + this.page = createBaseElement({ + cssClasses: [styles.userAddressesPage], + tag: 'div', + }); + + this.parent.append(this.page); + + return this.page; + } + + public getHTML(): HTMLDivElement { + return this.page; + } +} +export default UserAddressesPageView; diff --git a/src/pages/UserAddressesPage/view/userAddressesPageView.module.scss b/src/pages/UserAddressesPage/view/userAddressesPageView.module.scss new file mode 100644 index 00000000..0da5eafb --- /dev/null +++ b/src/pages/UserAddressesPage/view/userAddressesPageView.module.scss @@ -0,0 +1,19 @@ +@import 'src/app/styles/mixins'; + +.userAddressesPage { + position: relative; + display: block; + padding: 0 var(--small-offset); + animation: show 0.2s ease-out forwards; +} + +@keyframes show { + 0% { + opacity: 0; + } + + 100% { + display: block; + opacity: 1; + } +} diff --git a/src/pages/UserProfilePage/model/UserProfilePageModel.ts b/src/pages/UserProfilePage/model/UserProfilePageModel.ts index 3e5d68b6..8f6ab525 100644 --- a/src/pages/UserProfilePage/model/UserProfilePageModel.ts +++ b/src/pages/UserProfilePage/model/UserProfilePageModel.ts @@ -3,19 +3,17 @@ import type { Page } from '@/shared/types/page.ts'; import RouterModel from '@/app/Router/model/RouterModel.ts'; import getCustomerModel from '@/shared/API/customer/model/CustomerModel.ts'; import getStore from '@/shared/Store/Store.ts'; -import { setAuthToken, setCurrentPage, switchIsUserLoggedIn } from '@/shared/Store/actions.ts'; +import { setCurrentPage } from '@/shared/Store/actions.ts'; import { SERVER_MESSAGE_KEYS } from '@/shared/constants/messages.ts'; import { PAGE_ID } from '@/shared/constants/pages.ts'; import createBaseElement from '@/shared/utils/createBaseElement.ts'; import { showErrorMessage } from '@/shared/utils/userMessage.ts'; -import UserAddressesModel from '@/widgets/UserAddresses/model/UserAddressesModel.ts'; +// import UserAddressesModel from '@/widgets/UserAddresses/model/UserAddressesModel.ts'; import UserInfoModel from '@/widgets/UserInfo/model/UserInfoModel.ts'; import UserProfilePageView from '../view/UserProfilePageView.ts'; class UserProfilePageModel implements Page { - private addresses: UserAddressesModel | null = null; - private userInfo: UserInfoModel | null = null; private view: UserProfilePageView | null = null; @@ -31,22 +29,12 @@ class UserProfilePageModel implements Page { } } - private addressesLinkHandler(): void { - this.userInfo?.hide(); - this.addresses?.show(); - } - private async init(): Promise { - this.setAddressesLinkHandler(); - this.setPersonalInfoLinkHandler(); try { const user = await getCustomerModel().getCurrentUser(); - if (user) { this.userInfo = new UserInfoModel(user); - this.addresses = new UserAddressesModel(user); - this.view?.getUserProfileWrapper().append(this.userInfo.getHTML(), this.addresses.getHTML()); - this.setAccountLogoutButtonHandler(); + this.view?.getUserProfileWrapper().append(this.userInfo.getHTML()); getStore().dispatch(setCurrentPage(PAGE_ID.USER_PROFILE_PAGE)); } } catch (error) { @@ -54,34 +42,6 @@ class UserProfilePageModel implements Page { } } - private logoutHandler(): void { - localStorage.clear(); - getStore().dispatch(setAuthToken(null)); - getStore().dispatch(switchIsUserLoggedIn(false)); - getCustomerModel().logout().catch(showErrorMessage); - RouterModel.getInstance().navigateTo(PAGE_ID.LOGIN_PAGE); - } - - private personalInfoLinkHandler(): void { - this.addresses?.hide(); - this.userInfo?.show(); - } - - private setAccountLogoutButtonHandler(): void { - const logoutButton = this.view?.getAccountLogoutButton(); - logoutButton?.getHTML().addEventListener('click', () => this.logoutHandler()); - } - - private setAddressesLinkHandler(): void { - const addressesLink = this.view?.getAddressesLink(); - addressesLink?.getHTML().addEventListener('click', () => this.addressesLinkHandler()); - } - - private setPersonalInfoLinkHandler(): void { - const personalInfoLink = this.view?.getPersonalInfoLink(); - personalInfoLink?.getHTML().addEventListener('click', () => this.personalInfoLinkHandler()); - } - public getHTML(): HTMLDivElement { if (this.view) { return this.view.getHTML(); diff --git a/src/pages/UserProfilePage/view/UserProfilePageView.ts b/src/pages/UserProfilePage/view/UserProfilePageView.ts index 7ba64366..12567eae 100644 --- a/src/pages/UserProfilePage/view/UserProfilePageView.ts +++ b/src/pages/UserProfilePage/view/UserProfilePageView.ts @@ -1,87 +1,23 @@ -import ButtonModel from '@/shared/Button/model/ButtonModel.ts'; -import LinkModel from '@/shared/Link/model/LinkModel.ts'; -import { BUTTON_TEXT, BUTTON_TEXT_KEYS } from '@/shared/constants/buttons.ts'; -import { USER_PROFILE_MENU_LINK } from '@/shared/constants/links.ts'; -import { USER_INFO_MENU_LINK, USER_INFO_MENU_LINK_KEYS } from '@/shared/constants/pages.ts'; import clearOutElement from '@/shared/utils/clearOutElement.ts'; import createBaseElement from '@/shared/utils/createBaseElement.ts'; -import getCurrentLanguage from '@/shared/utils/getCurrentLanguage.ts'; -import observeCurrentLanguage from '@/shared/utils/observeCurrentLanguage.ts'; import styles from './userProfilePageView.module.scss'; class UserProfilePageView { - private accountLogoutButton: ButtonModel; - - private accountMenu: HTMLUListElement; - - private addressesLink: LinkModel; - - private links: LinkModel[] = []; - - private ordersLink: LinkModel; - private page: HTMLDivElement; private parent: HTMLDivElement; - private personalInfoLink: LinkModel; - - private supportLink: LinkModel; - private userProfileWrapper: HTMLDivElement; constructor(parent: HTMLDivElement) { this.parent = parent; clearOutElement(this.parent); - - this.accountLogoutButton = this.createLogoutButton(); - this.personalInfoLink = this.createPersonalInfoLink(); - this.addressesLink = this.createAddressesLink(); - this.ordersLink = this.createOrdersLink(); - this.supportLink = this.createSupportLink(); - this.accountMenu = this.createAccountMenu(); - - this.setLinksHandlers(); this.userProfileWrapper = this.createUserProfileWrapper(); this.page = this.createHTML(); window.scrollTo(0, 0); } - private createAccountMenu(): HTMLUListElement { - this.accountMenu = createBaseElement({ - cssClasses: [styles.accountMenu], - tag: 'ul', - }); - - this.links.forEach((link) => { - const li = createBaseElement({ - cssClasses: [styles.accountMenuItem], - tag: 'li', - }); - li.append(link.getHTML()); - - this.accountMenu.append(li); - }); - this.accountMenu.append(this.accountLogoutButton.getHTML()); - return this.accountMenu; - } - - private createAddressesLink(): LinkModel { - this.addressesLink = new LinkModel({ - attrs: { - href: USER_PROFILE_MENU_LINK.ADDRESSES, - }, - classes: [styles.link], - text: USER_INFO_MENU_LINK[getCurrentLanguage()].ADDRESSES, - }); - this.links.push(this.addressesLink); - - observeCurrentLanguage(this.addressesLink.getHTML(), USER_INFO_MENU_LINK, USER_INFO_MENU_LINK_KEYS.ADDRESSES); - - return this.addressesLink; - } - private createHTML(): HTMLDivElement { this.page = createBaseElement({ cssClasses: [styles.userProfilePage], @@ -94,126 +30,19 @@ class UserProfilePageView { return this.page; } - private createLogoutButton(): ButtonModel { - this.accountLogoutButton = new ButtonModel({ - classes: [styles.logoutButton], - text: BUTTON_TEXT[getCurrentLanguage()].LOG_OUT, - }); - - observeCurrentLanguage(this.accountLogoutButton.getHTML(), BUTTON_TEXT, BUTTON_TEXT_KEYS.LOG_OUT); - - return this.accountLogoutButton; - } - - private createOrdersLink(): LinkModel { - this.ordersLink = new LinkModel({ - attrs: { - href: USER_PROFILE_MENU_LINK.ORDERS, - }, - classes: [styles.link], - text: USER_INFO_MENU_LINK[getCurrentLanguage()].ORDERS, - }); - this.links.push(this.ordersLink); - - observeCurrentLanguage(this.ordersLink.getHTML(), USER_INFO_MENU_LINK, USER_INFO_MENU_LINK_KEYS.ORDERS); - - return this.ordersLink; - } - - private createPersonalInfoLink(): LinkModel { - this.personalInfoLink = new LinkModel({ - attrs: { - href: USER_PROFILE_MENU_LINK.PERSONAL_INFO, - }, - classes: [styles.link], - text: USER_INFO_MENU_LINK[getCurrentLanguage()].PERSONAL_INFO, - }); - this.links.push(this.personalInfoLink); - - observeCurrentLanguage( - this.personalInfoLink.getHTML(), - USER_INFO_MENU_LINK, - USER_INFO_MENU_LINK_KEYS.PERSONAL_INFO, - ); - - this.personalInfoLink.getHTML().classList.add(styles.active); - this.personalInfoLink.setDisabled(); - return this.personalInfoLink; - } - - private createSupportLink(): LinkModel { - this.supportLink = new LinkModel({ - attrs: { - href: USER_PROFILE_MENU_LINK.SUPPORT, - }, - classes: [styles.link], - text: USER_INFO_MENU_LINK[getCurrentLanguage()].SUPPORT, - }); - this.links.push(this.supportLink); - - observeCurrentLanguage(this.supportLink.getHTML(), USER_INFO_MENU_LINK, USER_INFO_MENU_LINK_KEYS.SUPPORT); - - return this.supportLink; - } - private createUserProfileWrapper(): HTMLDivElement { this.userProfileWrapper = createBaseElement({ cssClasses: [styles.userProfileWrapper], tag: 'div', }); - this.userProfileWrapper.append(this.accountMenu); return this.userProfileWrapper; } - private setLinksHandlers(): boolean { - this.links.forEach((link) => { - link.getHTML().addEventListener('click', (event) => { - event.preventDefault(); - // TBD replace route with route - const route = link.getHTML().attributes.getNamedItem('href')?.value; - if (route) { - this.switchActiveLink(route); - } - }); - }); - return true; - } - - private switchActiveLink(route: string): void { - this.links.forEach((link) => { - link.getHTML().classList.remove(styles.active); - link.setEnabled(); - }); - - const currentLink = this.links.find((link) => link.getHTML().attributes.getNamedItem('href')?.value === route); - - if (currentLink) { - currentLink.getHTML().classList.add(styles.active); - currentLink.setDisabled(); - } - } - - public getAccountLogoutButton(): ButtonModel { - return this.accountLogoutButton; - } - - public getAddressesLink(): LinkModel { - return this.addressesLink; - } - public getHTML(): HTMLDivElement { return this.page; } - public getLinks(): LinkModel[] { - return this.links; - } - - public getPersonalInfoLink(): LinkModel { - return this.personalInfoLink; - } - public getUserProfileWrapper(): HTMLDivElement { return this.userProfileWrapper; } diff --git a/src/pages/UserProfilePage/view/userProfilePageView.module.scss b/src/pages/UserProfilePage/view/userProfilePageView.module.scss index 906ac94b..bd327694 100644 --- a/src/pages/UserProfilePage/view/userProfilePageView.module.scss +++ b/src/pages/UserProfilePage/view/userProfilePageView.module.scss @@ -16,71 +16,6 @@ } } -.addressesWrapper { - position: relative; - display: grid; - align-items: center; - grid-template-columns: repeat(2, 1fr); - grid-template-rows: repeat(6, auto); - margin: 0 var(--small-offset); - padding: var(--small-offset); - min-width: 40%; - max-width: fit-content; - box-shadow: var(--mellow-shadow-100); - font: var(--extra-regular-font); - letter-spacing: var(--one); - color: var(--noble-gray-900); - background-color: var(--noble-gray-tr-800); - gap: var(--small-offset); -} - -.address { - grid-column: 2 span; - max-width: 100%; - word-break: break-all; -} - -.accountMenu { - display: flex; - flex-flow: column wrap; - justify-content: center; - padding: var(--small-offset); - width: 25%; - height: fit-content; - background-color: var(--white); - - @media (max-width: 768px) { - margin-bottom: var(--small-offset); - width: 100%; - } -} - -.accountMenuItem { - display: flex; - align-items: center; - justify-content: center; - width: 100%; - height: fit-content; -} - -.logoutButton { - @include green-btn; - - margin: var(--small-offset) auto; - padding: calc(var(--small-offset) / 3) var(--small-offset); -} - -.link { - @include link; - - align-self: center; - height: calc(var(--large-offset) * 0.8); -} - -.active { - @include active; -} - @keyframes show { 0% { opacity: 0; diff --git a/src/shared/constants/buttons.ts b/src/shared/constants/buttons.ts index f17587d8..6c24245e 100644 --- a/src/shared/constants/buttons.ts +++ b/src/shared/constants/buttons.ts @@ -18,6 +18,7 @@ export const BUTTON_TEXT = { REGISTRATION: 'Register', RESET: 'Reset', SAVE_CHANGES: 'Save changes', + TO_ADDRESSES: 'Addresses', }, ru: { ADD_ADDRESS: 'Добавить адрес', @@ -32,6 +33,7 @@ export const BUTTON_TEXT = { REGISTRATION: 'Регистрация', RESET: 'Сбросить', SAVE_CHANGES: 'Сохранить', + TO_ADDRESSES: 'Адреса', }, } as const; @@ -48,6 +50,7 @@ export const BUTTON_TEXT_KEYS = { REGISTRATION: 'REGISTRATION', RESET: 'RESET', SAVE_CHANGES: 'SAVE_CHANGES', + TO_ADDRESSES: 'TO_ADDRESSES', } as const; export type ButtonTextKeysType = (typeof BUTTON_TEXT_KEYS)[keyof typeof BUTTON_TEXT_KEYS]; diff --git a/src/shared/constants/pages.ts b/src/shared/constants/pages.ts index 7299ecfc..95a7a083 100644 --- a/src/shared/constants/pages.ts +++ b/src/shared/constants/pages.ts @@ -106,6 +106,7 @@ export const PAGE_ID = { NOT_FOUND_PAGE: '404', PRODUCT_PAGE: 'product', REGISTRATION_PAGE: 'register', + USER_ADDRESSES_PAGE: 'addresses', USER_PROFILE_PAGE: 'profile', WISHLIST_PAGE: 'wishlist', } as const; diff --git a/src/shared/constants/svg.ts b/src/shared/constants/svg.ts index 34229b39..fa15df34 100644 --- a/src/shared/constants/svg.ts +++ b/src/shared/constants/svg.ts @@ -1,7 +1,6 @@ const SVG_DETAILS = { ARROW_UP: 'arrowUp', BILL: 'bill', - BIN: 'bin', CART: 'cart', CLOSE: 'close', CLOSE_EYE: 'closeEye', @@ -10,9 +9,9 @@ const SVG_DETAILS = { DELETE: 'delete', DELIVERY: 'delivery', EDIT: 'edit', - FILL_HEART: 'heartFill', GO_DETAILS: 'arrow', - HEART_OUTLINE: 'heartOutline', + HEART: 'heart', + HOUSE: 'house', KEY: 'key', LEAVES: 'leaves', LIGHT: 'light', @@ -20,13 +19,15 @@ const SVG_DETAILS = { NOT_FOUND: 'notFound', OPEN_EYE: 'openEye', PROFILE: 'userCircle', + Plant: 'plant', SVG_URL: 'http://www.w3.org/2000/svg', + SWITCH_LANGUAGE: { en: 'en', ru: 'ru', }, - TRUCK: 'truck', - WALLET: 'wallet', + Search: 'search', + Settings: 'settings', } as const; export default SVG_DETAILS; diff --git a/src/shared/img/svg/bin.svg b/src/shared/img/svg/bin.svg deleted file mode 100644 index 709bfa15..00000000 --- a/src/shared/img/svg/bin.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/shared/img/svg/drop.svg b/src/shared/img/svg/drop.svg deleted file mode 100644 index 42d5a616..00000000 --- a/src/shared/img/svg/drop.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/src/shared/img/svg/flower.svg b/src/shared/img/svg/flower.svg deleted file mode 100644 index 38f5c53a..00000000 --- a/src/shared/img/svg/flower.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/shared/img/svg/github.svg b/src/shared/img/svg/github.svg deleted file mode 100644 index 471c8d9d..00000000 --- a/src/shared/img/svg/github.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/src/shared/img/svg/heartFill.svg b/src/shared/img/svg/heart.svg similarity index 100% rename from src/shared/img/svg/heartFill.svg rename to src/shared/img/svg/heart.svg diff --git a/src/shared/img/svg/heartOutline.svg b/src/shared/img/svg/heartOutline.svg deleted file mode 100644 index dff34254..00000000 --- a/src/shared/img/svg/heartOutline.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/shared/img/svg/house.svg b/src/shared/img/svg/house.svg index 05834259..3e6d7403 100644 --- a/src/shared/img/svg/house.svg +++ b/src/shared/img/svg/house.svg @@ -1,3 +1,80 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/shared/img/svg/truck.svg b/src/shared/img/svg/truck.svg deleted file mode 100644 index 4872b693..00000000 --- a/src/shared/img/svg/truck.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/src/shared/img/svg/wallet.svg b/src/shared/img/svg/wallet.svg deleted file mode 100644 index 23a30d27..00000000 --- a/src/shared/img/svg/wallet.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/widgets/Header/model/HeaderModel.ts b/src/widgets/Header/model/HeaderModel.ts index cfb65815..86594e7a 100644 --- a/src/widgets/Header/model/HeaderModel.ts +++ b/src/widgets/Header/model/HeaderModel.ts @@ -44,10 +44,12 @@ class HeaderModel { const logoutButton = this.view.getLogoutButton(); if (isUserLoggedIn) { this.view.getToProfileLink().setEnabled(); + this.view.getToAddressesLink().setEnabled(); logoutButton.setEnabled(); } else { logoutButton.setDisabled(); this.view.getToProfileLink().setDisabled(); + this.view.getToAddressesLink().setDisabled(); } } diff --git a/src/widgets/Header/view/HeaderView.ts b/src/widgets/Header/view/HeaderView.ts index d137cf74..7a611fe7 100644 --- a/src/widgets/Header/view/HeaderView.ts +++ b/src/widgets/Header/view/HeaderView.ts @@ -36,6 +36,8 @@ class HeaderView { private switchThemeCheckbox: InputModel; + private toAddressesLink: LinkModel; + private toCartLink: LinkModel; private toProfileLink: LinkModel; @@ -50,6 +52,7 @@ class HeaderView { this.toCartLink = this.createToCartLink(); this.toWishlistLink = this.createToWishlistLink(); this.toProfileLink = this.createToProfileLink(); + this.toAddressesLink = this.createToAddressesLink(); this.switchThemeCheckbox = this.createSwitchThemeCheckbox(); this.switchLanguageCheckbox = this.createSwitchLanguageCheckbox(); this.navigationWrapper = this.createNavigationWrapper(); @@ -148,10 +151,11 @@ class HeaderView { tag: 'div', }); this.navigationWrapper.append( - this.createSwitchLanguageLabel(), - this.logoutButton.getHTML(), this.toProfileLink.getHTML(), + this.toAddressesLink.getHTML(), this.createSwitchThemeLabel(), + this.createSwitchLanguageLabel(), + this.logoutButton.getHTML(), ); return this.navigationWrapper; @@ -228,6 +232,39 @@ class HeaderView { return label; } + private createToAddressesLink(): LinkModel { + this.toAddressesLink = new LinkModel({ + attrs: { + href: PAGE_ID.USER_ADDRESSES_PAGE, + }, + classes: [styles.addressesLink], + }); + + const svg = document.createElementNS(SVG_DETAILS.SVG_URL, 'svg'); + svg.append(createSVGUse(SVG_DETAILS.HOUSE)); + this.toAddressesLink.getHTML().append(svg); + + if (!getStore().getState().isUserLoggedIn) { + this.toAddressesLink.getHTML().classList.add(styles.hidden); + } + + observeStore(selectIsUserLoggedIn, () => + this.toAddressesLink.getHTML().classList.toggle(styles.hidden, !getStore().getState().isUserLoggedIn), + ); + + this.toAddressesLink + .getHTML() + .classList.toggle(styles.addressesLinkActive, RouterModel.getCurrentPage() === PAGE_ID.USER_ADDRESSES_PAGE); + + observeStore(selectCurrentPage, () => + this.toAddressesLink + .getHTML() + .classList.toggle(styles.addressesLinkActive, RouterModel.getCurrentPage() === PAGE_ID.USER_ADDRESSES_PAGE), + ); + + return this.toAddressesLink; + } + private createToCartLink(): LinkModel { this.toCartLink = new LinkModel({ attrs: { @@ -296,7 +333,7 @@ class HeaderView { }); const svg = document.createElementNS(SVG_DETAILS.SVG_URL, 'svg'); - svg.append(createSVGUse(SVG_DETAILS.FILL_HEART)); + svg.append(createSVGUse(SVG_DETAILS.HEART)); this.toWishlistLink.getHTML().append(svg); @@ -355,6 +392,10 @@ class HeaderView { return this.switchLanguageCheckbox; } + public getToAddressesLink(): LinkModel { + return this.toAddressesLink; + } + public getToCartLink(): LinkModel { return this.toCartLink; } diff --git a/src/widgets/Header/view/headerView.module.scss b/src/widgets/Header/view/headerView.module.scss index db77a30d..44dbc877 100644 --- a/src/widgets/Header/view/headerView.module.scss +++ b/src/widgets/Header/view/headerView.module.scss @@ -44,7 +44,7 @@ gap: var(--medium-offset); @media (max-width: 768px) { - top: calc(var(--extra-small-offset) * 6.1); + top: calc(var(--extra-small-offset) * 6); grid-row: 2; width: 45%; } @@ -90,12 +90,13 @@ .logoutButton { @include green-btn; - order: 4; + order: 5; } .cartLink, .wishListLink, -.profileLink { +.profileLink, +.addressesLink { position: relative; display: flex; align-items: center; @@ -178,7 +179,7 @@ } .profileLink { - order: 2; + order: 1; svg { stroke: var(--noble-gray-1100); @@ -194,10 +195,16 @@ } } -.profileLinkActive { +.addressesLink { + order: 2; +} + +.profileLinkActive, +.addressesLinkActive { pointer-events: none; svg { + fill: var(--steam-green-800); stroke: var(--steam-green-800); } } @@ -320,6 +327,7 @@ .switchThemeLabel { position: relative; display: inline-block; + order: 3; width: var(--large-offset); height: calc(calc(var(--small-offset) / 1.5) + var(--extra-small-offset)); cursor: pointer; @@ -392,7 +400,7 @@ .switchLanguageLabel { position: relative; display: inline-block; - order: 3; + order: 4; width: var(--large-offset); height: calc(calc(var(--small-offset) / 1.5) + var(--extra-small-offset)); cursor: pointer; diff --git a/src/widgets/UserAddresses/model/UserAddressesModel.ts b/src/widgets/UserAddresses/model/UserAddressesModel.ts index 4440839d..e8fe3f5c 100644 --- a/src/widgets/UserAddresses/model/UserAddressesModel.ts +++ b/src/widgets/UserAddresses/model/UserAddressesModel.ts @@ -37,14 +37,7 @@ class UserAddressesModel { }; const createAddress = (activeTypes: AddressTypeType[], inactiveTypes?: AddressTypeType[]): UserAddressModel => - new UserAddressModel( - address, - activeTypes, - (isDisabled: boolean) => { - this.view.toggleState(isDisabled); - }, - inactiveTypes, - ); + new UserAddressModel(address, activeTypes, inactiveTypes); const newAddress = determineNewAddress(addressesContainsID, defaultContainsID, user, createAddress); @@ -74,8 +67,6 @@ class UserAddressesModel { } } catch (error) { showErrorMessage(error); - } finally { - this.view.toggleState(false); } } @@ -104,14 +95,6 @@ class UserAddressesModel { public getHTML(): HTMLElement { return this.view.getHTML(); } - - public hide(): void { - this.view.hide(); - } - - public show(): void { - this.view.show(); - } } export default UserAddressesModel; diff --git a/src/widgets/UserAddresses/view/UserAddressesView.ts b/src/widgets/UserAddresses/view/UserAddressesView.ts index c4d66c82..1bbcfa27 100644 --- a/src/widgets/UserAddresses/view/UserAddressesView.ts +++ b/src/widgets/UserAddresses/view/UserAddressesView.ts @@ -78,7 +78,7 @@ class UserAddressView { private createHTML(): HTMLDivElement { this.addressesWrapper = createBaseElement({ - cssClasses: [styles.addressesWrapper, styles.hidden], + cssClasses: [styles.addressesWrapper], tag: 'div', }); this.addressesWrapper.append( @@ -112,18 +112,6 @@ class UserAddressView { public getHTML(): HTMLDivElement { return this.addressesWrapper; } - - public hide(): void { - this.addressesWrapper.classList.add(styles.hidden); - } - - public show(): void { - this.addressesWrapper.classList.remove(styles.hidden); - } - - public toggleState(isDisabled: boolean): void { - this.addressesListWrapper.classList.toggle(styles.disabled, isDisabled); - } } export default UserAddressView;