Add: - components/Notification/ - hooks/use-notification-store.tsx.back Fix: - app.config.js - app/(application)/(user)/_layout.tsx - app/(application)/(user)/home.tsx - app/(application)/(user)/test-notifications.tsx - app/(application)/_layout.tsx - app/_layout.tsx - components/_Icon/IconComponent.tsx - components/_Icon/IconPlus.tsx - components/_ShareComponent/NotificationInitializer.tsx - context/AuthContext.tsx - hooks/use-notification-store.tsx - ios/HIPMIBadungConnect/Info.plist - screens/Home/HeaderBell.tsx - service/api-device-token.ts - service/api-notifications.ts ### No Issue
113 lines
3.0 KiB
Plaintext
113 lines
3.0 KiB
Plaintext
// hooks/useNotificationStore.ts
|
|
import { apiGetNotificationsById } from "@/service/api-notifications";
|
|
import { createContext, ReactNode, useContext, useState, useEffect } from "react";
|
|
import { useAuth } from "./use-auth";
|
|
|
|
type AppNotification = {
|
|
id: string;
|
|
title: string;
|
|
body: string;
|
|
data?: Record<string, string>;
|
|
isRead: boolean;
|
|
timestamp: number;
|
|
type: "notification" | "trigger";
|
|
appId?: string;
|
|
kategoriApp?:
|
|
| "JOB"
|
|
| "VOTING"
|
|
| "EVENT"
|
|
| "DONASI"
|
|
| "INVESTASI"
|
|
| "COLLABORATION"
|
|
| "FORUM"
|
|
| "ACCESS";
|
|
};
|
|
|
|
type NotificationContextType = {
|
|
notifications: AppNotification[];
|
|
unreadCount: number;
|
|
addNotification: (
|
|
notif: Omit<AppNotification, "id" | "isRead" | "timestamp">
|
|
) => void;
|
|
markAsRead: (id: string) => void;
|
|
syncUnreadCount: () => Promise<void>;
|
|
};
|
|
|
|
const NotificationContext = createContext<NotificationContextType>({
|
|
notifications: [],
|
|
unreadCount: 0,
|
|
addNotification: () => {},
|
|
markAsRead: () => {},
|
|
syncUnreadCount: async () => {},
|
|
});
|
|
|
|
export const NotificationProvider = ({ children }: { children: ReactNode }) => {
|
|
const {user} = useAuth()
|
|
const [notifications, setNotifications] = useState<AppNotification[]>([]);
|
|
const [unreadCount, setUnreadCount] = useState(0);
|
|
|
|
// 🔔 Sync unread count dari backend saat provider di-mount
|
|
useEffect(() => {
|
|
const fetchUnreadCount = async () => {
|
|
try {
|
|
const count = await apiGetNotificationsById({
|
|
id: user?.id as any,
|
|
category: "count-as-unread"
|
|
}); // ← harus return number
|
|
const result = count.data
|
|
setUnreadCount(result);
|
|
} catch (error) {
|
|
console.erro("⚠️ Gagal fetch unread count:", error);
|
|
}
|
|
};
|
|
|
|
fetchUnreadCount();
|
|
}, []);
|
|
|
|
const addNotification = (
|
|
notif: Omit<AppNotification, "id" | "isRead" | "timestamp">
|
|
) => {
|
|
setNotifications((prev) => [
|
|
{
|
|
...notif,
|
|
id: Date.now().toString(),
|
|
isRead: false,
|
|
timestamp: Date.now(),
|
|
},
|
|
...prev,
|
|
]);
|
|
// Tambahkan ke unread count (untuk notifikasi foreground)
|
|
setUnreadCount((prev) => prev + 1);
|
|
};
|
|
|
|
const markAsRead = (id: string) => {
|
|
setNotifications((prev) =>
|
|
prev.map((n) => (n.id === id ? { ...n, isRead: true } : n))
|
|
);
|
|
// Kurangi unread count
|
|
setUnreadCount((prev) => Math.max(0, prev - 1));
|
|
};
|
|
|
|
const syncUnreadCount = async () => {
|
|
try {
|
|
const count = await apiGetNotificationsById({
|
|
id: user?.id as any,
|
|
category: "count-as-unread"
|
|
}); // ← harus return number
|
|
const result = count.data
|
|
setUnreadCount(result);
|
|
} catch (error) {
|
|
console.warn("⚠️ Gagal sync unread count:", error);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<NotificationContext.Provider
|
|
value={{ notifications, unreadCount, addNotification, markAsRead, syncUnreadCount }}
|
|
>
|
|
{children}
|
|
</NotificationContext.Provider>
|
|
);
|
|
};
|
|
|
|
export const useNotificationStore = () => useContext(NotificationContext); |