sendou.ink/app/features/notifications/components/NotificationList.tsx
Kalle fb86b9f24d
Some checks are pending
E2E Tests / e2e (push) Waiting to run
Tests and checks on push / run-checks-and-tests (push) Waiting to run
Updates translation progress / update-translation-progress-issue (push) Waiting to run
Change scrim notification text not to include timestamp
Closes #2998
2026-04-26 13:05:48 +03:00

91 lines
2.1 KiB
TypeScript

import { formatDistance } from "date-fns";
import { useTranslation } from "react-i18next";
import { Link } from "react-router";
import { Image } from "~/components/Image";
import type { LoaderNotification } from "~/components/layout/NotificationPopover";
import {
notificationLink,
notificationNavIcon,
} from "~/features/notifications/notifications-utils";
import { databaseTimestampToDate } from "~/utils/dates";
import { navIconUrl } from "~/utils/urls";
import styles from "./NotificationList.module.css";
export function NotificationsList({ children }: { children: React.ReactNode }) {
return <div>{children}</div>;
}
export function NotificationItem({
notification,
onClose,
}: {
notification: LoaderNotification;
onClose?: () => void;
}) {
const { t } = useTranslation(["common"]);
return (
<Link
to={notificationLink(notification)}
className={styles.item}
data-testid="notification-item"
onClick={onClose}
>
<NotificationImage notification={notification}>
{!notification.seen ? <div className={styles.unseenDot} /> : null}
</NotificationImage>
<div className={styles.itemHeader}>
{t(`common:notifications.text.${notification.type}`, notification.meta)}
</div>
<div className={styles.timestamp}>
{formatDistance(
databaseTimestampToDate(notification.createdAt),
new Date(),
{
addSuffix: true,
},
)}
</div>
</Link>
);
}
export function NotificationItemDivider() {
return <hr className={styles.itemDivider} />;
}
function NotificationImage({
notification,
children,
}: {
notification: LoaderNotification;
children: React.ReactNode;
}) {
if (notification.pictureUrl) {
return (
<div className={styles.imageContainer}>
{children}
<img
src={notification.pictureUrl}
alt="Notification"
className={styles.itemImage}
width={124}
height={124}
/>
</div>
);
}
return (
<div className={styles.imageContainer}>
{children}
<Image
path={navIconUrl(notificationNavIcon(notification.type))}
width={24}
height={24}
alt=""
/>
</div>
);
}