Files
info-target-mobile/components/ui/FilteredItems.tsx
Samandar Turgunboyev a7419929f8 complated project
2026-02-02 18:51:53 +05:00

367 lines
11 KiB
TypeScript

import { useTheme } from '@/components/ThemeContext';
import { products_api } from '@/screens/home/lib/api';
import { businessAboutDetailResData } from '@/screens/home/lib/types';
import { useMutation } from '@tanstack/react-query';
import { ChevronLeft, FileText, Phone, User } from 'lucide-react-native';
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
ActivityIndicator,
FlatList,
Image,
Linking,
ScrollView,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
interface FilteredItemsProps {
data: { id: number; company_name: string }[];
back: () => void;
}
export default function FilteredItems({ data, back }: FilteredItemsProps) {
const { isDark } = useTheme();
const { t } = useTranslation();
const [selectedItem, setSelectedItem] = useState<businessAboutDetailResData | null>(null);
const { mutate, isPending } = useMutation({
mutationFn: (id: number) => products_api.businessAboutDetail(id),
onSuccess: (data) => setSelectedItem(data.data.data),
});
if (isPending) {
return (
<View style={styles.center}>
<ActivityIndicator size="large" color="#3b82f6" />
</View>
);
}
if (selectedItem) {
return (
<ScrollView style={[styles.container, isDark ? styles.darkBg : styles.lightBg]}>
<View style={styles.content}>
{/* Back Button */}
<TouchableOpacity
onPress={() => setSelectedItem(null)}
style={[styles.backButton, isDark ? styles.darkBackButton : styles.lightBackButton]}
>
<ChevronLeft size={24} color="#3b82f6" />
</TouchableOpacity>
{/* Company Name */}
<Text style={[styles.detailTitle, isDark ? styles.darkText : styles.lightText]}>
{selectedItem.company_name}
</Text>
{/* Company Image */}
{selectedItem.company_image && (
<Image
source={{ uri: selectedItem.company_image }}
style={[styles.companyImage, isDark ? styles.darkImageBg : styles.lightImageBg]}
resizeMode="cover"
/>
)}
{/* Info Card */}
<View style={[styles.infoCard, isDark ? styles.darkCard : styles.lightCard]}>
{selectedItem.director_full_name && (
<View style={styles.infoRow}>
<User size={20} color={isDark ? '#64748b' : '#94a3b8'} />
<View style={styles.infoTextContainer}>
<Text
style={[styles.infoLabel, isDark ? styles.darkSubText : styles.lightSubText]}
>
{t('Rahbar')}
</Text>
<Text style={[styles.infoValue, isDark ? styles.darkText : styles.lightText]}>
{selectedItem.director_full_name}
</Text>
</View>
</View>
)}
{selectedItem.phone && (
<TouchableOpacity
style={styles.infoRow}
onPress={() => Linking.openURL(`tel:+${selectedItem.phone}`)}
>
<Phone size={20} color="#3b82f6" />
<View style={styles.infoTextContainer}>
<Text
style={[styles.infoLabel, isDark ? styles.darkSubText : styles.lightSubText]}
>
{t('Telefon raqami')}
</Text>
<Text style={[styles.infoValue, { color: '#3b82f6' }]}>
+{selectedItem.phone}
</Text>
</View>
</TouchableOpacity>
)}
{selectedItem.product_service_company?.length > 0 && (
<View style={styles.section}>
<View style={styles.sectionHeader}>
<FileText size={20} color="#3b82f6" />
<Text style={[styles.sectionTitle, isDark ? styles.darkText : styles.lightText]}>
{t('Mahsulot va xizmatlar')}
</Text>
</View>
{selectedItem.product_service_company.map((item, index) => (
<View
key={index}
style={[
styles.serviceItem,
isDark ? styles.darkServiceItem : styles.lightServiceItem,
]}
>
<Text
style={[styles.serviceTitle, isDark ? styles.darkText : styles.lightText]}
>
{item.title}
</Text>
{item.description && (
<Text
style={[
styles.serviceDescription,
isDark ? styles.darkSubText : styles.lightSubText,
]}
>
{item.description}
</Text>
)}
{item.category?.length > 0 && (
<View style={styles.tagsContainer}>
{item.category.map((cat) => (
<View
key={cat.id}
style={[styles.tag, isDark ? styles.darkTag : styles.lightTag]}
>
<Text
style={[
styles.tagText,
isDark ? styles.darkSubText : styles.lightSubText,
]}
>
{cat.name}
</Text>
</View>
))}
</View>
)}
{item.files?.length > 0 && (
<View style={styles.filesContainer}>
<Text
style={[styles.filesTitle, isDark ? styles.darkText : styles.lightText]}
>
{t('Fayllar')}:
</Text>
{item.files.map((file, idx) => (
<TouchableOpacity
key={idx}
onPress={() => Linking.openURL(file.file)}
style={styles.fileLink}
>
<Text style={styles.fileLinkText}>
{t('Fayl')} {idx + 1} {t('ochish')}
</Text>
</TouchableOpacity>
))}
</View>
)}
</View>
))}
</View>
)}
</View>
</View>
</ScrollView>
);
}
// List view
return (
<View style={[styles.container, isDark ? styles.darkBg : styles.lightBg]}>
<View style={styles.content}>
<TouchableOpacity
onPress={back}
style={[styles.backButton, isDark ? styles.darkBackButton : styles.lightBackButton]}
>
<ChevronLeft size={24} color="#3b82f6" />
</TouchableOpacity>
{data && data.length > 0 ? (
<FlatList
data={data}
style={{ marginBottom: 70 }}
keyExtractor={(item) => item.id.toString()}
renderItem={({ item }) => (
<TouchableOpacity
style={[styles.itemCard, isDark ? styles.darkItemCard : styles.lightItemCard]}
onPress={() => mutate(item.id)}
>
<Text style={[styles.itemTitle, isDark ? styles.darkText : styles.lightText]}>
{item.company_name}
</Text>
</TouchableOpacity>
)}
contentContainerStyle={styles.listContainer}
/>
) : (
<View style={styles.emptyContainer}>
<Text style={[styles.emptyText, isDark ? styles.darkSubText : styles.lightSubText]}>
{t('Natija topilmadi')}
</Text>
</View>
)}
</View>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1 },
darkBg: {
backgroundColor: '#0f172a',
},
lightBg: {
backgroundColor: '#f8fafc',
},
content: {
padding: 16,
maxWidth: 500,
width: '100%',
alignSelf: 'center',
},
center: { flex: 1, justifyContent: 'center', alignItems: 'center' },
backButton: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 16,
padding: 10,
borderRadius: 12,
alignSelf: 'flex-start',
gap: 8,
},
darkBackButton: {
backgroundColor: '#1e293b',
},
lightBackButton: {
backgroundColor: '#ffffff',
},
backText: { fontSize: 16, color: '#3b82f6', fontWeight: '600' },
listContainer: { gap: 12 },
itemCard: {
borderRadius: 12,
padding: 16,
borderWidth: 1,
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.05,
shadowRadius: 2,
elevation: 2,
},
darkItemCard: {
backgroundColor: '#1e293b',
borderColor: '#334155',
},
lightItemCard: {
backgroundColor: '#ffffff',
borderColor: '#e2e8f0',
},
itemTitle: { fontSize: 17, fontWeight: '600' },
darkText: {
color: '#f1f5f9',
},
lightText: {
color: '#0f172a',
},
emptyContainer: { flex: 1, alignItems: 'center', justifyContent: 'center', padding: 40 },
emptyText: { fontSize: 16, textAlign: 'center' },
darkSubText: {
color: '#64748b',
},
lightSubText: {
color: '#94a3b8',
},
// Detail
detailTitle: { fontSize: 26, fontWeight: '700', marginBottom: 16 },
companyImage: {
width: '100%',
height: 220,
borderRadius: 16,
marginBottom: 20,
},
darkImageBg: {
backgroundColor: '#1e293b',
},
lightImageBg: {
backgroundColor: '#f1f5f9',
},
infoCard: {
borderRadius: 16,
padding: 20,
borderWidth: 1,
gap: 16,
},
darkCard: {
backgroundColor: '#1e293b',
borderColor: '#334155',
},
lightCard: {
backgroundColor: '#ffffff',
borderColor: '#e2e8f0',
},
infoRow: { flexDirection: 'row', alignItems: 'center', gap: 12, paddingVertical: 8 },
infoTextContainer: { flex: 1 },
infoLabel: { fontSize: 14, marginBottom: 4 },
infoValue: { fontSize: 16, fontWeight: '500' },
section: { marginTop: 8 },
sectionHeader: { flexDirection: 'row', alignItems: 'center', gap: 10, marginBottom: 12 },
sectionTitle: { fontSize: 18, fontWeight: '700' },
serviceItem: {
borderRadius: 12,
padding: 16,
marginBottom: 12,
},
darkServiceItem: {
backgroundColor: '#0f172a',
},
lightServiceItem: {
backgroundColor: '#f8fafc',
},
serviceTitle: { fontSize: 17, fontWeight: '600', marginBottom: 8 },
serviceDescription: { fontSize: 15, lineHeight: 22, marginBottom: 12 },
tagsContainer: { flexDirection: 'row', flexWrap: 'wrap', gap: 8, marginTop: 8 },
tag: {
flexDirection: 'row',
alignItems: 'center',
gap: 6,
paddingHorizontal: 12,
paddingVertical: 6,
borderRadius: 20,
},
darkTag: {
backgroundColor: '#1e293b',
},
lightTag: {
backgroundColor: '#ffffff',
},
tagText: { fontSize: 13, fontWeight: '500' },
filesContainer: { marginTop: 12 },
filesTitle: { fontSize: 14, fontWeight: '600', marginBottom: 8 },
fileLink: { paddingVertical: 6 },
fileLinkText: { color: '#3b82f6', fontSize: 15, textDecorationLine: 'underline' },
});