Files
info-target-mobile/screens/profile/ui/RefferallsTab.tsx
Samandar Turgunboyev d747c72c8d complated
2026-02-17 10:46:57 +05:00

221 lines
5.9 KiB
TypeScript

import { useTheme } from '@/components/ThemeContext';
import { useInfiniteQuery } from '@tanstack/react-query';
import * as Clipboard from 'expo-clipboard';
import { useRouter } from 'expo-router';
import { ArrowLeft, CopyIcon, HandCoins, Plus, Users } from 'lucide-react-native';
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
ActivityIndicator,
FlatList,
Platform,
Pressable,
RefreshControl,
Share,
StyleSheet,
Text,
ToastAndroid,
TouchableOpacity,
View,
} from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { user_api } from '../lib/api';
const PAGE_SIZE = 10;
export function ReferralsTab() {
const router = useRouter();
const { isDark } = useTheme();
const { t } = useTranslation();
const [refreshing, setRefreshing] = useState(false);
const theme = {
background: isDark ? '#0f172a' : '#f8fafc',
cardBg: isDark ? '#1e293b' : '#ffffff',
text: isDark ? '#ffffff' : '#0f172a',
subText: isDark ? '#94a3b8' : '#64748b',
primary: '#3b82f6',
success: '#10b981',
};
const { data, isLoading, isError, fetchNextPage, hasNextPage, refetch } = useInfiniteQuery({
queryKey: ['my_referrals'],
queryFn: async ({ pageParam = 1 }) => {
const res = await user_api.my_referrals({
page: pageParam,
page_size: PAGE_SIZE,
});
const d = res.data.data;
return {
results: d.results ?? [],
current_page: d.current_page,
total_pages: d.total_pages,
};
},
getNextPageParam: (lastPage) =>
lastPage.current_page < lastPage.total_pages ? lastPage.current_page + 1 : undefined,
initialPageParam: 1,
});
const referrals = data?.pages.flatMap((p) => p.results) ?? [];
const onRefresh = async () => {
setRefreshing(true);
await refetch();
setRefreshing(false);
};
// Clipboard + Share funksiyasi
const handleCopyAndShare = async (code: string) => {
const referralLink = `https://t.me/infotargetbot/join?startapp=${code}`;
// Clipboard-ga nusxa olish
await Clipboard.setStringAsync(referralLink);
// Share qilish
try {
await Share.share({
message: referralLink,
title: t('Referal linkni ulashish'),
});
} catch (err) {
console.log('Share error:', err);
}
if (Platform.OS === 'android') {
ToastAndroid.show(t('Refferal kopiya qilindi'), ToastAndroid.SHORT);
}
};
if (isLoading) {
return (
<SafeAreaView style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<ActivityIndicator size="large" />
</SafeAreaView>
);
}
if (isError) {
return (
<View style={[styles.center, { backgroundColor: theme.background }]}>
<Text style={{ color: 'red' }}>{t('Xatolik yuz berdi')}</Text>
</View>
);
}
return (
<View style={[styles.container, { backgroundColor: theme.background }]}>
{/* Header */}
<View style={styles.topHeader}>
<Pressable onPress={() => router.push('/profile')}>
<ArrowLeft color={theme.text} />
</Pressable>
<Text style={[styles.headerTitle, { color: theme.text }]}>{t('Refferallarim')}</Text>
<Pressable onPress={() => router.push('/profile/added-referalls')}>
<Plus color={theme.primary} />
</Pressable>
</View>
<FlatList
data={referrals}
keyExtractor={(item) => item.id.toString()}
contentContainerStyle={styles.list}
refreshControl={
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} tintColor={theme.primary} />
}
onEndReached={() => hasNextPage && fetchNextPage()}
renderItem={({ item }) => (
<View style={[styles.card, { backgroundColor: theme.cardBg }]}>
<View style={styles.cardRow}>
<View style={styles.cardHeader}>
<HandCoins size={20} color={theme.primary} />
<Text style={[styles.code, { color: theme.text }]}>{item.code}</Text>
</View>
<TouchableOpacity onPress={() => handleCopyAndShare(item.code)}>
<CopyIcon size={20} color={theme.primary} />
</TouchableOpacity>
</View>
<Text style={{ color: theme.subText }}>{item.description}</Text>
<View style={styles.footer}>
<View style={styles.row}>
<Users size={16} color={theme.subText} />
<Text style={[styles.meta, { color: theme.subText }]}>
{item.referral_registered_count} {t('foydalanuvchi')}
</Text>
</View>
<Text style={[styles.amount, { color: theme.success }]}>
{item.referral_income_amount} {t("so'm")}
</Text>
</View>
</View>
)}
ListEmptyComponent={
<Text style={{ textAlign: 'center', color: theme.subText }}>
{t('Refferallar topilmadi')}
</Text>
}
/>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1 },
center: { flex: 1, justifyContent: 'center', alignItems: 'center' },
topHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
padding: 16,
alignItems: 'center',
},
headerTitle: { fontSize: 18, fontWeight: '700' },
list: { padding: 16, gap: 12, paddingBottom: 30 },
card: {
borderRadius: 16,
padding: 16,
gap: 10,
},
cardRow: {
flexDirection: 'row',
justifyContent: 'space-between',
alignContent: 'center',
alignItems: 'center',
},
cardHeader: {
flexDirection: 'row',
gap: 8,
alignItems: 'center',
},
code: {
fontSize: 16,
fontWeight: '700',
},
footer: {
flexDirection: 'row',
justifyContent: 'space-between',
marginTop: 6,
},
row: {
flexDirection: 'row',
gap: 6,
alignItems: 'center',
},
meta: {},
amount: {
fontWeight: '700',
},
});