import { useTheme } from "@/components/ThemeContext"; import { useInfiniteQuery, useQueryClient } from "@tanstack/react-query"; import { Image } from "expo-image"; import { router, useLocalSearchParams } from "expo-router"; import { ChevronLeft } from "lucide-react-native"; import { useCallback, useState } from "react"; import { ActivityIndicator, Dimensions, FlatList, StyleSheet, Text, ToastAndroid, TouchableOpacity, View, } from "react-native"; import * as WebBrowser from "expo-web-browser"; import { useTranslation } from "react-i18next"; import { RefreshControl } from "react-native-gesture-handler"; import { eservices_api } from "../lib/api"; const { width: SCREEN_WIDTH } = Dimensions.get("window"); const PAGE_SIZE = 10; export interface GovermentServiceDataRes { id: number; name: string; url: string; logo: string; } export default function EServicesScreen() { const { isDark } = useTheme(); const params = useLocalSearchParams(); const { t } = useTranslation(); const [refreshing, setRefreshing] = useState(false); const queryClient = useQueryClient(); const { data, isLoading, isError, fetchNextPage, hasNextPage, isFetchingNextPage, } = useInfiniteQuery({ queryKey: ["goverment_service", params.categoryId], queryFn: async ({ pageParam = 1 }) => { const response = await eservices_api.list({ page: pageParam, page_size: PAGE_SIZE, category: Number(params.categoryId), }); return response.data.data; }, getNextPageParam: (lastPage) => lastPage.current_page < lastPage.total_pages ? lastPage.current_page + 1 : undefined, initialPageParam: 1, }); const services: GovermentServiceDataRes[] = data?.pages.flatMap((p) => p.results) ?? []; const onRefresh = async () => { setRefreshing(true); try { await queryClient.refetchQueries({ queryKey: ["goverment_service"] }); } finally { setRefreshing(false); } }; const handleOpenBrowser = async (fileUrl: string) => { ToastAndroid.show(t("Xatolik yuz berdi"), ToastAndroid.TOP); try { await WebBrowser.openBrowserAsync(fileUrl); } catch (error) { ToastAndroid.show(t("Xatolik yuz berdi"), ToastAndroid.TOP); } }; const renderItem = useCallback( ({ item }: { item: GovermentServiceDataRes }) => ( handleOpenBrowser(item.url)} > {/* Name (alog‘ifa, faqat ko‘rsatish) */} {item.name} ), [isDark], ); if (isLoading) { return ( ); } if (isError) { return ( Xatolik yuz berdi ); } return ( {/* Header */} router.back()} hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }} > {params.categoryName} {/* Empty / List */} {services.length === 0 && !isLoading ? ( {t("Bu kategoriya bo'yicha xizmat topilmadi")} {t("Tez orada xizmat qo'shiladi")} ) : ( } keyExtractor={(item) => item.id.toString()} renderItem={renderItem} numColumns={3} columnWrapperStyle={{ justifyContent: "space-between", marginBottom: 12, }} contentContainerStyle={{ padding: 16, paddingBottom: 80 }} onEndReached={() => hasNextPage && !isFetchingNextPage && fetchNextPage() } onEndReachedThreshold={0.4} ListFooterComponent={ isFetchingNextPage ? ( ) : null } showsVerticalScrollIndicator={false} /> )} ); } const CARD_WIDTH = (SCREEN_WIDTH - 50) / 3; const styles = StyleSheet.create({ center: { flex: 1, justifyContent: "center", alignItems: "center" }, card: { width: CARD_WIDTH, borderRadius: 12, padding: 12, alignItems: "center", }, logo: { width: 80, height: 80, marginBottom: 8, }, name: { fontSize: 14, fontWeight: "600", textAlign: "center", }, darkShadow: { shadowColor: "#000", shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.4, shadowRadius: 6, elevation: 3, }, lightShadow: { shadowColor: "#000", shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 4, elevation: 2, }, });