import GuideOverlay from "@/components/GuideOverlay";
import InputSearch from "@/components/inputSearch";
import Skeleton from "@/components/skeleton";
import Text from '@/components/Text';
import Styles from "@/constants/Styles";
import { apiGetAnnouncement } from "@/lib/api";
import { GUIDE_ANNOUNCEMENT } from "@/lib/guideSteps";
import { useGuide } from "@/lib/useGuide";
import { useAuthSession } from "@/providers/AuthProvider";
import { useTheme } from "@/providers/ThemeProvider";
import { MaterialIcons } from "@expo/vector-icons";
import { useInfiniteQuery } from "@tanstack/react-query";
import { router } from "expo-router";
import { useEffect, useMemo, useRef, useState } from "react";
import { Pressable, RefreshControl, View, VirtualizedList } from "react-native";
import { useSelector } from "react-redux";
type Props = {
id: string
title: string
desc: string
createdAt: string
}
export default function Announcement() {
const { token, decryptToken } = useAuthSession()
const { colors } = useTheme();
const [search, setSearch] = useState('')
const update = useSelector((state: any) => state.announcementUpdate)
const isFirstRender = useRef(true)
const { visible: guideVisible, dismiss: dismissGuide } = useGuide('announcement')
const arrSkeleton = Array.from({ length: 5 }, (_, i) => i)
const themed = {
background: { backgroundColor: colors.background },
card: { backgroundColor: colors.card, borderColor: colors.icon + '18' },
iconBox: { backgroundColor: colors.icon + '18' },
title: { color: colors.text },
desc: { color: colors.dimmed },
date: { color: colors.dimmed },
cardPressed: { backgroundColor: colors.icon + '08' },
}
const {
data,
fetchNextPage,
hasNextPage,
isFetchingNextPage,
isLoading,
refetch,
isRefetching
} = useInfiniteQuery({
queryKey: ['announcements', search],
queryFn: async ({ pageParam = 1 }) => {
const hasil = await decryptToken(String(token?.current))
const response = await apiGetAnnouncement({ user: hasil, search, page: pageParam })
return response.data
},
initialPageParam: 1,
getNextPageParam: (lastPage, allPages) => {
return lastPage.length > 0 ? allPages.length + 1 : undefined
},
})
useEffect(() => {
if (isFirstRender.current) { isFirstRender.current = false; return }
refetch()
}, [update])
const flattenedData = useMemo(() => data?.pages.flat() || [], [data])
const getItem = (_data: unknown, index: number): Props => ({
id: flattenedData[index].id,
title: flattenedData[index].title,
desc: flattenedData[index].desc,
createdAt: flattenedData[index].createdAt,
})
const renderSkeleton = () => (
)
const renderItem = ({ item }: { item: Props }) => (
router.push(`/announcement/${item.id}`)}
style={({ pressed }) => [Styles.announcementListCard, themed.card, pressed && themed.cardPressed]}
>
{item.title}
{item.createdAt}
{item.desc.replace(/<[^>]*>?/gm, '').replace(/\r?\n|\r/g, ' ')}
)
return (
{isLoading && !flattenedData.length ? (
arrSkeleton.map((_, i) => (
{renderSkeleton()}
))
) : flattenedData.length > 0 ? (
flattenedData.length}
getItem={getItem}
renderItem={renderItem}
keyExtractor={(item, index) => String(item.id || index)}
onEndReached={() => { if (hasNextPage && !isFetchingNextPage) fetchNextPage() }}
onEndReachedThreshold={0.5}
showsVerticalScrollIndicator={false}
ItemSeparatorComponent={() => }
refreshControl={
}
/>
) : (
Tidak ada pengumuman
)}
)
}