feat: tambah fitur tandai semua notifikasi dibaca dengan modal konfirmasi
This commit is contained in:
@@ -1,8 +1,9 @@
|
|||||||
import AppHeader from "@/components/AppHeader";
|
import AppHeader from "@/components/AppHeader";
|
||||||
|
import ModalConfirmation from "@/components/ModalConfirmation";
|
||||||
import SkeletonTwoItem from "@/components/skeletonTwoItem";
|
import SkeletonTwoItem from "@/components/skeletonTwoItem";
|
||||||
import Text from "@/components/Text";
|
import Text from "@/components/Text";
|
||||||
import Styles from "@/constants/Styles";
|
import Styles from "@/constants/Styles";
|
||||||
import { apiGetNotification, apiReadOneNotification } from "@/lib/api";
|
import { apiGetNotification, apiReadAllNotification, apiReadOneNotification } from "@/lib/api";
|
||||||
import { setUpdateNotification } from "@/lib/notificationSlice";
|
import { setUpdateNotification } from "@/lib/notificationSlice";
|
||||||
import { pushToPage } from "@/lib/pushToPage";
|
import { pushToPage } from "@/lib/pushToPage";
|
||||||
import { useAuthSession } from "@/providers/AuthProvider";
|
import { useAuthSession } from "@/providers/AuthProvider";
|
||||||
@@ -32,7 +33,7 @@ type ListRow = HeaderRow | ItemRow
|
|||||||
function getNotifStyle(category: string): { icon: keyof typeof Feather.glyphMap; color: string } {
|
function getNotifStyle(category: string): { icon: keyof typeof Feather.glyphMap; color: string } {
|
||||||
if (category === 'announcement') return { icon: 'volume-2', color: '#3B82F6' }
|
if (category === 'announcement') return { icon: 'volume-2', color: '#3B82F6' }
|
||||||
if (category === 'project') return { icon: 'activity', color: '#10B981' }
|
if (category === 'project') return { icon: 'activity', color: '#10B981' }
|
||||||
if (category.includes('/task')) return { icon: 'check-circle', color: '#8B5CF6' }
|
if (category.includes('/task')) return { icon: 'clipboard', color: '#8B5CF6' }
|
||||||
if (category === 'division') return { icon: 'users', color: '#3B82F6' }
|
if (category === 'division') return { icon: 'users', color: '#3B82F6' }
|
||||||
if (category.includes('/discussion') || category === 'discussion-general') return { icon: 'message-square', color: '#06B6D4' }
|
if (category.includes('/discussion') || category === 'discussion-general') return { icon: 'message-square', color: '#06B6D4' }
|
||||||
if (category.includes('/calendar')) return { icon: 'calendar', color: '#F59E0B' }
|
if (category.includes('/calendar')) return { icon: 'calendar', color: '#F59E0B' }
|
||||||
@@ -48,6 +49,8 @@ export default function Notification() {
|
|||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
const updateNotification = useSelector((state: any) => state.notificationUpdate)
|
const updateNotification = useSelector((state: any) => state.notificationUpdate)
|
||||||
const [refreshing, setRefreshing] = useState(false)
|
const [refreshing, setRefreshing] = useState(false)
|
||||||
|
const [markingAll, setMarkingAll] = useState(false)
|
||||||
|
const [showConfirm, setShowConfirm] = useState(false)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data,
|
data,
|
||||||
@@ -106,6 +109,22 @@ export default function Notification() {
|
|||||||
setRefreshing(false)
|
setRefreshing(false)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const hasUnread = flatData.some((item) => !item.isRead)
|
||||||
|
|
||||||
|
async function handleReadAll() {
|
||||||
|
try {
|
||||||
|
setMarkingAll(true)
|
||||||
|
const hasil = await decryptToken(String(token?.current))
|
||||||
|
await apiReadAllNotification({ user: hasil })
|
||||||
|
await queryClient.invalidateQueries({ queryKey: ['notifications'] })
|
||||||
|
dispatch(setUpdateNotification(!updateNotification))
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
} finally {
|
||||||
|
setMarkingAll(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function handleReadNotification(id: string, category: string, idContent: string) {
|
async function handleReadNotification(id: string, category: string, idContent: string) {
|
||||||
try {
|
try {
|
||||||
const hasil = await decryptToken(String(token?.current))
|
const hasil = await decryptToken(String(token?.current))
|
||||||
@@ -123,11 +142,39 @@ export default function Notification() {
|
|||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
options={{
|
options={{
|
||||||
header: () => (
|
header: () => (
|
||||||
<AppHeader title="Notifikasi" showBack={true} onPressLeft={() => router.back()} />
|
<AppHeader
|
||||||
|
title="Notifikasi"
|
||||||
|
showBack={true}
|
||||||
|
onPressLeft={() => router.back()}
|
||||||
|
right={
|
||||||
|
hasUnread ? (
|
||||||
|
<Pressable
|
||||||
|
onPress={() => setShowConfirm(true)}
|
||||||
|
disabled={markingAll}
|
||||||
|
style={{ opacity: markingAll ? 0.5 : 1, padding: 4 }}
|
||||||
|
>
|
||||||
|
<Feather name="check-square" size={22} color="white" />
|
||||||
|
</Pressable>
|
||||||
|
) : undefined
|
||||||
|
}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<ModalConfirmation
|
||||||
|
visible={showConfirm}
|
||||||
|
title="Tandai Semua Dibaca"
|
||||||
|
message="Semua notifikasi akan ditandai sebagai telah dibaca."
|
||||||
|
confirmText="Tandai"
|
||||||
|
cancelText="Batal"
|
||||||
|
onConfirm={() => {
|
||||||
|
setShowConfirm(false)
|
||||||
|
handleReadAll()
|
||||||
|
}}
|
||||||
|
onCancel={() => setShowConfirm(false)}
|
||||||
|
/>
|
||||||
|
|
||||||
<View style={[Styles.flex1, Styles.ph15, { paddingTop: 10 }]}>
|
<View style={[Styles.flex1, Styles.ph15, { paddingTop: 10 }]}>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
[0, 1, 2, 3, 4].map((_, i) => <SkeletonTwoItem key={i} />)
|
[0, 1, 2, 3, 4].map((_, i) => <SkeletonTwoItem key={i} />)
|
||||||
|
|||||||
@@ -859,6 +859,11 @@ export const apiReadOneNotification = async (data: { user: string, id: string })
|
|||||||
return response.data;
|
return response.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const apiReadAllNotification = async (data: { user: string }) => {
|
||||||
|
const response = await api.post(`/mobile/home/notification`, data)
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
export const apiGetVersion = async () => {
|
export const apiGetVersion = async () => {
|
||||||
const response = await api.get(`mobile/version`);
|
const response = await api.get(`mobile/version`);
|
||||||
return response.data;
|
return response.data;
|
||||||
|
|||||||
Reference in New Issue
Block a user