You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

79 lines
2.5 KiB

import React from 'react';
import { FiBell, FiX } from 'react-icons/fi';
import { shift, useFloating } from '@floating-ui/react-dom';
import { Popover } from '@headlessui/react';
import { useAppSelector } from '@hooks/useAppSelector';
import { Button, IconButton } from '@meshtastic/components';
export const Notifications = (): JSX.Element => {
const [unreadCount, setUnreadCount] = React.useState(0);
const notifications = useAppSelector((state) => state.app.notifications);
const { x, y, reference, floating, strategy } = useFloating({
placement: 'bottom',
middleware: [shift()],
});
React.useEffect(() => {
setUnreadCount(
notifications.filter((notification) => !notification.read).length,
);
}, [notifications]);
return (
<Popover>
<Popover.Button as="div" className="relative" ref={reference}>
<IconButton icon={<FiBell className="w-5 h-5" />} />
{unreadCount > 0 && (
<div className="absolute pointer-events-none top-1 right-1">
<div className="w-3 h-3 text-xs font-semibold leading-3 text-center text-white bg-orange-500 rounded-full">
{unreadCount}
</div>
</div>
)}
</Popover.Button>
<Popover.Panel
ref={floating}
style={{
position: strategy,
top: y ?? '',
left: x ?? '',
}}
className="fixed z-50 border border-gray-300 rounded-md shadow-md w-72 bg-primaryDark dark:border-gray-600"
>
<div className="divide-y divide-gray-600">
{notifications.map((notification, index) => (
<div
key={index}
className={`p-1 flex text-sm justify-between ${
notification.read
? 'text-gray-600 dark:text-gray-300'
: 'text-gray-900 dark:text-white'
}`}
>
<div className="my-auto">{notification.icon}</div>
<div className="my-auto font-light">{notification.title}</div>
<div className="flex space-x-1">
{notification.action ? (
<div className="my-auto w-18">
<Button border onClick={notification.action.action}>
{notification.action.message}
</Button>
</div>
) : (
<div className="w-16" />
)}
<IconButton icon={<FiX />} />
</div>
</div>
))}
</div>
</Popover.Panel>
</Popover>
);
};