Thanks to visit codestin.com
Credit goes to github.com

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)