diff --git a/components/NotificationsTable.js b/components/NotificationsTable.js
index f6883c82b..a267e23ee 100644
--- a/components/NotificationsTable.js
+++ b/components/NotificationsTable.js
@@ -1,7 +1,8 @@
/* globals DOMPurify, marked: false */
-import { useState, useEffect } from 'react'
+import { useState, useEffect, useCallback } from 'react'
import upperFirst from 'lodash/upperFirst'
+import { debounce } from 'lodash'
import Table from './Table'
import Collapse from './Collapse'
import { formatDateTime, prettyId } from '../lib/utils'
@@ -11,12 +12,37 @@ export default function NotificationsTable({
numUnviewed,
markViewed,
markAllViewed,
+ setSearchTerm,
+ searchTerm,
}) {
+ const [immediateSearchTerm, setImmediateSearchTerm] = useState(null)
+
+ const delaySearch = useCallback(
+ debounce((term) => setSearchTerm(term), 300),
+ []
+ )
+
+ useEffect(() => {
+ if (searchTerm !== null) return
+ setImmediateSearchTerm(null)
+ }, [searchTerm])
+
if (!messages) return null
const headingContent = (
- <>
- Message Details
+
+
+
+ {
+ setImmediateSearchTerm(e.target.value)
+ delaySearch(e.target.value)
+ }}
+ />
+
- >
+
)
return (
diff --git a/pages/notifications.js b/pages/notifications.js
index 494eb13e6..e79986559 100644
--- a/pages/notifications.js
+++ b/pages/notifications.js
@@ -25,6 +25,7 @@ export default function Notifications({ appContext }) {
const [page, setPage] = useState(1)
const [error, setError] = useState(null)
const [shouldRefresh, setShouldRefresh] = useState(false)
+ const [searchTerm, setSearchTerm] = useState(null)
const router = useRouter()
const { setUnreadNotificationCount, decrementNotificationCount } = useContext(UserContext)
const { setBannerHidden } = appContext
@@ -93,6 +94,7 @@ export default function Notifications({ appContext }) {
setToEmail(router.query.email || user.profile.preferredEmail || user.profile.emails[0])
setPage(1)
+ setSearchTerm(null)
}, [user?.id, router.isReady, router.query.email])
useEffect(() => {
@@ -147,11 +149,13 @@ export default function Notifications({ appContext }) {
if (!accessToken || !toEmail) return
setError(null)
+ const cleanSearchTerm = searchTerm?.trim()
api
.get(
'/messages',
{
+ ...(cleanSearchTerm?.length && { subject: `${cleanSearchTerm}.*` }),
to: toEmail,
limit: pageSize,
offset: pageSize * (page - 1),
@@ -168,6 +172,34 @@ export default function Notifications({ appContext }) {
})
}, [accessToken, toEmail, page, shouldRefresh])
+ useEffect(() => {
+ const cleanSearchTerm = searchTerm?.trim()
+ if (!cleanSearchTerm?.length) {
+ if (searchTerm === '') {
+ // search term cleared
+ setPage(1)
+ setShouldRefresh((refresh) => !refresh)
+ }
+ return
+ }
+ api
+ .get(
+ '/messages',
+ { subject: `${cleanSearchTerm}.*`, to: toEmail, limit: pageSize },
+
+ { accessToken }
+ )
+ .then((apiRes) => {
+ setMessages(apiRes.messages ?? [])
+ setCount(apiRes.count ?? 0)
+ setPage(1)
+ })
+ .catch((apiError) => {
+ setError(apiError)
+ setMessages(null)
+ })
+ }, [searchTerm])
+
return (
@@ -231,6 +263,8 @@ export default function Notifications({ appContext }) {
numUnviewed={unviewedCounts?.[toEmail] ?? 0}
markViewed={markViewed}
markAllViewed={markAllViewed}
+ setSearchTerm={setSearchTerm}
+ searchTerm={searchTerm}
/>