2024-09-10 19:26:54 +02:00

135 lines
3.3 KiB
TypeScript

import React from "react";
// Components
// Stores
// Styles
import classes from "./classes.module.scss";
import Toasts, { IToast } from "@Front/Stores/Toasts";
import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography";
// import CheckIcon from "@Assets/Icons/check.svg";
// import Image from "next/image";
import { NextRouter, useRouter } from "next/router";
type IProps = {
toast: IToast;
};
type IPropsClass = IProps & {
router: NextRouter;
};
type IState = {
willClose: boolean;
};
class ToastElementClass extends React.Component<IPropsClass, IState> {
private closeTimeout = 0;
constructor(props: IPropsClass) {
super(props);
this.state = {
willClose: false,
};
this.onClose = this.onClose.bind(this);
this.handleClick = this.handleClick.bind(this);
}
public override render(): JSX.Element {
const toast = this.props.toast;
const style = {
"--data-duration": `${toast.time}ms`,
} as React.CSSProperties;
return (
<div
className={classes["root"]}
data-will-close={this.state.willClose}
data-clickable={toast.redirectUrl ? true : false}
onClick={this.handleClick}>
{toast.time !== 0 && <div className={classes["loadbar"]} style={style} />}
<div className={classes["header"]}>
<div className={classes["text-icon_row"]}>
{toast.icon && toast.icon}
<div className={classes["text-container"]}>
{this.getToastTitle(toast.title)}
{this.getToastText(toast.text)}
{this.getToastDate(toast.created_at)}
</div>
</div>
<div className={classes["notif-unread"]}>
<div className={classes["notif-unread-dot"]} onClick={this.onClose} />
</div>
{/* {toast.closable && <Image src={CheckIcon} alt="Document check" className={classes["cross"]} onClick={this.onClose} />} */}
</div>
{toast.button}
</div>
);
}
public override componentDidMount() {
if (this.props.toast.time === 0) return;
this.closeTimeout = window.setTimeout(() => {
this.close();
}, this.props.toast.time);
}
private getToastTitle(title: string | React.ReactNode) {
if (typeof title === "string") {
return <Typography typo={ETypo.TEXT_MD_REGULAR}>{title}</Typography>;
}
return title;
}
private getToastDate(date: Date | null | undefined) {
const tempDate = new Date(date!);
return tempDate.toDateString();
}
private getToastText(text: React.ReactNode) {
if (typeof text === "string") {
return (
<div className={classes["text-container"]}>
<Typography typo={ETypo.TEXT_SM_REGULAR} color={ETypoColor.COLOR_NEUTRAL_500}>
{text}
</Typography>
</div>
);
}
return text;
}
private onClose(e: React.MouseEvent) {
e.preventDefault();
e.stopPropagation();
this.close();
}
private async close() {
await Toasts.getInstance().markRead(this.props.toast);
window.clearTimeout(this.closeTimeout);
this.setState({
willClose: true,
});
setTimeout(() => {
Toasts.getInstance().close(this.props.toast);
}, 200);
}
private async handleClick(e: React.MouseEvent) {
if (this.props.toast.redirectUrl) {
await this.onClose(e);
await this.props.router.push(this.props.toast.redirectUrl);
this.props.router.reload();
}
}
}
export default function ToastElement(props: IProps) {
const router = useRouter();
return <ToastElementClass {...props} router={router} />;
}