Skip to content

Commit b29e1e0

Browse files
committed
Show notification status
1 parent 19d980a commit b29e1e0

13 files changed

+353
-89
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CreateCollection({
2+
name: "notification_statuses"
3+
})
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CreateIndex({
2+
name: "notification_status_by_user",
3+
source: Collection("notification_statuses"),
4+
unique: true,
5+
terms: [{
6+
field: ["data", "user"]
7+
}]
8+
})
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CreateCollection({
2+
name: 'notification_statuses'
3+
})
4+
5+
/**
6+
# "data": {
7+
# "userId": String,
8+
# "count": Number,
9+
# "timestamps: {
10+
# "createdAt": Time,
11+
# "updatedAt": Time,
12+
# }
13+
**/
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CreateIndex({
2+
name: 'notification_status_by_user',
3+
source: Collection('notification_statuses'),
4+
unique: true,
5+
terms: [
6+
{
7+
field: ['data', 'user'],
8+
},
9+
],
10+
})

src/adapters/fauna/shell.mjs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,28 @@ const client = new faunadb.Client({
99
})
1010

1111
async function main() {
12+
const userId = '291732880734814720'
13+
const userRef = q.Ref(q.Collection('users'), userId)
1214
const response = await client.query(
13-
q.Do(
14-
q.Map(
15-
q.Paginate(q.Documents(q.Collection('notifications'))),
16-
(goalUpdate) => q.Delete(goalUpdate)
17-
),
18-
q.Map(q.Paginate(q.Documents(q.Collection('activities'))), (goalUpdate) =>
19-
q.Delete(goalUpdate)
20-
)
15+
// q.If(
16+
// q.Exists(q.Match(q.Index('notification_status_by_user'), userRef)),
17+
// q.Subtract(
18+
// q.Count(q.Match(q.Index('all_notifications_by_user'), userRef)),
19+
// q.Select(
20+
// ['data', 'count'],
21+
// q.Get(q.Match(q.Index('notification_status_by_user'), userRef)),
22+
// 0
23+
// )
24+
// ),
25+
// q.Count(
26+
// q.Match(
27+
// q.Index('all_notifications_by_user'),
28+
// q.Ref(q.Collection('users'), userId)
29+
// )
30+
// )
31+
// )
32+
q.Map(q.Paginate(q.Documents(q.Collection('notifications'))), (userRef) =>
33+
q.Delete(userRef)
2134
)
2235
)
2336
console.log(JSON.stringify(response, null, 2))

src/components/AppNavBar.tsx

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,10 @@ import { User } from 'src/pages/members'
77
import { Toggle } from '@/ui'
88
import { Gear, RocketLaunch, SignOut, UserCircle } from 'phosphor-react'
99
import { useState } from 'react'
10+
import { useQuery } from 'react-query'
11+
import classNames from 'classnames'
1012

1113
const navbarItems = [
12-
{
13-
title: 'Home',
14-
value: 'home',
15-
href: '/',
16-
},
1714
{
1815
title: 'Members',
1916
value: 'members',
@@ -57,6 +54,12 @@ export default function AppNavBar() {
5754
]
5855
: []),
5956
]
57+
const { data: notificationsCount } = useQuery(
58+
'api/fauna/has-notifications',
59+
() => {
60+
return fetch(`/api/fauna/has-notifications`).then((res) => res.json())
61+
}
62+
)
6063

6164
return (
6265
<NavBar
@@ -100,21 +103,33 @@ export default function AppNavBar() {
100103
<A href="/notifications">
101104
<button className="bg-white p-1 rounded-full text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
102105
<span className="sr-only">View notifications</span>
103-
<svg
104-
className="h-6 w-6"
105-
xmlns="http://www.w3.org/2000/svg"
106-
fill="none"
107-
viewBox="0 0 24 24"
108-
stroke="currentColor"
109-
aria-hidden="true"
110-
>
111-
<path
112-
strokeLinecap="round"
113-
strokeLinejoin="round"
114-
strokeWidth="2"
115-
d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"
116-
/>
117-
</svg>
106+
<span className="inline-block relative">
107+
<div className="border border-gray-300 rounded-full p-1">
108+
<svg
109+
className={classNames(
110+
'h-6 w-6',
111+
notificationsCount > 0 && 'text-gray-900'
112+
)}
113+
xmlns="http://www.w3.org/2000/svg"
114+
fill="none"
115+
viewBox="0 0 24 24"
116+
stroke="currentColor"
117+
aria-hidden="true"
118+
>
119+
<path
120+
strokeLinecap="round"
121+
strokeLinejoin="round"
122+
strokeWidth="2"
123+
d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"
124+
/>
125+
</svg>
126+
</div>
127+
{notificationsCount > 0 && (
128+
<span className="absolute -top-1 -right-1 block h-4 w-4 rounded-full ring-2 ring-white bg-red-400 text-white text-xs dark:text-white">
129+
{notificationsCount}
130+
</span>
131+
)}
132+
</span>
118133
</button>
119134
</A>
120135

src/pages/api/fauna/add-comment.ts

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -62,23 +62,41 @@ const FaunaCreateHandler: NextApiHandler = async (
6262
},
6363
},
6464
}),
65-
notificationDoc: q.Create(q.Collection('notifications'), {
66-
data: {
67-
user: q.Select(
68-
['data', 'postedBy'],
69-
q.Get(q.Ref(q.Collection('goal_updates'), updateId))
70-
),
71-
activity: q.Ref(
72-
q.Collection('activities'),
73-
q.Select(['ref', 'id'], q.Var('activityDoc'))
65+
notificationDoc: q.If(
66+
q.And(
67+
q.Equals(
68+
q.Select(['data', 'type'], q.Var('activityDoc')),
69+
'COMMENTED_ON_UPDATE'
7470
),
75-
isRead: false,
76-
timestamps: {
77-
createdAt: q.Now(),
78-
updatedAt: q.Now(),
71+
q.Not(
72+
q.Equals(
73+
q.Select(
74+
['data', 'postedBy', 'id'],
75+
q.Get(q.Ref(q.Collection('goal_updates'), updateId))
76+
),
77+
q.Select(['data', 'user', 'id'], q.Var('activityDoc'))
78+
)
79+
)
80+
),
81+
q.Create(q.Collection('notifications'), {
82+
data: {
83+
user: q.Select(
84+
['data', 'postedBy'],
85+
q.Get(q.Ref(q.Collection('goal_updates'), updateId))
86+
),
87+
activity: q.Ref(
88+
q.Collection('activities'),
89+
q.Select(['ref', 'id'], q.Var('activityDoc'))
90+
),
91+
isRead: false,
92+
timestamps: {
93+
createdAt: q.Now(),
94+
updatedAt: q.Now(),
95+
},
7996
},
80-
},
81-
}),
97+
}),
98+
null
99+
),
82100
},
83101
{}
84102
)
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next'
2+
import { getSession } from 'next-auth/client'
3+
4+
import faunadb from 'faunadb'
5+
import { User } from 'src/pages/members'
6+
const q = faunadb.query
7+
const isProduction = process.env.NODE_ENV === 'production'
8+
const client = new faunadb.Client({
9+
secret: process.env.FAUNADB_SECRET ?? 'secret',
10+
scheme: isProduction ? 'https' : 'http',
11+
domain: isProduction ? 'db.fauna.com' : 'localhost',
12+
...(isProduction ? {} : { port: 8443 }),
13+
})
14+
15+
const FaunaCreateHandler: NextApiHandler = async (
16+
req: NextApiRequest,
17+
res: NextApiResponse
18+
) => {
19+
const session = await getSession({ req })
20+
21+
if (!session) {
22+
return res.status(401).json({ message: 'Unauthorized' })
23+
}
24+
25+
const userId = (session.user as User).id
26+
const userRef = q.Ref(q.Collection('users'), userId)
27+
try {
28+
const response = await client.query(
29+
q.If(
30+
q.Exists(q.Match(q.Index('notification_status_by_user'), userRef)),
31+
q.Subtract(
32+
q.Count(q.Match(q.Index('all_notifications_by_user'), userRef)),
33+
q.Select(
34+
['data', 'count'],
35+
q.Get(q.Match(q.Index('notification_status_by_user'), userRef)),
36+
0
37+
)
38+
),
39+
q.Count(
40+
q.Match(
41+
q.Index('all_notifications_by_user'),
42+
q.Ref(q.Collection('users'), userId)
43+
)
44+
)
45+
)
46+
)
47+
res.status(200).json(response)
48+
} catch (error) {
49+
console.error(error)
50+
console.error({ msg: error.message })
51+
res.status(500).json({ message: error.message })
52+
}
53+
}
54+
55+
export default FaunaCreateHandler

src/pages/api/fauna/toggle-comment-like.ts

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -78,23 +78,41 @@ const FaunaCreateHandler: NextApiHandler = async (
7878
},
7979
},
8080
}),
81-
notificationDoc: q.Create(q.Collection('notifications'), {
82-
data: {
83-
user: q.Select(
84-
['data', 'postedBy'],
85-
q.Get(q.Ref(q.Collection('update_comments'), commentId))
86-
),
87-
activity: q.Ref(
88-
q.Collection('activities'),
89-
q.Select(['ref', 'id'], q.Var('activityDoc'))
81+
notificationDoc: q.If(
82+
q.And(
83+
q.Equals(
84+
q.Select(['data', 'type'], q.Var('activityDoc')),
85+
'LIKED_COMMENT'
9086
),
91-
isRead: false,
92-
timestamps: {
93-
createdAt: q.Now(),
94-
updatedAt: q.Now(),
87+
q.Not(
88+
q.Equals(
89+
q.Select(
90+
['data', 'postedBy', 'id'],
91+
q.Get(q.Ref(q.Collection('update_comments'), commentId))
92+
),
93+
q.Select(['data', 'user', 'id'], q.Var('activityDoc'))
94+
)
95+
)
96+
),
97+
q.Create(q.Collection('notifications'), {
98+
data: {
99+
user: q.Select(
100+
['data', 'postedBy'],
101+
q.Get(q.Ref(q.Collection('update_comments'), commentId))
102+
),
103+
activity: q.Ref(
104+
q.Collection('activities'),
105+
q.Select(['ref', 'id'], q.Var('activityDoc'))
106+
),
107+
isRead: false,
108+
timestamps: {
109+
createdAt: q.Now(),
110+
updatedAt: q.Now(),
111+
},
95112
},
96-
},
97-
}),
113+
}),
114+
null
115+
),
98116
},
99117
{}
100118
)

src/pages/api/fauna/toggle-follow.ts

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -85,20 +85,26 @@ const FaunaCreateHandler: NextApiHandler = async (
8585
},
8686
},
8787
}),
88-
notificationDoc: q.Create(q.Collection('notifications'), {
89-
data: {
90-
user: q.Ref(q.Collection('users'), userId),
91-
activity: q.Ref(
92-
q.Collection('activities'),
93-
q.Select(['ref', 'id'], q.Var('activityDoc'))
94-
),
95-
isRead: false,
96-
timestamps: {
97-
createdAt: q.Now(),
98-
updatedAt: q.Now(),
88+
notificationDoc: q.If(
89+
q.Equals(
90+
q.Select(['data', 'type'], q.Var('activityDoc')),
91+
'FOLLOWED'
92+
),
93+
q.Create(q.Collection('notifications'), {
94+
data: {
95+
user: q.Ref(q.Collection('users'), userId),
96+
activity: q.Ref(
97+
q.Collection('activities'),
98+
q.Select(['ref', 'id'], q.Var('activityDoc'))
99+
),
100+
timestamps: {
101+
createdAt: q.Now(),
102+
updatedAt: q.Now(),
103+
},
99104
},
100-
},
101-
}),
105+
}),
106+
null
107+
),
102108
},
103109
{}
104110
)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy