fitst commit
This commit is contained in:
369
components/ui/FilteredItems.tsx
Normal file
369
components/ui/FilteredItems.tsx
Normal file
@@ -0,0 +1,369 @@
|
||||
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]}
|
||||
contentContainerStyle={{ paddingBottom: 70 }}
|
||||
>
|
||||
<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: 120 }}
|
||||
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' },
|
||||
});
|
||||
Reference in New Issue
Block a user