import clsx from "clsx"; import { Bell, ChevronRight } from "lucide-react"; import * as React from "react"; import { useTranslation } from "react-i18next"; import { Link } from "react-router"; import { SendouPopover } from "~/components/elements/Popover"; import { NotificationItem, NotificationItemDivider, NotificationsList, } from "~/features/notifications/components/NotificationList"; import { type NotificationsData, useNotificationsData, } from "~/features/notifications/NotificationsProvider"; import { NOTIFICATIONS } from "~/features/notifications/notifications-contants"; import { NOTIFICATIONS_URL } from "~/utils/urls"; import { useMarkNotificationsAsSeen, useShowUnseenDot, useStickyUnseenIds, } from "../../features/notifications/notifications-hooks"; import styles from "./NotificationPopover.module.css"; export type LoaderNotification = NonNullable[number]; export function useNotifications() { const { notifications } = useNotificationsData(); const unseenIds = React.useMemo( () => notifications ?.filter((notification) => !notification.seen) .map((notification) => notification.id) ?? [], [notifications], ); const showUnseenDot = useShowUnseenDot(notifications); return { notifications, unseenIds, showUnseenDot }; } export function NotificationPopover({ notifications, unseenIds, triggerClassName, }: { notifications: LoaderNotification[]; unseenIds: number[]; triggerClassName?: string; }) { const [isOpen, setIsOpen] = React.useState(false); return ( } popoverClassName={clsx(styles.popoverContainer, { [styles.noNotificationsContainer]: notifications.length === 0, })} > ); } const NO_IDS: number[] = []; /** The list of the bell popover and the mobile "You" panel, rendered while closed too so that both work before hydration. */ export function NotificationContent({ notifications, unseenIds, isOpen, }: { notifications: LoaderNotification[]; unseenIds: number[]; isOpen: boolean; }) { const { t } = useTranslation(["common"]); const stickyUnseenIds = useStickyUnseenIds(notifications, isOpen); useMarkNotificationsAsSeen(isOpen ? unseenIds : NO_IDS); return ( <>

{t("common:notifications.title")}


{notifications.length === 0 ? (
{t("common:notifications.empty")}
) : ( {notifications.map((notification, i) => ( {i !== notifications.length - 1 ? ( ) : null} ))} )} {notifications.length === NOTIFICATIONS.PEEK_COUNT ? ( ) : null} ); } function NotificationsFooter() { const { t } = useTranslation(["common"]); return (

{t("common:actions.viewAll")}
); }