Skip to content

Commit

Permalink
feat: implement not found page
Browse files Browse the repository at this point in the history
  • Loading branch information
stardustmeg committed May 2, 2024
1 parent e11e805 commit 7bbbfd4
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/app/App/model/AppModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class AppModel {
const loginPage = new LoginPageModel(root, this.router);
const mainPage = new MainPageModel(root, this.router);
const registrationPage = new RegistrationPageModel(root, this.router);
const notFoundPage = new NotFoundPageModel(root);
const notFoundPage = new NotFoundPageModel(root, this.router);
const pages: Map<string, PageInterface> = new Map(
Object.entries({
[PAGES_IDS.DEFAULT_PAGE]: mainPage,
Expand Down
31 changes: 29 additions & 2 deletions src/pages/NotFoundPage/model/NotFoundPageModel.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,38 @@
import type RouterModel from '@/app/Router/model/RouterModel.ts';
import type { PageInterface } from '@/shared/types/interfaces.ts';

import EventMediatorModel from '@/shared/EventMediator/model/EventMediatorModel.ts';
import { MEDIATOR_EVENTS, PAGES_IDS } from '@/shared/constants/enums.ts';
import getStore from '@/shared/Store/Store.ts';
import { EVENT_NAMES, MEDIATOR_EVENTS, PAGE_DESCRIPTION, PAGES_IDS } from '@/shared/constants/enums.ts';

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

class NotFoundPageModel implements PageInterface {
private eventMediator = EventMediatorModel.getInstance();

private router: RouterModel;

private view: NotFoundPageView;

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

private createPageDescription(): string {
const { currentUser } = getStore().getState();

const textDescription = currentUser
? `Hi, ${currentUser.firstName}. ${PAGE_DESCRIPTION[404]}`
: PAGE_DESCRIPTION[404];
return textDescription;
}

private init(): boolean {
this.subscribeToEventMediator();
this.toMainButtonHandler();
return true;
}

private subscribeToEventMediator(): void {
Expand All @@ -22,13 +42,20 @@ class NotFoundPageModel implements PageInterface {
private switchPageVisibility(route: unknown): boolean {
if (route === PAGES_IDS.NOT_FOUND_PAGE) {
this.view.show();
this.view.setPageDescription(this.createPageDescription());
} else {
this.view.hide();
return false;
}
return true;
}

private toMainButtonHandler(): boolean {
const toMainButton = this.view.getToMainButton().getHTML();
toMainButton.addEventListener(EVENT_NAMES.CLICK, this.router.navigateTo.bind(this.router, PAGES_IDS.MAIN_PAGE));
return true;
}

public getHTML(): HTMLDivElement {
return this.view.getHTML();
}
Expand Down
68 changes: 63 additions & 5 deletions src/pages/NotFoundPage/view/NotFoundPageView.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,98 @@
import { TAG_NAMES } from '@/shared/constants/enums.ts';
import ButtonModel from '@/shared/Button/model/ButtonModel.ts';
import { SVG_DETAILS, TAG_NAMES } from '@/shared/constants/enums.ts';
import createBaseElement from '@/shared/utils/createBaseElement.ts';
import createSVGUse from '@/shared/utils/createSVGUse.ts';

import NOT_FOUND_PAGE_STYLES from './notFoundPageView.module.scss';
import styles from './notFoundPageView.module.scss';

class NotFoundPageView {
private description: HTMLParagraphElement;

private logo: HTMLDivElement;

private page: HTMLDivElement;

private parent: HTMLDivElement;

private title: HTMLHeadingElement;

private toMainButton: ButtonModel;

constructor(parent: HTMLDivElement) {
this.parent = parent;

this.logo = this.createPageLogo();
this.title = this.createPageTitle();
this.description = this.createPageDescription();
this.toMainButton = this.createToMainButton();

this.page = this.createHTML();
}

private createHTML(): HTMLDivElement {
this.page = createBaseElement({
cssClasses: [NOT_FOUND_PAGE_STYLES.notFoundPage],
cssClasses: [styles.notFoundPage],
tag: TAG_NAMES.DIV,
});

this.page.append(this.logo, this.title, this.description, this.toMainButton.getHTML());
this.parent.append(this.page);

return this.page;
}

private createPageDescription(): HTMLParagraphElement {
this.description = createBaseElement({
cssClasses: [styles.pageDescription],
tag: TAG_NAMES.P,
});
return this.description;
}

private createPageLogo(): HTMLDivElement {
this.logo = createBaseElement({ cssClasses: [styles.pageLogo], tag: TAG_NAMES.DIV });
const svg = document.createElementNS(SVG_DETAILS.SVG_URL, TAG_NAMES.SVG);
svg.append(createSVGUse(SVG_DETAILS.LOGO));

this.logo.append(svg);

return this.logo;
}

private createPageTitle(): HTMLHeadingElement {
this.title = createBaseElement({
cssClasses: [styles.pageTitle],
innerContent: '404',
tag: TAG_NAMES.H1,
});
return this.title;
}

private createToMainButton(): ButtonModel {
this.toMainButton = new ButtonModel({ classes: [styles.toMainButton], text: 'Go Back' });
return this.toMainButton;
}

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

public getToMainButton(): ButtonModel {
return this.toMainButton;
}

public hide(): boolean {
this.page.classList.add(NOT_FOUND_PAGE_STYLES.notFoundPage_hidden);
this.page.classList.add(styles.notFoundPage_hidden);
return true;
}

public setPageDescription(text: string): HTMLParagraphElement {
this.description.innerText = text;
return this.description;
}

public show(): boolean {
this.page.classList.remove(NOT_FOUND_PAGE_STYLES.notFoundPage_hidden);
this.page.classList.remove(styles.notFoundPage_hidden);
return true;
}
}
Expand Down
58 changes: 56 additions & 2 deletions src/pages/NotFoundPage/view/notFoundPageView.module.scss
Original file line number Diff line number Diff line change
@@ -1,9 +1,63 @@
.notFoundPage {
position: relative;
display: block;
padding: 0 var(--small-offset);
display: flex;
flex-direction: column;
margin: 0 auto;
border-bottom: calc(var(--extra-small-offset) / 2) solid var(--steam-green-800);
padding: calc(var(--extra-large-offset) / 2) var(--extra-large-offset);
padding-bottom: calc(var(--extra-large-offset) / 2 + calc(var(--extra-small-offset) / 2));
max-width: 500px;
background-color: var(--white);
gap: var(--medium-offset);

&_hidden {
display: none;
}
}

.pageLogo {
display: flex;
margin: 0 auto;

svg {
width: var(--large-offset);
height: var(--large-offset);
}
}

.pageTitle {
display: flex;
margin: 0 auto;
font: var(--extra-medium-font);
letter-spacing: 1px;
color: var(--steam-green-800);
}

.pageDescription {
font: var(--regular-font) '*' 1.5;
letter-spacing: 1px;
text-align: center;
color: var(--noble-gray-700);
}

.toMainButton {
border-radius: var(--small-br);
padding: calc(var(--extra-small-offset) / 2) var(--small-offset);
font: var(--bold-font);
letter-spacing: 1px;
color: var(--white);
background-color: var(--steam-green-800);
transition:
color 0.2s,
background-color 0.2s;

&:focus {
background-color: var(--steam-green-700);
}

@media (hover: hover) {
&:hover {
background-color: var(--steam-green-700);
}
}
}
2 changes: 2 additions & 0 deletions src/shared/constants/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ export const FORM_SUBMIT_BUTTON_TEXT = {

export const SVG_DETAILS = {
CLOSE_EYE: 'closeEye',
LOGO: 'logo',
OPEN_EYE: 'openEye',
SVG_URL: 'http://www.w3.org/2000/svg',
} as const;
Expand All @@ -201,6 +202,7 @@ export const PAGE_LINK_TEXT = {
} as const;

export const PAGE_DESCRIPTION = {
404: 'This is not the page you are looking for. Please go back to the main page.',
LOGIN: 'Enter your email and password to login.',
REGISTRATION: 'Enter your information to register.',
} as const;
Expand Down
3 changes: 3 additions & 0 deletions src/shared/img/svg/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 7bbbfd4

Please sign in to comment.