import GuideOverlay from "@/components/GuideOverlay"; import ButtonTab from "@/components/buttonTab"; import InputSearch from "@/components/inputSearch"; import LabelStatus from "@/components/labelStatus"; import SkeletonContent from "@/components/skeletonContent"; import Text from "@/components/Text"; import WrapTab from "@/components/wrapTab"; import Styles from "@/constants/Styles"; import { apiGetDiscussionGeneral } from "@/lib/api"; import { GUIDE_DISCUSSION } from "@/lib/guideSteps"; import { useGuide } from "@/lib/useGuide"; import { useAuthSession } from "@/providers/AuthProvider"; import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign, Feather } from "@expo/vector-icons"; import { useInfiniteQuery, useQueryClient } from "@tanstack/react-query"; import { router, useLocalSearchParams } from "expo-router"; import { useEffect, useMemo, useState } from "react"; import { FlatList, Pressable, RefreshControl, View } from "react-native"; import { useSelector } from "react-redux"; type Props = { id: string title: string desc: string status: number total_komentar: number createdAt: string } export default function Discussion() { const entityUser = useSelector((state: any) => state.user) const { token, decryptToken } = useAuthSession() const { colors } = useTheme(); const { active, group } = useLocalSearchParams<{ active?: string, group?: string }>() const [search, setSearch] = useState('') const update = useSelector((state: any) => state.discussionGeneralDetailUpdate) const queryClient = useQueryClient() const [status, setStatus] = useState<'true' | 'false'>(active == 'false' ? 'false' : 'true') const [refreshing, setRefreshing] = useState(false) const { visible: guideVisible, dismiss: dismissGuide } = useGuide('discussion') const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading, refetch } = useInfiniteQuery({ queryKey: ['discussions', { status, search, group }], queryFn: async ({ pageParam = 1 }) => { const hasil = await decryptToken(String(token?.current)) const response = await apiGetDiscussionGeneral({ user: hasil, active: status, search: search, group: String(group), page: pageParam }) return response; }, initialPageParam: 1, getNextPageParam: (lastPage, allPages) => { return lastPage.data.length > 0 ? allPages.length + 1 : undefined; }, enabled: !!token?.current, staleTime: 0, }) const flatData = useMemo(() => { return data?.pages.flatMap(page => page.data) || []; }, [data]) const nameGroup = useMemo(() => { return data?.pages[0]?.filter?.name || ""; }, [data]) useEffect(() => { refetch() }, [update, refetch]) const handleRefresh = async () => { setRefreshing(true) await queryClient.invalidateQueries({ queryKey: ['discussions'] }) setRefreshing(false) }; const isOpen = (item: Props) => item.status === 1 const themed = { background: { backgroundColor: colors.background }, card: { backgroundColor: colors.card, borderColor: colors.icon + '20' }, cardPressed: { backgroundColor: colors.icon + '10' }, iconCircle: { backgroundColor: colors.icon + '20' }, title: { color: colors.text }, dimmed: { color: colors.dimmed }, statusOpen: { borderColor: '#10B981' as const }, statusClosed: { borderColor: colors.dimmed + '80' }, statusTextOpen: { color: '#10B981' as const }, statusTextClosed: { color: colors.dimmed }, } return ( {/* Header controls */} {entityUser.role != "user" && entityUser.role != "coadmin" && ( setStatus("true")} label="Aktif" icon={} n={2} /> setStatus("false")} label="Arsip" icon={} n={2} /> )} {(entityUser.role == "supadmin" || entityUser.role == "developer") && ( Filter : )} {/* List */} {isLoading ? ( [0, 1, 2, 3, 4].map((_, i) => ) ) : flatData.length === 0 ? ( Tidak ada diskusi ) : ( String(i)} showsVerticalScrollIndicator={false} onEndReached={() => { if (hasNextPage && !isFetchingNextPage) fetchNextPage() }} onEndReachedThreshold={0.5} refreshControl={ } ItemSeparatorComponent={() => } renderItem={({ item }: { item: Props }) => ( router.push(`/discussion/${item.id}`)} style={({ pressed }) => [ Styles.discussionCard, themed.card, pressed && themed.cardPressed, ]} > {/* Top row: icon + title + status badge */} {/* Discussion icon */} {/* Title + status badge */} {item.title} {status !== "false" && ( {isOpen(item) ? 'Buka' : 'Tutup'} )} {/* Description */} {item.desc ? ( {item.desc.replace(/<[^>]*>?/gm, ' ').replace(/\r?\n|\r/g, ' ')} ) : null} {/* Bottom row: comment count + date */} {item.total_komentar} Komentar {item.createdAt} )} /> )} ); }