Skip to content

Commit

Permalink
feat(client): improve notification system
Browse files Browse the repository at this point in the history
  • Loading branch information
lareii committed Sep 19, 2024
1 parent 7de0db7 commit 780619c
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 46 deletions.
8 changes: 2 additions & 6 deletions client/components/app/Navbar/Collapsed.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Home, Compass, Bell, Menu, User, Settings } from 'lucide-react';
import Item from '@/components/app/Navbar/Item';
import Dropdown from '@/components/app/Navbar/Dropdown';
import PostModal from '@/components/app/Navbar/PostModal';
import NotificationButton from '@/components/app/Navbar/Notification';
import { Sheet, SheetContent, SheetTrigger } from '@/components/ui/sheet';
import { Button } from '@/components/ui/button';
import { useAuthStore } from '@/stores/auth';
Expand Down Expand Up @@ -65,12 +66,7 @@ export default function Collapsed({ router, pathname }) {
icon={Compass}
label='keşfet'
/>
<Item
pathname={pathname}
href='/app/notifications'
icon={Bell}
label='bildirimler'
/>
<NotificationButton pathname={pathname} />
</div>
<div className='mt-5 mb-3 font-medium text-xs text-muted-foreground'>
yaratıcılık
Expand Down
33 changes: 3 additions & 30 deletions client/components/app/Navbar/Item.jsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,19 @@
import Link from 'next/link';
import { useState, useEffect } from 'react';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { getUnreadNotificationsCount } from '@/lib/api/me';

export default function Item({ pathname, href, icon: Icon, label }) {
const isActive =
pathname === href || (href !== '/app' && pathname.startsWith(href));

const [unreadNotificationsCount, setUnreadNotificationsCount] = useState(0);

useEffect(
() => {
const fetchUnreadNotificationsCount = async () => {
const response = await getUnreadNotificationsCount();
if (response) {
setUnreadNotificationsCount(response.data.unreads);
}
};

fetchUnreadNotificationsCount();
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[]
);

return (
<Button
variant={isActive ? 'secondary' : 'ghost'}
className='justify-start'
asChild
>
<Link href={href} className='flex gap-5'>
<Icon className=' h-4 w-4' />
{href === '/app/notifications' && unreadNotificationsCount ? (
<div className='flex justify-between items-center grow'>
{label}
<Badge>{unreadNotificationsCount}</Badge>
</div>
) : (
label
)}
<Link href={href}>
<Icon className='mr-5 h-4 w-4' />
{label}
</Link>
</Button>
);
Expand Down
47 changes: 47 additions & 0 deletions client/components/app/Navbar/Notification.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import Link from 'next/link';
import { useEffect } from 'react';
import { Bell } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { getUnreadNotificationsCount } from '@/lib/api/me';
import { useNotificationStore } from '@/stores/notification';

export default function NotificationButton({ pathname }) {
const isActive = pathname === '/app/notifications';

const notificationCount = useNotificationStore(
(state) => state.notificationCount
);
const setNotificationCount = useNotificationStore(
(state) => state.setNotificationCount
);

useEffect(() => {
const fetchUnreadNotificationsCount = async () => {
const response = await getUnreadNotificationsCount();
if (!response) return;

setNotificationCount(response.data.unreads);
};

fetchUnreadNotificationsCount();
}, [setNotificationCount]);

return (
<Button
variant={isActive ? 'secondary' : 'ghost'}
className='justify-start'
asChild
>
<Link href='/app/notifications'>
<Bell className='mr-5 h-4 w-4' />
<div className='flex items-center justify-between grow'>
bildirimler
{notificationCount > 0 && (
<Badge className='rounded-md'>{notificationCount}</Badge>
)}
</div>
</Link>
</Button>
);
}
10 changes: 3 additions & 7 deletions client/components/app/Navbar/Uncollapsed.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import Link from 'next/link';
import Image from 'next/image';
import { Home, Compass, Bell } from 'lucide-react';
import { Home, Compass } from 'lucide-react';
import Item from '@/components/app/Navbar/Item';
import Dropdown from '@/components/app/Navbar/Dropdown';
import PostModal from '@/components/app/Navbar/PostModal';
import NotificationButton from '@/components/app/Navbar/Notification';

export default function Uncollapsed({ router, pathname }) {
return (
Expand Down Expand Up @@ -34,12 +35,7 @@ export default function Uncollapsed({ router, pathname }) {
icon={Compass}
label='keşfet'
/>
<Item
pathname={pathname}
href='/app/notifications'
icon={Bell}
label='bildirimler'
/>
<NotificationButton pathname={pathname} />
</div>
<div className='mt-5 mb-3 font-medium text-xs text-muted-foreground'>
yaratıcılık
Expand Down
4 changes: 2 additions & 2 deletions client/components/app/Notification/Skeleton.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ export default function NotificationSkeleton() {
</div>
<Skeleton className='mt-3 w-1/2 h-4'></Skeleton>
</div>
)
}
);
}
15 changes: 14 additions & 1 deletion client/components/app/Notification/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import UserInfo from '@/components/app/User/Info';
import { Button } from '@/components/ui/button';
import { useToast } from '@/components/ui/use-toast';
import { updateNotification } from '@/lib/api/me';
import { useNotificationStore } from '@/stores/notification';

function typeContent(notification) {
switch (notification.type) {
Expand Down Expand Up @@ -33,6 +34,12 @@ function typeContent(notification) {

export default function Notification({ notification }) {
const [isRead, setIsRead] = useState(notification.read);
const notificationCount = useNotificationStore(
(state) => state.notificationCount
);
const setNotificationCount = useNotificationStore(
(state) => state.setNotificationCount
);
const { toast } = useToast();

const markAsRead = async ({ read }) => {
Expand All @@ -51,6 +58,7 @@ export default function Notification({ notification }) {
}

setIsRead(!read);
setNotificationCount(!read ? notificationCount - 1 : notificationCount + 1);
};

return (
Expand All @@ -69,7 +77,12 @@ export default function Notification({ notification }) {
<Mail className='w-4 h-4' />
)}
</Button>
<Button variant='ghost' size='icon' asChild>
<Button
variant='ghost'
size='icon'
onClick={() => markAsRead({ read: isRead })}
asChild
>
<Link href={typeContent(notification).href}>
<SquareArrowOutUpRight className='w-4 h-4' />
</Link>
Expand Down
6 changes: 6 additions & 0 deletions client/stores/notification/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { create } from 'zustand';

export const useNotificationStore = create((set) => ({
notificationCount: 0,
setNotificationCount: (notificationCount) => set({ notificationCount }),
}));

0 comments on commit 780619c

Please sign in to comment.