notifications container front
This commit is contained in:
parent
28e6ced198
commit
fa7bc24fed
@ -23,7 +23,7 @@ export default class Toasts {
|
|||||||
private toastList: IToast[] = [];
|
private toastList: IToast[] = [];
|
||||||
private uid: number = 0;
|
private uid: number = 0;
|
||||||
|
|
||||||
private defaultTime: IToast["time"] = 4000;
|
private defaultTime: IToast["time"] = 40000;
|
||||||
private defaultClosable: IToast["closable"] = true;
|
private defaultClosable: IToast["closable"] = true;
|
||||||
private defaultPriority: IToast["priority"] = EToastPriority.LOW;
|
private defaultPriority: IToast["priority"] = EToastPriority.LOW;
|
||||||
|
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
@import "@Themes/constants.scss";
|
@import "@Themes/constants.scss";
|
||||||
|
|
||||||
.root {
|
.root {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
width: 300px;
|
width: 300px;
|
||||||
height: 500px;
|
max-height: 80%;
|
||||||
background-color: $orange-flash;
|
background-color: $white;
|
||||||
|
box-shadow: $shadow-nav;
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 107px;
|
top: 107px;
|
||||||
right:56px;
|
right:56px;
|
||||||
|
|
||||||
.notification-header{
|
.notification-header{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
@ -16,4 +20,9 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.notification-body{
|
||||||
|
margin-top: 24px;
|
||||||
|
overflow: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,41 +3,64 @@ import classes from "./classes.module.scss";
|
|||||||
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
||||||
import CloseIcon from "@Assets/icons/cross.svg";
|
import CloseIcon from "@Assets/icons/cross.svg";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
import ToastHandler from "@Front/Components/DesignSystem/Toasts/ToastsHandler";
|
||||||
|
import Toasts, { IToast } from "@Front/Stores/Toasts";
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
openModal: () => void;
|
isOpen: boolean;
|
||||||
|
closeModal: () => void;
|
||||||
};
|
};
|
||||||
type IState = {
|
type IState = {
|
||||||
isModalOpen: boolean;
|
toastList: IToast[] | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class NotificationModal extends React.Component<IProps, IState> {
|
export default class NotificationModal extends React.Component<IProps, IState> {
|
||||||
|
private removeOnToastChange: () => void = () => { };
|
||||||
|
|
||||||
constructor(props: IProps) {
|
constructor(props: IProps) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
isModalOpen: true,
|
toastList: Toasts.getInstance().toasts,
|
||||||
};
|
};
|
||||||
this.closeModal = this.closeModal.bind(this);
|
this.handleToastChange = this.handleToastChange.bind(this);
|
||||||
this.openModal = this.openModal.bind(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override render(): JSX.Element | null {
|
public override render(): JSX.Element | null {
|
||||||
if (!this.state.isModalOpen) return null;
|
if (!this.props.isOpen) return null;
|
||||||
return <div className={classes["root"]}>
|
return <div className={classes["root"]}>
|
||||||
<div className={classes["notification-header"]}>
|
<div className={classes["notification-header"]}>
|
||||||
<Typography typo={ITypo.P_16}>
|
<Typography typo={ITypo.P_16}>
|
||||||
Notifications
|
Notifications
|
||||||
</Typography>
|
</Typography>
|
||||||
<div className={classes["close-icon"]} onClick={this.closeModal}>
|
<div className={classes["close-icon"]} onClick={this.props.closeModal}>
|
||||||
<Image src={CloseIcon} alt="Close notification modal" className={classes["close-icon"]}></Image>
|
<Image src={CloseIcon} alt="Close notification modal" className={classes["close-icon"]}></Image>
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
|
|
||||||
|
<div className={classes["notification-body"]}>
|
||||||
|
<>
|
||||||
|
{Toasts.getInstance().toasts.length === 0
|
||||||
|
?
|
||||||
|
<div>
|
||||||
|
<Typography typo={ITypo.P_16}>No notification yet</Typography>
|
||||||
|
</div>
|
||||||
|
: <ToastHandler />}
|
||||||
|
</>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
private closeModal() {
|
|
||||||
this.setState({ isModalOpen: false });
|
public override componentDidMount() {
|
||||||
}
|
this.removeOnToastChange = Toasts.getInstance().onChange(this.handleToastChange);
|
||||||
private openModal() {
|
}
|
||||||
this.setState({ isModalOpen: true });
|
|
||||||
}
|
public override componentWillUnmount() {
|
||||||
|
this.removeOnToastChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleToastChange(toastList: IToast[] | null) {
|
||||||
|
this.setState({
|
||||||
|
toastList,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,21 +18,26 @@ export default class Notifications extends React.Component<IProps, IState> {
|
|||||||
hasNotifications: true,
|
hasNotifications: true,
|
||||||
isModalOpen: true,
|
isModalOpen: true,
|
||||||
};
|
};
|
||||||
this.opeModal = this.opeModal.bind(this);
|
this.openModal = this.openModal.bind(this);
|
||||||
|
this.closeModal = this.closeModal.bind(this);
|
||||||
}
|
}
|
||||||
public override render(): JSX.Element {
|
public override render(): JSX.Element {
|
||||||
const hasNotifications = Toasts.getInstance().toasts.length;
|
const hasNotifications = Toasts.getInstance().toasts.length;
|
||||||
console.log(hasNotifications)
|
console.log(hasNotifications)
|
||||||
return <div className={classes["root"]}>
|
return <div className={classes["root"]}>
|
||||||
<div className={classes["icon-container"]} onClick={this.opeModal}>
|
<div className={classes["icon-container"]} onClick={this.openModal}>
|
||||||
<Image alt="notifications" src={NotificationIcon} className={classes["notification-icon"]} />
|
<Image alt="notifications" src={NotificationIcon} className={classes["notification-icon"]} />
|
||||||
{this.state.hasNotifications && <div className={classes["notification-dot"]}></div>}
|
{this.state.hasNotifications && <div className={classes["notification-dot"]}></div>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{ this.state.isModalOpen && <NotificationModal isOpen={this.state.isModalOpen} />}
|
{this.state.isModalOpen && <NotificationModal isOpen={this.state.isModalOpen} closeModal={this.closeModal} />}
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
private opeModal() {
|
private openModal() {
|
||||||
this.setState({ isModalOpen: true });
|
this.setState({ isModalOpen: true });
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
private closeModal() {
|
||||||
|
this.setState({ isModalOpen: false });
|
||||||
|
};
|
||||||
|
}
|
@ -6,7 +6,7 @@
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
height: 83px;
|
height: 83px;
|
||||||
background-color: $white;
|
background-color: $white;
|
||||||
box-shadow: $shadow-neutral;
|
box-shadow: $shadow-nav;
|
||||||
padding: 0 48px;
|
padding: 0 48px;
|
||||||
|
|
||||||
.logo-container {
|
.logo-container {
|
||||||
|
@ -3,22 +3,9 @@
|
|||||||
.root {
|
.root {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
position: fixed;
|
|
||||||
z-index: 10;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
padding: 0px;
|
|
||||||
width: 0px;
|
|
||||||
max-height: calc(100vh - 80px);
|
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
|
||||||
&.open {
|
|
||||||
width: 341px;
|
|
||||||
top: 70px;
|
|
||||||
padding: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > *:not(:first-child) {
|
& > *:not(:first-child) {
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import React, { ReactNode } from "react";
|
import React, { ReactNode } from "react";
|
||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
import Header from "@Front/Components/DesignSystem/Header";
|
import Header from "@Front/Components/DesignSystem/Header";
|
||||||
import ToastHandler from "@Front/Components/DesignSystem/Toasts/ToastsHandler";
|
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
title: string;
|
title: string;
|
||||||
@ -23,7 +22,6 @@ export default class DefaultTemplate extends React.Component<IProps, IState> {
|
|||||||
<>
|
<>
|
||||||
<Header />
|
<Header />
|
||||||
<div className={classes["root"]}>
|
<div className={classes["root"]}>
|
||||||
<ToastHandler />
|
|
||||||
<div className={classes["content"]}>{this.props.children}</div>
|
<div className={classes["content"]}>{this.props.children}</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
@ -39,4 +39,5 @@ $grey-soft: #f9f9f9;
|
|||||||
|
|
||||||
$modal-background: rgba(0, 0, 0, 0.44);
|
$modal-background: rgba(0, 0, 0, 0.44);
|
||||||
|
|
||||||
$shadow-neutral: 0px 8px 10px 0px #00000012;
|
$shadow-nav: 0px 8px 10px rgba(0, 0, 0, 0.07);
|
||||||
|
$shadow-tooltip: 0px 4px 24px rgba(0, 0, 0, 0.15);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user