Skip to content

Commit

Permalink
feat(RSS-ECOMM-3_21): implement navigation (#217)
Browse files Browse the repository at this point in the history
* feat: implement navigation to catalog and cart pages

* fix: footer styles

* fix: header styles

* feat: implement navigation to other pages

* feat: check auth user to profile page

* feat: check auth user with init app

* feat: visually profile button
  • Loading branch information
Kleostro authored May 10, 2024
1 parent 44a36fd commit 74f3e30
Show file tree
Hide file tree
Showing 15 changed files with 364 additions and 36 deletions.
8 changes: 4 additions & 4 deletions src/app/App/model/AppModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ class AppModel {
private createRoutes(): Promise<Map<string, () => Promise<Page>>> {
const routesMap = {
[PAGE_ID.ABOUT_US_PAGE]: async (): Promise<Page> => {
const { default: AbooutUsPageModel } = await import('@/pages/AboutUsPage/model/AboutUsPageModel.ts');
return new AbooutUsPageModel(this.appView.getHTML());
const { default: AboutUsPageModel } = await import('@/pages/AboutUsPage/model/AboutUsPageModel.ts');
return new AboutUsPageModel(this.appView.getHTML());
},
[PAGE_ID.CART_PAGE]: async (): Promise<Page> => {
const { default: CartPageModel } = await import('@/pages/CartPage/model/CartPageModel.ts');
Expand All @@ -37,7 +37,7 @@ class AppModel {
},
[PAGE_ID.DEFAULT_PAGE]: async (): Promise<Page> => {
const { default: MainPageModel } = await import('@/pages/MainPage/model/MainPageModel.ts');
return new MainPageModel(this.appView.getHTML());
return new MainPageModel(this.appView.getHTML(), this.router);
},
[PAGE_ID.ITEM_PAGE]: async (): Promise<Page> => {
const { default: ItemPageModel } = await import('@/pages/ItemPage/model/ItemPageModel.ts');
Expand All @@ -49,7 +49,7 @@ class AppModel {
},
[PAGE_ID.MAIN_PAGE]: async (): Promise<Page> => {
const { default: MainPageModel } = await import('@/pages/MainPage/model/MainPageModel.ts');
return new MainPageModel(this.appView.getHTML());
return new MainPageModel(this.appView.getHTML(), this.router);
},
[PAGE_ID.NOT_FOUND_PAGE]: async (): Promise<Page> => {
const { default: NotFoundPageModel } = await import('@/pages/NotFoundPage/model/NotFoundPageModel.ts');
Expand Down
1 change: 1 addition & 0 deletions src/app/styles/variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
--noble-gray-700: #727272;
--noble-gray-800: #3d3d3d;
--red-power-600: #d0302f;
--steam-green-300: #46a35880;
--steam-green-400: #c8f4b4;
--steam-green-500: #b6f09c;
--steam-green-700: #70d27a;
Expand Down
44 changes: 43 additions & 1 deletion src/entities/Navigation/view/NavigationView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ class NavigationView {

private navigationLinks: Map<string, LinkModel> = new Map();

private toAboutLink: LinkModel;

private toCatalogLink: LinkModel;

private toLoginLink: LinkModel;

private toMainLink: LinkModel;
Expand All @@ -21,6 +25,8 @@ class NavigationView {
this.toMainLink = this.createToMainLink();
this.toLoginLink = this.createToLoginLink();
this.toRegisterLink = this.createToRegisterLink();
this.toCatalogLink = this.createToCatalogLink();
this.toAboutLink = this.createToAboutLink();
this.navigation = this.createHTML();
}

Expand All @@ -29,10 +35,46 @@ class NavigationView {
cssClasses: [styles.navigation],
tag: 'nav',
});
this.navigation.append(this.toMainLink.getHTML(), this.toLoginLink.getHTML(), this.toRegisterLink.getHTML());
this.navigation.append(
this.toMainLink.getHTML(),
this.toLoginLink.getHTML(),
this.toRegisterLink.getHTML(),
this.toCatalogLink.getHTML(),
this.toAboutLink.getHTML(),
);
return this.navigation;
}

private createToAboutLink(): LinkModel {
this.toAboutLink = new LinkModel({
attrs: {
href: PAGE_ID.ABOUT_US_PAGE,
},
classes: [styles.link],
text: PAGE_LINK_TEXT[getStore().getState().currentLanguage].ABOUT,
});

observeCurrentLanguage(this.toAboutLink.getHTML(), PAGE_LINK_TEXT, PAGE_LINK_TEXT_KEYS.ABOUT);

this.navigationLinks.set(PAGE_ID.ABOUT_US_PAGE, this.toAboutLink);
return this.toAboutLink;
}

private createToCatalogLink(): LinkModel {
this.toCatalogLink = new LinkModel({
attrs: {
href: PAGE_ID.CATALOG_PAGE,
},
classes: [styles.link],
text: PAGE_LINK_TEXT[getStore().getState().currentLanguage].CATALOG,
});

observeCurrentLanguage(this.toCatalogLink.getHTML(), PAGE_LINK_TEXT, PAGE_LINK_TEXT_KEYS.CATALOG);

this.navigationLinks.set(PAGE_ID.CATALOG_PAGE, this.toCatalogLink);
return this.toCatalogLink;
}

private createToLoginLink(): LinkModel {
this.toLoginLink = new LinkModel({
attrs: {
Expand Down
10 changes: 7 additions & 3 deletions src/entities/Navigation/view/navigationView.module.scss
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
.navigation {
display: flex;
align-items: center;
align-self: center;
justify-content: center;
grid-column: 2;
grid-row: 1;
order: 2;
height: 70px;
gap: var(--extra-small-offset);
}

.link {
position: relative;
display: flex;
align-items: center;
height: 100%;
font: var(--regular-font);
letter-spacing: 1px;
text-transform: uppercase;
Expand All @@ -19,7 +23,7 @@
content: '';
position: absolute;
left: 0;
bottom: -4px;
bottom: -1px;
width: 100%;
height: 2px;
background-color: currentcolor;
Expand Down
11 changes: 10 additions & 1 deletion src/pages/MainPage/model/MainPageModel.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
import type RouterModel from '@/app/Router/model/RouterModel.ts';
import type { Page } from '@/shared/types/common.ts';

import NavigationModel from '@/entities/Navigation/model/NavigationModel.ts';
import getStore from '@/shared/Store/Store.ts';
import { setCurrentPage } from '@/shared/Store/actions.ts';
import { PAGE_ID } from '@/shared/constants/pages.ts';

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

class MainPageModel implements Page {
private navigation: NavigationModel;

private router: RouterModel;

private view: MainPageView;

constructor(parent: HTMLDivElement) {
constructor(parent: HTMLDivElement, router: RouterModel) {
this.router = router;
this.view = new MainPageView(parent);
this.navigation = new NavigationModel(this.router);
this.init();
}

private init(): void {
this.getHTML().append(this.navigation.getHTML());
getStore().dispatch(setCurrentPage(PAGE_ID.MAIN_PAGE));
}

Expand Down
6 changes: 6 additions & 0 deletions src/shared/constants/pages.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
export const PAGE_LINK_TEXT = {
en: {
ABOUT: 'About us',
CATALOG: 'Catalog',
LOGIN: 'Login',
MAIN: 'Main',
REGISTRATION: 'Register',
},
ru: {
ABOUT: 'О нас',
CATALOG: 'Каталог',
LOGIN: 'Вход',
MAIN: 'Главная',
REGISTRATION: 'Регистрация',
},
} as const;

export const PAGE_LINK_TEXT_KEYS = {
ABOUT: 'ABOUT',
CATALOG: 'CATALOG',
LOGIN: 'LOGIN',
MAIN: 'MAIN',
REGISTRATION: 'REGISTRATION',
Expand Down
2 changes: 2 additions & 0 deletions src/shared/constants/svg.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
const SVG_DETAILS = {
CART: 'cart',
CLOSE_EYE: 'closeEye',
LOGO: 'logo',
OPEN_EYE: 'openEye',
PROFILE: 'userCircle',
SVG_URL: 'http://www.w3.org/2000/svg',
SWITCH_LANGUAGE: {
en: 'en',
Expand Down
3 changes: 3 additions & 0 deletions src/shared/img/svg/cart.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/shared/img/svg/userCircle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/widgets/Footer/model/FooterModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class FooterModel {
}

private init(): boolean {
this.getHTML().append(this.navigation.getHTML());
this.view.getWrapper().append(this.navigation.getHTML());
return true;
}

Expand Down
18 changes: 18 additions & 0 deletions src/widgets/Footer/view/FooterView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import styles from './footerView.module.scss';
class FooterView {
private footer: HTMLElement;

private wrapper: HTMLDivElement;

constructor() {
this.wrapper = this.createWrapper();
this.footer = this.createHTML();
}

Expand All @@ -14,12 +17,27 @@ class FooterView {
cssClasses: [styles.footer],
tag: 'footer',
});

this.footer.append(this.wrapper);
return this.footer;
}

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

return this.wrapper;
}

public getHTML(): HTMLElement {
return this.footer;
}

public getWrapper(): HTMLDivElement {
return this.wrapper;
}
}

export default FooterView;
12 changes: 7 additions & 5 deletions src/widgets/Footer/view/footerView.module.scss
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
.footer {
border-top: 1px solid var(--steam-green-300);
padding: 0 var(--small-offset);
width: 100%;
background-color: var(--white);
}

.wrapper {
display: flex;
align-items: center;
justify-content: center;
border-top: 10px solid var(--steam-green-800);
border-radius: var(--medium-br);
padding: calc(var(--small-offset) / 2) var(--small-offset);
width: 100%;
max-width: 1440px;
background-color: var(--white);
}
55 changes: 54 additions & 1 deletion src/widgets/Header/model/HeaderModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,44 @@ class HeaderModel {
this.init();
}

private checkAuthUser(): boolean {
const { currentUser } = getStore().getState();
if (!currentUser) {
this.router
.navigateTo(PAGE_ID.LOGIN_PAGE)
.catch(() =>
serverMessageModel.showServerMessage(
SERVER_MESSAGE[getStore().getState().currentLanguage].BAD_REQUEST,
MESSAGE_STATUS.ERROR,
),
);
return false;
}
return true;
}

private checkCurrentUser(): boolean {
const { currentUser } = getStore().getState();
const logoutButton = this.view.getLogoutButton();
if (currentUser) {
this.view.getToProfileLink().setEnabled();
logoutButton.setEnabled();
} else {
logoutButton.setDisabled();
this.view.getToProfileLink().setDisabled();
}
return true;
}

private init(): boolean {
this.getHTML().append(this.navigation.getHTML());
this.view.getWrapper().append(this.navigation.getHTML());
this.checkAuthUser();
this.checkCurrentUser();
this.setLogoHandler();
this.observeCurrentUser();
this.setLogoutButtonHandler();
this.setCartLinkHandler();
this.setProfileLinkHandler();
this.setChangeLanguageButtonHandler();
return true;
}
Expand All @@ -68,6 +89,22 @@ class HeaderModel {
return true;
}

private setCartLinkHandler(): boolean {
const logo = this.view.getToCartLink().getHTML();
logo.addEventListener('click', async (event) => {
event.preventDefault();
try {
await this.router.navigateTo(PAGE_ID.CART_PAGE);
} catch {
serverMessageModel.showServerMessage(
SERVER_MESSAGE[getStore().getState().currentLanguage].BAD_REQUEST,
MESSAGE_STATUS.ERROR,
);
}
});
return true;
}

private setChangeLanguageButtonHandler(): boolean {
const switchLanguageButton = this.view.getSwitchLanguageButton().getHTML();
switchLanguageButton.addEventListener('click', () => {
Expand Down Expand Up @@ -110,6 +147,22 @@ class HeaderModel {
return true;
}

private setProfileLinkHandler(): boolean {
const logo = this.view.getToProfileLink().getHTML();
logo.addEventListener('click', (event) => {
event.preventDefault();
if (this.checkAuthUser()) {
this.router.navigateTo(PAGE_ID.USER_PROFILE_PAGE).catch(() => {
serverMessageModel.showServerMessage(
SERVER_MESSAGE[getStore().getState().currentLanguage].BAD_REQUEST,
MESSAGE_STATUS.ERROR,
);
});
}
});
return true;
}

public getHTML(): HTMLElement {
return this.view.getHTML();
}
Expand Down
Loading

0 comments on commit 74f3e30

Please sign in to comment.