This commit is contained in:
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user