import React, { useState, useCallback, useMemo } from "react"; import { View, TouchableOpacity, Alert, ActivityIndicator } from "react-native"; import { MaterialIcons } from "@expo/vector-icons"; import { useRouter } from "expo-router"; import { tw, ConfirmationDialog, MyText, MyFlatList, useMarkDataFetchers, ImageViewerURI } from "common-ui"; import { trpc } from "@/src/trpc-client"; export default function Complaints() { const router = useRouter(); const [dialogOpen, setDialogOpen] = useState(false); const [selectedComplaintId, setSelectedComplaintId] = useState(null); const { data, isLoading, isError, error, fetchNextPage, hasNextPage, isFetchingNextPage, refetch, } = trpc.admin.complaint.getAll.useInfiniteQuery( { limit: 20 }, { getNextPageParam: (lastPage) => lastPage.nextCursor, } ); useMarkDataFetchers(() => { refetch(); }); const resolveComplaint = trpc.admin.complaint.resolve.useMutation(); const complaints = useMemo(() => { const allComplaints = data?.pages.flatMap((page) => page.complaints) || []; return allComplaints.filter( (complaint, index, self) => index === self.findIndex((c) => c.id === complaint.id) ); }, [data]); const handleLoadMore = useCallback(() => { if (hasNextPage && !isFetchingNextPage) { fetchNextPage(); } }, [hasNextPage, isFetchingNextPage, fetchNextPage]); const handleUserPress = useCallback((userId: number) => { router.push(`/(drawer)/user-management/${userId}`); }, [router]); const handleOrderPress = useCallback((orderId: number) => { router.push(`/(drawer)/manage-orders/order-details/${orderId}`); }, [router]); const handleMarkResolved = (id: number) => { setSelectedComplaintId(id); setDialogOpen(true); }; const handleConfirmResolve = (response?: string) => { if (!selectedComplaintId) return; resolveComplaint.mutate( { id: String(selectedComplaintId), response }, { onSuccess: () => { Alert.alert("Success", "Complaint marked as resolved"); refetch(); setDialogOpen(false); setSelectedComplaintId(null); }, onError: (error: any) => { Alert.alert( "Error", error.message || "Failed to resolve complaint" ); setDialogOpen(false); setSelectedComplaintId(null); }, } ); }; if (isLoading) { return ( Loading complaints... ); } if (isError) { return ( Error {error?.message || "Failed to load complaints"} refetch()} style={tw`bg-blue-600 px-6 py-3 rounded-full`} > Retry ); } return ( item.id.toString()} onEndReached={handleLoadMore} onEndReachedThreshold={0.5} renderItem={({ item }) => ( Complaint #{item.id} {item.status === "resolved" ? "Resolved" : "Pending"} {item.text} {item.images && item.images.length > 0 && ( Attached Images: {item.images.map((imageUri: string, index: number) => ( ))} )} item.userId && handleUserPress(item.userId)} > {item.userName || item.userMobile || "Unknown User"} {item.orderId && ( <> | item.orderId && handleOrderPress(item.orderId)} > Order #{item.orderId} )} {item.status === "pending" && ( handleMarkResolved(item.id)} style={tw`bg-blue-500 py-3 rounded-xl items-center shadow-sm mt-2`} > Resolve Complaint )} )} ListEmptyComponent={ No complaints All complaints will appear here } ListFooterComponent={ isFetchingNextPage ? ( Loading more... ) : null } /> { setDialogOpen(false); setSelectedComplaintId(null); }} title="Resolve Complaint" message="Add admin notes for this resolution:" confirmText="Resolve" cancelText="Cancel" isLoading={resolveComplaint.isPending} /> ); }