-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathNotification.tsx
More file actions
106 lines (98 loc) · 2.82 KB
/
Copy pathNotification.tsx
File metadata and controls
106 lines (98 loc) · 2.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import React, { useState, useEffect } from 'react';
import { useId } from '@react-aria/utils';
import moment from 'moment';
import Popup from 'reactjs-popup';
import cn from 'classnames';
import styles from './notification.module.css';
import 'reactjs-popup/dist/index.css';
import { notificationBadge, notificationBell } from '../../icons/other';
import { Ride } from '../../types';
import DisplayMessage from './Message';
type Message = {
key: number;
time: Date;
title: string;
body: string;
read: boolean;
};
type NotificationData = {
title: string;
body: string;
ride: Ride;
sentTime: string;
};
const Notification = () => {
const [newMessages, setNewMessages] = useState<Message[]>([]);
const [messages, setMessages] = useState<Message[]>([]);
const [notify, setNotify] = useState(false);
const popupId = useId();
const markAsRead = (key: number) => {
setMessages((prevMessages) =>
prevMessages.map((message) =>
message.key === key ? { ...message, read: true } : message
)
);
};
useEffect(() => {
navigator.serviceWorker.addEventListener('message', (event) => {
const { body, ride, sentTime, title }: NotificationData = event.data;
const newMsg = {
key: newMessages.length + 1,
time: new Date(sentTime),
title,
body,
day: ride.startTime,
read: false,
};
setNewMessages([newMsg, ...newMessages]);
setNotify(true);
});
}, []);
const mapMessages = (msgs: Message[]) =>
msgs.map((message) => (
<DisplayMessage {...message} key={message.key} markAsRead={markAsRead} />
));
useEffect(() => {
const element = document.getElementById(popupId);
element?.removeAttribute('aria-describedby');
}, []);
return (
<Popup
trigger={
<button id={popupId} className={styles.bell}>
<img src={notificationBell} alt="Notifications" />
{notify && (
<img
src={notificationBadge}
className={styles.badge}
alt="notification badge"
/>
)}
</button>
}
onClose={() => {
setMessages([...newMessages, ...messages]);
setNewMessages([]);
setNotify(false);
}}
position={['bottom right']}
contentStyle={{
margin: '10px',
width: '333px',
}}
>
<div className={styles.content}>
{newMessages.length === 0 || (
<h6 className={cn(styles.heading, styles.divider)}>
You have {newMessages.length} new message
{newMessages.length === 1 || 's'}
</h6>
)}
{newMessages.length === 0 || mapMessages(newMessages)}
<h6 className={styles.heading}>Message History</h6>
{mapMessages(messages)}
</div>
</Popup>
);
};
export default Notification;