import { useNuiEvent } from '../../hooks/useNuiEvent'; import { toast, Toaster } from 'react-hot-toast'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import ReactMarkdown from 'react-markdown'; import { Avatar, createStyles, Group, Stack, Box, Text, keyframes, Sx } from '@mantine/core'; import React from 'react'; import type { NotificationProps } from '../../typings'; import MarkdownComponents from '../../config/MarkdownComponents'; import LibIcon from '../../components/LibIcon'; const useStyles = createStyles((theme) => ({ container: { width: 300, height: 'fit-content', backgroundColor: theme.colors.dark[6], color: theme.colors.dark[0], padding: 12, borderRadius: theme.radius.sm, fontFamily: 'Roboto', boxShadow: theme.shadows.sm, }, title: { fontWeight: 500, lineHeight: 'normal', }, description: { fontSize: 12, color: theme.colors.dark[2], fontFamily: 'Roboto', lineHeight: 'normal', }, descriptionOnly: { fontSize: 14, color: theme.colors.dark[2], fontFamily: 'Roboto', lineHeight: 'normal', }, })); // I hate this const enterAnimationTop = keyframes({ from: { opacity: 0, transform: 'translateY(-30px)', }, to: { opacity: 1, transform: 'translateY(0px)', }, }); const enterAnimationBottom = keyframes({ from: { opacity: 0, transform: 'translateY(30px)', }, to: { opacity: 1, transform: 'translateY(0px)', }, }); const exitAnimationTop = keyframes({ from: { opacity: 1, transform: 'translateY(0px)', }, to: { opacity: 0, transform: 'translateY(-100%)', }, }); const exitAnimationRight = keyframes({ from: { opacity: 1, transform: 'translateX(0px)', }, to: { opacity: 0, transform: 'translateX(100%)', }, }); const exitAnimationLeft = keyframes({ from: { opacity: 1, transform: 'translateX(0px)', }, to: { opacity: 0, transform: 'translateX(-100%)', }, }); const exitAnimationBottom = keyframes({ from: { opacity: 1, transform: 'translateY(0px)', }, to: { opacity: 0, transform: 'translateY(100%)', }, }); const Notifications: React.FC = () => { const { classes } = useStyles(); useNuiEvent('notify', (data) => { if (!data.title && !data.description) return; // Backwards compat with old notifications let position = data.position; switch (position) { case 'top': position = 'top-center'; break; case 'bottom': position = 'bottom-center'; break; } if (!data.icon) { switch (data.type) { case 'error': data.icon = 'circle-xmark'; break; case 'success': data.icon = 'circle-check'; break; case 'warning': data.icon = 'circle-exclamation'; break; default: data.icon = 'circle-info'; break; } } toast.custom( (t) => ( {data.icon && ( <> {!data.iconColor ? ( ) : ( )} )} {data.title && {data.title}} {data.description && ( {data.description} )} ), { id: data.id?.toString(), duration: data.duration || 3000, position: position || 'top-right', } ); }); return ; }; export default Notifications;