Files
TREK/client/src/components/Notifications/NotificationDayList.tsx
T
Maurice aecef03090 feat(notifications): a tile per kind, the list cut into days, and clear actions
Every notification gets a tile in the colour of what it is about (a trip, a
message, a booking, packing, a to-do, Vacay, a collection, shared photos, a
tour, an update or an alert) with the sender's face on its corner, the page
and the bell's panel group the list under Today, Yesterday, the weekday or
the date, and answering or following a notification is a proper button.
The server's UTC timestamps are read as UTC for the grouping and the time.
2026-10-24 17:31:46 +02:00

57 lines
2.0 KiB
TypeScript

import React, { useMemo } from 'react';
import { useTranslation } from '../../i18n';
import type { InAppNotification } from '../../store/inAppNotificationStore';
import InAppNotificationItem from './InAppNotificationItem';
import { groupByDay } from './notificationModel';
interface NotificationDayListProps {
notifications: InAppNotification[];
/** Closes the bell's panel after a notification led somewhere. */
onClose?: () => void;
/** The bell's panel: headings stick to its top and the days need no cards of their own. */
compact?: boolean;
}
/**
* The notifications cut into days, each under its heading (Today, Yesterday,
* a weekday, then the date). On the page every day is a card of its own; in
* the bell's panel the headings stay at the top while the day scrolls by.
*/
export default function NotificationDayList({
notifications,
onClose,
compact = false,
}: NotificationDayListProps): React.ReactElement {
const { locale } = useTranslation();
const groups = useMemo(() => groupByDay(notifications, locale), [notifications, locale]);
return (
<div className={compact ? '' : 'flex flex-col gap-6'}>
{groups.map((group) => (
<section key={group.key} aria-label={group.label}>
<h2
className={
compact
? 'sticky top-0 z-10 bg-surface-card px-4 pb-1.5 pt-3 text-caption font-semibold text-content-muted'
: 'mb-2 px-1 text-caption font-semibold text-content-muted'
}
>
{group.label}
</h2>
<div
className={
compact
? 'divide-y divide-edge-secondary'
: 'divide-y divide-edge-secondary overflow-hidden rounded-2xl border border-edge bg-surface-card'
}
>
{group.items.map((n) => (
<InAppNotificationItem key={n.id} notification={n} onClose={onClose} />
))}
</div>
</section>
))}
</div>
);
}