diff --git a/app/(application)/(user)/notifications/index.tsx b/app/(application)/(user)/notifications/index.tsx
index b10ee39..2e2c57b 100644
--- a/app/(application)/(user)/notifications/index.tsx
+++ b/app/(application)/(user)/notifications/index.tsx
@@ -1,9 +1,11 @@
-import ScreenNotification from "@/screens/Notification/ScreenNotification";
+import ScreenNotification from "@/screens/Notification/ScreenNotification_V2";
+import ScreenNotification_V1 from "@/screens/Notification/ScreenNotification_V1";
export default function Notification() {
return (
<>
+ {/* */}
>
);
}
diff --git a/app/(application)/admin/notification/index.tsx b/app/(application)/admin/notification/index.tsx
index 9875bd5..cd76188 100644
--- a/app/(application)/admin/notification/index.tsx
+++ b/app/(application)/admin/notification/index.tsx
@@ -1,213 +1,10 @@
-import {
- AlertDefaultSystem,
- BackButton,
- BaseBox,
- DrawerCustom,
- MenuDrawerDynamicGrid,
- NewWrapper,
- ScrollableCustom,
- StackCustom,
- TextCustom,
-} from "@/components";
-import { IconPlus } from "@/components/_Icon";
-import { IconDot } from "@/components/_Icon/IconComponent";
-import ListSkeletonComponent from "@/components/_ShareComponent/ListSkeletonComponent";
-import NoDataText from "@/components/_ShareComponent/NoDataText";
-import { AccentColor, MainColor } from "@/constants/color-palet";
-import { ICON_SIZE_SMALL } from "@/constants/constans-value";
-import { useAuth } from "@/hooks/use-auth";
-import { useNotificationStore } from "@/hooks/use-notification-store";
-import { apiGetNotificationsById } from "@/service/api-notifications";
-import { listOfcategoriesAppNotification } from "@/types/type-notification-category";
-import { formatChatTime } from "@/utils/formatChatTime";
-import { Ionicons } from "@expo/vector-icons";
-import { router, Stack, useFocusEffect } from "expo-router";
-import _ from "lodash";
-import { useCallback, useState } from "react";
-import { RefreshControl, View } from "react-native";
-
-const selectedCategory = (value: string) => {
- const category = listOfcategoriesAppNotification.find(
- (c) => c.value === value
- );
- return category?.label;
-};
-
-const BoxNotification = ({
- data,
- activeCategory,
-}: {
- data: any;
- activeCategory: string | null;
-}) => {
- const { markAsRead } = useNotificationStore();
- return (
- <>
- {
- console.log(
- "Notification >",
- selectedCategory(activeCategory as string)
- );
- router.push(data.deepLink);
- markAsRead(data.id);
- }}
- >
-
-
- {data.title}
-
-
- {data.pesan}
-
-
- {formatChatTime(data.createdAt)}
-
-
-
- >
- );
-};
+import Admin_ScreenNotification from "@/screens/Admin/Notification-Admin/ScreenNotificationAdmin";
+import Admin_ScreenNotification2 from "@/screens/Admin/Notification-Admin/ScreenNotificationAdmin2";
export default function AdminNotification() {
- const { user } = useAuth();
- const [activeCategory, setActiveCategory] = useState("event");
- const [listData, setListData] = useState([]);
- const [refreshing, setRefreshing] = useState(false);
- const [loading, setLoading] = useState(false);
- const [openDrawer, setOpenDrawer] = useState(false);
-
- const { markAsReadAll } = useNotificationStore();
-
- const handlePress = (item: any) => {
- setActiveCategory(item.value);
- // tambahkan logika lain seperti filter dsb.
- };
-
- useFocusEffect(
- useCallback(() => {
- fecthData();
- }, [activeCategory])
- );
-
- const fecthData = async () => {
- try {
- setLoading(true);
- const response = await apiGetNotificationsById({
- id: user?.id as any,
- category: activeCategory as any,
- });
-
- if (response.success) {
- setListData(response.data);
- } else {
- setListData([]);
- }
- } catch (error) {
- console.log("Error Notification", error);
- } finally {
- setLoading(false);
- }
- };
-
- const onRefresh = () => {
- setRefreshing(true);
- fecthData();
- setRefreshing(false);
- };
-
return (
<>
- ,
- headerRight: () => (
- setOpenDrawer(true)}
- />
- ),
- }}
- />
-
- ({
- id: i,
- label: e.label,
- value: e.value,
- }))}
- onButtonPress={handlePress}
- activeId={activeCategory as string}
- />
- }
- refreshControl={
-
- }
- >
- {loading ? (
-
- ) : _.isEmpty(listData) ? (
-
- ) : (
- listData.map((e, i) => (
-
-
-
- ))
- )}
-
-
- setOpenDrawer(false)}
- height={"auto"}
- >
-
- ),
- path: "",
- },
- ]}
- onPressItem={(item: any) => {
- console.log("Item", item.value);
- if (item.value === "read-all") {
- AlertDefaultSystem({
- title: "Tandai Semua Dibaca",
- message:
- "Apakah Anda yakin ingin menandai semua notifikasi dibaca?",
- textLeft: "Batal",
- textRight: "Ya",
- onPressRight: () => {
- markAsReadAll(user?.id as any);
- const data = _.cloneDeep(listData);
- data.forEach((e) => {
- e.isRead = true;
- });
- setListData(data);
- onRefresh();
- setOpenDrawer(false);
- },
- });
- }
- }}
- />
-
+
>
);
}
diff --git a/docs/prompt-for-qwen-code.md b/docs/prompt-for-qwen-code.md
index 6cca10e..d3d30d8 100644
--- a/docs/prompt-for-qwen-code.md
+++ b/docs/prompt-for-qwen-code.md
@@ -1,8 +1,8 @@
-File utama: screens/Job/ScreenArchive2.tsx
-Fun fecth: apiJobGetByStatus
-File fetch: service/api-client/api-job.ts
+File utama: screens/Admin/Notification-Admin/ScreenNotificationAdmin2.tsx
+Fun fecth: apiGetNotificationsById
+File fetch: service/api-notifications.ts
File komponen wrapper: components/_ShareComponent/NewWrapper.tsx
Terapkan pagination pada file "File utama"
diff --git a/screens/Admin/Notification-Admin/ScreenNotificationAdmin.tsx b/screens/Admin/Notification-Admin/ScreenNotificationAdmin.tsx
new file mode 100644
index 0000000..5a36598
--- /dev/null
+++ b/screens/Admin/Notification-Admin/ScreenNotificationAdmin.tsx
@@ -0,0 +1,213 @@
+import {
+ AlertDefaultSystem,
+ BackButton,
+ BaseBox,
+ DrawerCustom,
+ MenuDrawerDynamicGrid,
+ NewWrapper,
+ ScrollableCustom,
+ StackCustom,
+ TextCustom,
+} from "@/components";
+import { IconPlus } from "@/components/_Icon";
+import { IconDot } from "@/components/_Icon/IconComponent";
+import ListSkeletonComponent from "@/components/_ShareComponent/ListSkeletonComponent";
+import NoDataText from "@/components/_ShareComponent/NoDataText";
+import { AccentColor, MainColor } from "@/constants/color-palet";
+import { ICON_SIZE_SMALL } from "@/constants/constans-value";
+import { useAuth } from "@/hooks/use-auth";
+import { useNotificationStore } from "@/hooks/use-notification-store";
+import { apiGetNotificationsById } from "@/service/api-notifications";
+import { listOfcategoriesAppNotification } from "@/types/type-notification-category";
+import { formatChatTime } from "@/utils/formatChatTime";
+import { Ionicons } from "@expo/vector-icons";
+import { router, Stack, useFocusEffect } from "expo-router";
+import _ from "lodash";
+import { useCallback, useState } from "react";
+import { RefreshControl, View } from "react-native";
+
+const selectedCategory = (value: string) => {
+ const category = listOfcategoriesAppNotification.find(
+ (c) => c.value === value
+ );
+ return category?.label;
+};
+
+const BoxNotification = ({
+ data,
+ activeCategory,
+}: {
+ data: any;
+ activeCategory: string | null;
+}) => {
+ const { markAsRead } = useNotificationStore();
+ return (
+ <>
+ {
+ console.log(
+ "Notification >",
+ selectedCategory(activeCategory as string)
+ );
+ router.push(data.deepLink);
+ markAsRead(data.id);
+ }}
+ >
+
+
+ {data.title}
+
+
+ {data.pesan}
+
+
+ {formatChatTime(data.createdAt)}
+
+
+
+ >
+ );
+};
+
+export default function Admin_ScreenNotification() {
+ const { user } = useAuth();
+ const [activeCategory, setActiveCategory] = useState("event");
+ const [listData, setListData] = useState([]);
+ const [refreshing, setRefreshing] = useState(false);
+ const [loading, setLoading] = useState(false);
+ const [openDrawer, setOpenDrawer] = useState(false);
+
+ const { markAsReadAll } = useNotificationStore();
+
+ const handlePress = (item: any) => {
+ setActiveCategory(item.value);
+ // tambahkan logika lain seperti filter dsb.
+ };
+
+ useFocusEffect(
+ useCallback(() => {
+ fecthData();
+ }, [activeCategory])
+ );
+
+ const fecthData = async () => {
+ try {
+ setLoading(true);
+ const response = await apiGetNotificationsById({
+ id: user?.id as any,
+ category: activeCategory as any,
+ });
+
+ if (response.success) {
+ setListData(response.data);
+ } else {
+ setListData([]);
+ }
+ } catch (error) {
+ console.log("Error Notification", error);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ const onRefresh = () => {
+ setRefreshing(true);
+ fecthData();
+ setRefreshing(false);
+ };
+
+ return (
+ <>
+ ,
+ headerRight: () => (
+ setOpenDrawer(true)}
+ />
+ ),
+ }}
+ />
+
+ ({
+ id: i,
+ label: e.label,
+ value: e.value,
+ }))}
+ onButtonPress={handlePress}
+ activeId={activeCategory as string}
+ />
+ }
+ refreshControl={
+
+ }
+ >
+ {loading ? (
+
+ ) : _.isEmpty(listData) ? (
+
+ ) : (
+ listData.map((e, i) => (
+
+
+
+ ))
+ )}
+
+
+ setOpenDrawer(false)}
+ height={"auto"}
+ >
+
+ ),
+ path: "",
+ },
+ ]}
+ onPressItem={(item: any) => {
+ console.log("Item", item.value);
+ if (item.value === "read-all") {
+ AlertDefaultSystem({
+ title: "Tandai Semua Dibaca",
+ message:
+ "Apakah Anda yakin ingin menandai semua notifikasi dibaca?",
+ textLeft: "Batal",
+ textRight: "Ya",
+ onPressRight: () => {
+ markAsReadAll(user?.id as any);
+ const data = _.cloneDeep(listData);
+ data.forEach((e) => {
+ e.isRead = true;
+ });
+ setListData(data);
+ onRefresh();
+ setOpenDrawer(false);
+ },
+ });
+ }
+ }}
+ />
+
+ >
+ );
+}
diff --git a/screens/Admin/Notification-Admin/ScreenNotificationAdmin2.tsx b/screens/Admin/Notification-Admin/ScreenNotificationAdmin2.tsx
new file mode 100644
index 0000000..26816b5
--- /dev/null
+++ b/screens/Admin/Notification-Admin/ScreenNotificationAdmin2.tsx
@@ -0,0 +1,222 @@
+import {
+ AlertDefaultSystem,
+ BackButton,
+ BaseBox,
+ DrawerCustom,
+ MenuDrawerDynamicGrid,
+ NewWrapper,
+ ScrollableCustom,
+ StackCustom,
+ TextCustom,
+} from "@/components";
+import { IconPlus } from "@/components/_Icon";
+import { IconDot } from "@/components/_Icon/IconComponent";
+import { AccentColor, MainColor } from "@/constants/color-palet";
+import { ICON_SIZE_SMALL } from "@/constants/constans-value";
+import { createPaginationComponents } from "@/helpers/paginationHelpers";
+import { useAuth } from "@/hooks/use-auth";
+import { useNotificationStore } from "@/hooks/use-notification-store";
+import { usePagination } from "@/hooks/use-pagination";
+import { apiGetNotificationsById } from "@/service/api-notifications";
+import { listOfcategoriesAppNotification } from "@/types/type-notification-category";
+import { formatChatTime } from "@/utils/formatChatTime";
+import { Ionicons } from "@expo/vector-icons";
+import { router, Stack, useFocusEffect } from "expo-router";
+import _ from "lodash";
+import { useState } from "react";
+import { RefreshControl, View } from "react-native";
+
+const PAGE_SIZE = 10;
+
+const selectedCategory = (value: string) => {
+ const category = listOfcategoriesAppNotification.find(
+ (c) => c.value === value,
+ );
+ return category?.label;
+};
+
+const BoxNotification = ({
+ data,
+ activeCategory,
+ setListData,
+}: {
+ data: any;
+ activeCategory: string | null;
+ setListData: (data: any) => void;
+}) => {
+ const { markAsRead } = useNotificationStore();
+ return (
+ <>
+ {
+ console.log(
+ "Notification >",
+ selectedCategory(activeCategory as string),
+ );
+ router.push(data.deepLink);
+ markAsRead(data.id);
+ setListData((prev: any) =>
+ prev.map((item: any) =>
+ item.id === data.id ? { ...item, isRead: true } : item,
+ ),
+ );
+ }}
+ >
+
+
+ {data.title}
+
+
+ {data.pesan}
+
+
+ {formatChatTime(data.createdAt)}
+
+
+
+ >
+ );
+};
+
+export default function Admin_ScreenNotification2() {
+ const { user } = useAuth();
+ const [activeCategory, setActiveCategory] = useState("event");
+ const [openDrawer, setOpenDrawer] = useState(false);
+
+ const { markAsReadAll } = useNotificationStore();
+
+ // Setup pagination
+ const pagination = usePagination({
+ fetchFunction: async (page) => {
+ if (!user?.id) return { data: [] };
+
+ return await apiGetNotificationsById({
+ id: user?.id as any,
+ category: activeCategory as any,
+ page: String(page),
+ });
+ },
+ pageSize: PAGE_SIZE,
+ dependencies: [user?.id, activeCategory],
+ onError: (error) =>
+ console.error("[ERROR] Fetch admin notifications:", error),
+ });
+
+ // Generate komponen
+ const { ListEmptyComponent, ListFooterComponent } =
+ createPaginationComponents({
+ loading: pagination.loading,
+ refreshing: pagination.refreshing,
+ listData: pagination.listData,
+ emptyMessage: "Belum ada notifikasi",
+ skeletonCount: 5,
+ skeletonHeight: 100,
+ });
+
+ // Render item notification
+ const renderNotificationItem = ({ item }: { item: any }) => (
+
+
+
+ );
+
+ const handlePress = (item: any) => {
+ setActiveCategory(item.value);
+ // Reset pagination saat kategori berubah
+ pagination.reset();
+ };
+
+ return (
+ <>
+ ,
+ headerRight: () => (
+ setOpenDrawer(true)}
+ />
+ ),
+ }}
+ />
+
+ ({
+ id: i,
+ label: e.label,
+ value: e.value,
+ }))}
+ onButtonPress={handlePress}
+ activeId={activeCategory as string}
+ />
+ }
+ listData={pagination.listData}
+ renderItem={renderNotificationItem}
+ refreshControl={
+
+ }
+ onEndReached={pagination.loadMore}
+ ListEmptyComponent={ListEmptyComponent}
+ ListFooterComponent={ListFooterComponent}
+ />
+
+ setOpenDrawer(false)}
+ height={"auto"}
+ >
+
+ ),
+ path: "",
+ },
+ ]}
+ onPressItem={(item: any) => {
+ console.log("Item", item.value);
+ if (item.value === "read-all") {
+ AlertDefaultSystem({
+ title: "Tandai Semua Dibaca",
+ message:
+ "Apakah Anda yakin ingin menandai semua notifikasi dibaca?",
+ textLeft: "Batal",
+ textRight: "Ya",
+ onPressRight: () => {
+ markAsReadAll(user?.id as any);
+ const data = _.cloneDeep(pagination.listData);
+ data.forEach((e) => {
+ e.isRead = true;
+ });
+ pagination.setListData(data);
+ pagination.onRefresh();
+ setOpenDrawer(false);
+ },
+ });
+ }
+ }}
+ />
+
+ >
+ );
+}
diff --git a/screens/Job/MainViewStatus2.tsx b/screens/Job/MainViewStatus2.tsx
index 13385e3..c53724a 100644
--- a/screens/Job/MainViewStatus2.tsx
+++ b/screens/Job/MainViewStatus2.tsx
@@ -1,22 +1,16 @@
/* eslint-disable react-hooks/exhaustive-deps */
-import {
- BaseBox,
- ScrollableCustom,
- TextCustom,
- ViewWrapper,
-} from "@/components";
+import { BaseBox, ScrollableCustom, TextCustom } from "@/components";
+import NewWrapper from "@/components/_ShareComponent/NewWrapper";
import { MainColor } from "@/constants/color-palet";
+import { PAGINATION_DEFAULT_TAKE } from "@/constants/constans-value";
import { createPaginationComponents } from "@/helpers/paginationHelpers";
import { useAuth } from "@/hooks/use-auth";
import { usePagination } from "@/hooks/use-pagination";
import { dummyMasterStatus } from "@/lib/dummy-data/_master/status";
import { apiJobGetByStatus } from "@/service/api-client/api-job";
import { useFocusEffect, useLocalSearchParams } from "expo-router";
-import _ from "lodash";
-import { useState } from "react";
+import { useCallback, useState } from "react";
import { RefreshControl, View } from "react-native";
-import NewWrapper from "@/components/_ShareComponent/NewWrapper";
-import { PAGINATION_DEFAULT_TAKE } from "@/constants/constans-value";
export default function Job_MainViewStatus2() {
const { user } = useAuth();
@@ -24,7 +18,7 @@ export default function Job_MainViewStatus2() {
console.log("STATUS", status);
const [activeCategory, setActiveCategory] = useState(
- status || "publish"
+ status || "publish",
);
// Setup pagination
@@ -44,14 +38,15 @@ export default function Job_MainViewStatus2() {
});
// Generate komponen
- const { ListEmptyComponent, ListFooterComponent } = createPaginationComponents({
- loading: pagination.loading,
- refreshing: pagination.refreshing,
- listData: pagination.listData,
- emptyMessage: `Tidak ada data ${activeCategory}`,
- skeletonCount: PAGINATION_DEFAULT_TAKE,
- skeletonHeight: 100,
- });
+ const { ListEmptyComponent, ListFooterComponent } =
+ createPaginationComponents({
+ loading: pagination.loading,
+ refreshing: pagination.refreshing,
+ listData: pagination.listData,
+ emptyMessage: `Tidak ada data ${activeCategory}`,
+ skeletonCount: PAGINATION_DEFAULT_TAKE,
+ skeletonHeight: 100,
+ });
// Render item job
const renderJobItem = ({ item }: { item: any }) => (
@@ -67,6 +62,14 @@ export default function Job_MainViewStatus2() {
);
+ // useFocusEffect(
+ // useCallback(() => {
+ // // Reset and load first page when category changes
+ // pagination.reset();
+ // // pagination.onRefresh();
+ // }, [activeCategory]),
+ // );
+
const handlePress = (item: any) => {
setActiveCategory(item.value);
// Reset pagination saat kategori berubah
@@ -87,11 +90,7 @@ export default function Job_MainViewStatus2() {
return (
- {scrollComponent}
-
- }
+ headerComponent={{scrollComponent}}
listData={pagination.listData}
renderItem={renderJobItem}
refreshControl={
diff --git a/screens/Notification/ScreenNotification_V1.tsx b/screens/Notification/ScreenNotification_V1.tsx
new file mode 100644
index 0000000..6b11ec6
--- /dev/null
+++ b/screens/Notification/ScreenNotification_V1.tsx
@@ -0,0 +1,321 @@
+/* eslint-disable react-hooks/exhaustive-deps */
+import {
+ AlertDefaultSystem,
+ BackButton,
+ BaseBox,
+ DrawerCustom,
+ LoaderCustom,
+ MenuDrawerDynamicGrid,
+ NewWrapper,
+ ScrollableCustom,
+ StackCustom,
+ TextCustom,
+} from "@/components";
+import { IconDot } from "@/components/_Icon/IconComponent";
+import ListSkeletonComponent from "@/components/_ShareComponent/ListSkeletonComponent";
+import NoDataText from "@/components/_ShareComponent/NoDataText";
+import { AccentColor, MainColor } from "@/constants/color-palet";
+import { ICON_SIZE_SMALL } from "@/constants/constans-value";
+import { useAuth } from "@/hooks/use-auth";
+import { useNotificationStore } from "@/hooks/use-notification-store";
+import { apiGetNotificationsById } from "@/service/api-notifications";
+import { listOfcategoriesAppNotification } from "@/types/type-notification-category";
+import { formatChatTime } from "@/utils/formatChatTime";
+import { Ionicons } from "@expo/vector-icons";
+import {
+ router,
+ Stack,
+ useFocusEffect,
+ useLocalSearchParams,
+} from "expo-router";
+import _ from "lodash";
+import { useCallback, useEffect, useState } from "react";
+import { RefreshControl, View } from "react-native";
+
+const selectedCategory = (value: string) => {
+ const category = listOfcategoriesAppNotification.find(
+ (c) => c.value === value,
+ );
+ return category?.label;
+};
+
+const fixPath = ({
+ deepLink,
+ categoryApp,
+}: {
+ deepLink: string;
+ categoryApp: string;
+}) => {
+ if (categoryApp === "OTHER") {
+ return deepLink;
+ }
+
+ const separator = deepLink.includes("?") ? "&" : "?";
+
+ const fixedPath = `${deepLink}${separator}from=notifications&category=${_.lowerCase(
+ categoryApp,
+ )}`;
+
+ console.log("Fix Path", fixedPath);
+
+ return fixedPath;
+};
+
+const BoxNotification = ({
+ data,
+ activeCategory,
+ setListData,
+}: {
+ data: any;
+ activeCategory: string | null;
+ setListData: (data: any) => void;
+}) => {
+ // console.log("DATA NOTIFICATION", JSON.stringify(data, null, 2));
+ const { markAsRead } = useNotificationStore();
+ return (
+ <>
+ {
+ // console.log(
+ // "Notification >",
+ // selectedCategory(activeCategory as string)
+ // );
+ const newPath = fixPath({
+ deepLink: data.deepLink,
+ categoryApp: data.kategoriApp,
+ });
+
+ router.navigate(newPath as any);
+ selectedCategory(activeCategory as string);
+
+ if (!data.isRead) {
+ markAsRead(data.id);
+ const updatedData = {
+ ...data,
+ isRead: true,
+ };
+
+ console.log("Updated Data", updatedData);
+ setListData((prev: any) =>
+ prev.map((item: any) =>
+ item.id === data.id ? updatedData : item,
+ ),
+ );
+ }
+ }}
+ >
+
+
+ {data.title}
+
+
+ {data.pesan}
+
+
+ {formatChatTime(data.createdAt)}
+
+
+
+ >
+ );
+};
+
+export default function ScreenNotification_V1() {
+ const { user } = useAuth();
+ const { category } = useLocalSearchParams<{ category?: string }>();
+ const [activeCategory, setActiveCategory] = useState(
+ category || "event",
+ );
+ const [listData, setListData] = useState([]);
+ const [refreshing, setRefreshing] = useState(false);
+ const [loading, setLoading] = useState(false);
+ const [loadingMore, setLoadingMore] = useState(false);
+ const [page, setPage] = useState(1);
+ const [hasMore, setHasMore] = useState(true);
+ const [openDrawer, setOpenDrawer] = useState(false);
+
+ const { markAsReadAll } = useNotificationStore();
+
+ const handlePress = (item: any) => {
+ setActiveCategory(item.value);
+ // Reset pagination saat kategori berubah
+ setListData([]);
+ setPage(1);
+ setHasMore(true);
+ };
+
+ // useFocusEffect(
+ // useCallback(() => {
+ // fecthData(1, true);
+ // }, [activeCategory])
+ // );
+
+ useEffect(() => {
+ fecthData(1, true);
+ }, [activeCategory]);
+
+ const fecthData = async (pageNum: number, clear: boolean = false) => {
+ if (pageNum === 1 && !clear) return; // Hindari duplicate call untuk page 1
+
+ try {
+ if (pageNum === 1) {
+ setLoading(true);
+ } else {
+ setLoadingMore(true);
+ }
+
+ const response = await apiGetNotificationsById({
+ id: user?.id as any,
+ category: activeCategory as any,
+ page: String(pageNum),
+ });
+
+ if (response.success) {
+ if (clear || pageNum === 1) {
+ setListData(response.data);
+ } else {
+ setListData((prev) => [...prev, ...response.data]);
+ }
+
+ // Jika data yang dikembalikan kurang dari ukuran halaman, maka tidak ada halaman berikutnya
+ setHasMore(response.data.length >= 10); // Asumsikan ukuran halaman 10
+ } else {
+ if (pageNum === 1) {
+ setListData([]);
+ }
+ }
+ } catch (error) {
+ console.log("Error Notification", error);
+ if (pageNum === 1) {
+ setListData([]);
+ }
+ } finally {
+ if (pageNum === 1) {
+ setLoading(false);
+ } else {
+ setLoadingMore(false);
+ }
+ }
+ };
+
+ const onRefresh = async () => {
+ setRefreshing(true);
+ await fecthData(1, true);
+ setRefreshing(false);
+ };
+
+ const loadMore = () => {
+ if (!loadingMore && hasMore) {
+ const nextPage = page + 1;
+ setPage(nextPage);
+ fecthData(nextPage, false);
+ }
+ };
+
+ return (
+ <>
+ ,
+ headerRight: () => (
+ setOpenDrawer(true)}
+ />
+ ),
+ }}
+ />
+
+ ({
+ id: i,
+ label: e.label,
+ value: e.value,
+ }))}
+ onButtonPress={handlePress}
+ activeId={activeCategory as string}
+ />
+ }
+ listData={listData}
+ renderItem={({ item }) => (
+
+
+
+ )}
+ refreshControl={
+
+ }
+ onEndReached={loadMore}
+ // onEndReachedThreshold={0.1}
+ ListEmptyComponent={
+ loading ? (
+
+ ) : (
+
+ )
+ }
+ ListFooterComponent={
+ loadingMore ? (
+
+
+
+ ) : null
+ }
+ />
+
+ setOpenDrawer(false)}
+ height={"auto"}
+ >
+
+ ),
+ path: "",
+ },
+ ]}
+ onPressItem={(item: any) => {
+ console.log("Item", item.value);
+ if (item.value === "read-all") {
+ AlertDefaultSystem({
+ title: "Tandai Semua Dibaca",
+ message:
+ "Apakah Anda yakin ingin menandai semua notifikasi dibaca?",
+ textLeft: "Batal",
+ textRight: "Ya",
+ onPressRight: () => {
+ markAsReadAll(user?.id as any);
+ const data = _.cloneDeep(listData);
+ data.forEach((e) => {
+ e.isRead = true;
+ });
+ setListData(data);
+ onRefresh();
+ setOpenDrawer(false);
+ },
+ });
+ }
+ }}
+ />
+
+ >
+ );
+}
diff --git a/screens/Notification/ScreenNotification.tsx b/screens/Notification/ScreenNotification_V2.tsx
similarity index 79%
rename from screens/Notification/ScreenNotification.tsx
rename to screens/Notification/ScreenNotification_V2.tsx
index e8dfcd7..f4f12cb 100644
--- a/screens/Notification/ScreenNotification.tsx
+++ b/screens/Notification/ScreenNotification_V2.tsx
@@ -11,26 +11,32 @@ import {
TextCustom,
} from "@/components";
import { IconDot } from "@/components/_Icon/IconComponent";
-import ListSkeletonComponent from "@/components/_ShareComponent/ListSkeletonComponent";
-import NoDataText from "@/components/_ShareComponent/NoDataText";
import { AccentColor, MainColor } from "@/constants/color-palet";
-import { ICON_SIZE_SMALL, PAGINATION_DEFAULT_TAKE } from "@/constants/constans-value";
+import {
+ ICON_SIZE_SMALL,
+ PAGINATION_DEFAULT_TAKE,
+} from "@/constants/constans-value";
+import { createPaginationComponents } from "@/helpers/paginationHelpers";
import { useAuth } from "@/hooks/use-auth";
import { useNotificationStore } from "@/hooks/use-notification-store";
import { usePagination } from "@/hooks/use-pagination";
-import { createPaginationComponents } from "@/helpers/paginationHelpers";
import { apiGetNotificationsById } from "@/service/api-notifications";
import { listOfcategoriesAppNotification } from "@/types/type-notification-category";
import { formatChatTime } from "@/utils/formatChatTime";
import { Ionicons } from "@expo/vector-icons";
-import { router, Stack, useFocusEffect, useLocalSearchParams } from "expo-router";
+import {
+ router,
+ Stack,
+ useFocusEffect,
+ useLocalSearchParams,
+} from "expo-router";
import _ from "lodash";
import { useCallback, useState } from "react";
import { RefreshControl, View } from "react-native";
const selectedCategory = (value: string) => {
const category = listOfcategoriesAppNotification.find(
- (c) => c.value === value
+ (c) => c.value === value,
);
return category?.label;
};
@@ -49,7 +55,7 @@ const fixPath = ({
const separator = deepLink.includes("?") ? "&" : "?";
const fixedPath = `${deepLink}${separator}from=notifications&category=${_.lowerCase(
- categoryApp
+ categoryApp,
)}`;
console.log("Fix Path", fixedPath);
@@ -60,21 +66,18 @@ const fixPath = ({
const BoxNotification = ({
data,
activeCategory,
+ setListData,
}: {
data: any;
activeCategory: string | null;
+ setListData: (data: any) => void;
}) => {
- // console.log("DATA NOTIFICATION", JSON.stringify(data, null, 2));
const { markAsRead } = useNotificationStore();
return (
<>
{
- // console.log(
- // "Notification >",
- // selectedCategory(activeCategory as string)
- // );
const newPath = fixPath({
deepLink: data.deepLink,
categoryApp: data.kategoriApp,
@@ -85,6 +88,11 @@ const BoxNotification = ({
if (!data.isRead) {
markAsRead(data.id);
+ setListData((prev: any) =>
+ prev.map((item: any) =>
+ item.id === data.id ? { ...item, isRead: true } : item,
+ ),
+ );
}
}}
>
@@ -108,7 +116,7 @@ export default function ScreenNotification() {
const { user } = useAuth();
const { category } = useLocalSearchParams<{ category?: string }>();
const [activeCategory, setActiveCategory] = useState(
- category || "event"
+ category || "event",
);
const [openDrawer, setOpenDrawer] = useState(false);
@@ -117,6 +125,8 @@ export default function ScreenNotification() {
// Initialize pagination for notifications
const pagination = usePagination({
fetchFunction: async (page) => {
+ if (!user?.id) return { data: [] };
+
return await apiGetNotificationsById({
id: user?.id as string,
category: activeCategory as any,
@@ -127,20 +137,19 @@ export default function ScreenNotification() {
dependencies: [activeCategory],
});
- useFocusEffect(
- useCallback(() => {
- // Reset and load first page when category changes
- pagination.reset();
- pagination.onRefresh();
- }, [activeCategory])
- );
+ // useFocusEffect(
+ // useCallback(() => {
+ // // Reset and load first page when category changes
+ // pagination.reset();
+ // pagination.onRefresh();
+ // }, [activeCategory]),
+ // );
const handlePress = (item: any) => {
- console.log("ITEM", item.value);
setActiveCategory(item.value);
// Reset and load first page when category changes
- pagination.reset();
- pagination.onRefresh();
+ // pagination.reset();
+ // pagination.onRefresh();
};
// Render individual notification item
@@ -149,24 +158,26 @@ export default function ScreenNotification() {
);
// Generate pagination components using helper
- const { ListEmptyComponent, ListFooterComponent } = createPaginationComponents({
- loading: pagination.loading,
- refreshing: pagination.refreshing,
- listData: pagination.listData,
- isInitialLoad: pagination.isInitialLoad,
- emptyMessage: "Belum ada notifikasi",
- skeletonCount: 5,
- skeletonHeight: 100,
- });
+ const { ListEmptyComponent, ListFooterComponent } =
+ createPaginationComponents({
+ loading: pagination.loading,
+ refreshing: pagination.refreshing,
+ listData: pagination.listData,
+ isInitialLoad: pagination.isInitialLoad,
+ emptyMessage: "Belum ada notifikasi",
+ skeletonCount: 5,
+ skeletonHeight: 100,
+ });
return (
<>
- ,
@@ -180,6 +191,7 @@ export default function ScreenNotification() {
/>
({
@@ -225,7 +237,7 @@ export default function ScreenNotification() {
},
]}
onPressItem={(item: any) => {
- console.log("Item", item.value);
+ // console.log("Item", item.value);
if (item.value === "read-all") {
AlertDefaultSystem({
title: "Tandai Semua Dibaca",
@@ -234,9 +246,13 @@ export default function ScreenNotification() {
textLeft: "Batal",
textRight: "Ya",
onPressRight: () => {
- markAsReadAll(user?.id as any);
// Reset and refresh data after marking all as read
- pagination.reset();
+ markAsReadAll(user?.id as any);
+ const data = _.cloneDeep(pagination.listData);
+ data.forEach((e) => {
+ e.isRead = true;
+ });
+ pagination.setListData(data);
pagination.onRefresh();
setOpenDrawer(false);
},