// EServicesScreen.tsx import { useTheme } from '@/components/ThemeContext'; import { useInfiniteQuery } from '@tanstack/react-query'; import { Image } from 'expo-image'; import { ChevronLeft, XIcon } from 'lucide-react-native'; import React, { useCallback, useRef, useState } from 'react'; import { ActivityIndicator, Dimensions, FlatList, Modal, StyleSheet, Text, TouchableOpacity, View, } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { WebView } from 'react-native-webview'; 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 [webUrl, setWebUrl] = useState(null); const [modalVisible, setModalVisible] = useState(false); const webviewRef = useRef(null); // WebView ref for goBack const { data, isLoading, isError, fetchNextPage, hasNextPage, isFetchingNextPage } = useInfiniteQuery({ queryKey: ['goverment_service'], queryFn: async ({ pageParam = 1 }) => { const response = await eservices_api.list({ page: pageParam, page_size: PAGE_SIZE, }); 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 openWebView = (url: string) => { setWebUrl(url); setModalVisible(true); }; const renderItem = useCallback( ({ item }: { item: GovermentServiceDataRes }) => ( openWebView(item.url)} > {item.name} ), [isDark] ); if (isLoading) { return ( ); } if (isError) { return ( Xatolik yuz berdi ); } return ( item.id.toString()} renderItem={renderItem} numColumns={2} columnWrapperStyle={{ justifyContent: 'space-between', marginBottom: 12 }} contentContainerStyle={{ padding: 16 }} onEndReached={() => hasNextPage && fetchNextPage()} onEndReachedThreshold={0.4} ListFooterComponent={ isFetchingNextPage ? : null } showsVerticalScrollIndicator={false} /> {/* WebView Modal */} {/* WebView Modal */} {/* Header */} {/* Back tugmasi */} { if (webviewRef.current) webviewRef.current.goBack(); }} hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }} > {/* Close tugmasi */} setModalVisible(false)} hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }} > {/* WebView */} {webUrl && ( ( )} /> )} ); } const CARD_WIDTH = (SCREEN_WIDTH - 48) / 2; const styles = StyleSheet.create({ center: { flex: 1, justifyContent: 'center', alignItems: 'center' }, card: { width: CARD_WIDTH, borderRadius: 12, padding: 12, alignItems: 'center', }, logo: { width: 60, height: 60, 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, }, });