fix notification badge initialization
continuous-integration/drone/push Build is passing

This commit is contained in:
AmirReza Jamali
2026-07-11 14:56:05 +03:30
parent 4051cb156c
commit 37aa916ad5
2 changed files with 25 additions and 28 deletions
@@ -8,19 +8,21 @@ import {
import { useUser } from "@/contexts";
import Modal from "@/components/ui/modal";
import Status from "@/components/ui/Status";
import { useMarkNotificationAsSeen } from "@/hooks/queries/useNotificationQueries";
import {
useGetMyNotifications,
useMarkNotificationAsSeen,
} from "@/hooks/queries/useNotificationQueries";
import { useIsMobile } from "@/hooks/use-mobile";
import { TNotificationDetailsResponse } from "@/lib/api/types/NotificationHistory";
import { cn, sanitizeHtmlWithStyles } from "@/lib/utils";
import { capitalize, unixToDate } from "@/utils/shared";
import Link from "next/link";
import { useMemo, useState } from "react";
import { useEffect, useMemo, useState } from "react";
import { BellIcon } from "./icons";
import NotificationList from "./notification-list";
export function Notification() {
const [isOpen, setIsOpen] = useState(false);
const [isDotVisible, setIsDotVisible] = useState(true);
const [unreadNotificationCount, setUnreadNotificationCount] =
useState<number>(0);
const [isModalOpen, setIsModalOpen] = useState(false);
@@ -28,8 +30,15 @@ export function Notification() {
useState<TNotificationDetailsResponse | null>(null);
const { mutate } = useMarkNotificationAsSeen();
const { data: unreadNotifications, isLoading: isLoadingNotifications } =
useGetMyNotifications({ seen: false });
const isMobile = useIsMobile();
const { user } = useUser();
useEffect(() => {
setUnreadNotificationCount(unreadNotifications?.data.length ?? 0);
}, [unreadNotifications]);
const notificationHistoryHref = useMemo(() => {
if (!user?.id) return "/notification-history";
@@ -47,20 +56,14 @@ export function Notification() {
return (
<>
<Dropdown
isOpen={isOpen}
setIsOpen={(open) => {
setIsOpen(open);
if (setIsDotVisible) setIsDotVisible(false);
}}
>
<Dropdown isOpen={isOpen} setIsOpen={setIsOpen}>
<DropdownTrigger
className="shadow-theme-xs grid size-12 place-items-center rounded-full border border-stroke/70 bg-white/75 text-dark outline-none backdrop-blur-md transition-colors hover:text-primary focus-visible:border-primary focus-visible:text-primary dark:border-dark-3 dark:bg-dark-2/75 dark:text-white dark:focus-visible:border-primary"
aria-label="View Notifications"
>
<span className="relative">
<BellIcon />
{isDotVisible && unreadNotificationCount > 0 && (
{unreadNotificationCount > 0 && (
<span
className={cn(
"absolute -right-1.5 -top-1.5 z-1 grid min-w-[18px] place-items-center rounded-full bg-gradient-to-br from-rose-500 to-red-600 px-1 text-[10px] font-bold leading-none text-white shadow-[0_2px_8px_rgba(239,68,68,0.55)] ring-2 ring-white dark:ring-dark-2",
@@ -88,7 +91,8 @@ export function Notification() {
</div>
<NotificationList
setUnreadNotificationCount={setUnreadNotificationCount}
notifications={unreadNotifications?.data}
isLoading={isLoadingNotifications}
onNotificationClick={handleNotificationClick}
/>
@@ -118,7 +122,7 @@ export function Notification() {
<div className="pointer-events-none absolute -bottom-12 -left-6 size-28 rounded-full bg-white/10 blur-md" />
<div className="relative flex items-start gap-4">
<span className="grid size-12 shrink-0 place-items-center rounded-2xl bg-white/20 text-white shadow-theme-sm ring-1 ring-white/30 backdrop-blur-sm">
<span className="shadow-theme-sm grid size-12 shrink-0 place-items-center rounded-2xl bg-white/20 text-white ring-1 ring-white/30 backdrop-blur-sm">
<BellIcon />
</span>
@@ -183,7 +187,7 @@ export function Notification() {
<button
type="button"
onClick={() => setIsModalOpen(false)}
className="rounded-xl bg-gradient-to-br from-primary to-blue-700 px-5 py-2 text-sm font-semibold text-white shadow-theme-sm transition-opacity hover:opacity-90"
className="shadow-theme-sm rounded-xl bg-gradient-to-br from-primary to-blue-700 px-5 py-2 text-sm font-semibold text-white transition-opacity hover:opacity-90"
>
Got it
</button>
@@ -2,36 +2,29 @@
import Loading from "@/components/loading";
import IsVisible from "@/components/ui/IsVisible";
import { useGetMyNotifications } from "@/hooks/queries/useNotificationQueries";
import { TNotificationDetailsResponse } from "@/lib/api/types/NotificationHistory";
import { truncateString } from "@/utils/shared";
import { Dispatch, SetStateAction, useEffect } from "react";
interface IProps {
setUnreadNotificationCount: Dispatch<SetStateAction<number>>;
notifications?: TNotificationDetailsResponse[];
isLoading: boolean;
onNotificationClick: (notification: TNotificationDetailsResponse) => void;
}
const NotificationList = ({
setUnreadNotificationCount,
notifications,
isLoading,
onNotificationClick,
}: IProps) => {
const { data, isLoading } = useGetMyNotifications({ seen: false });
useEffect(() => {
setUnreadNotificationCount(data?.data.length ?? 0);
}, [data, isLoading]);
if (isLoading)
return (
<Loading className="min-h-48 flex-none justify-center p-6" />
);
return <Loading className="min-h-48 flex-none justify-center p-6" />;
return (
<ul className="mb-3 max-h-[23rem] space-y-1.5 overflow-y-auto">
<IsVisible condition={data?.data.length === 0}>
<IsVisible condition={notifications?.length === 0}>
<h2 className="cursor-default ps-2">No new notification</h2>
</IsVisible>
{data?.data.map((notification) => (
{notifications?.map((notification) => (
<li
role="menuitem"
key={notification.id}