import React, { useCallback, useState, useRef, useEffect } from "react"; import { View, Text, StyleSheet, TouchableOpacity, FlatList, InteractionManager, Image, ScrollView, Modal, ImageBackground, RefreshControl, Dimensions, } from "react-native"; import { productApi, ProductParams, type Product, } from "../services/api/productApi"; import Carousel from "react-native-reanimated-carousel"; import Ionicons from "@expo/vector-icons/Ionicons"; import { useNavigation } from "@react-navigation/native"; import { NativeStackNavigationProp } from "@react-navigation/native-stack"; import { useTranslation } from "react-i18next"; import widthUtils from "../utils/widthUtils"; import DownArrowIcon from "../components/DownArrowIcon"; import { LinearGradient } from "expo-linear-gradient"; import fontSize from "../utils/fontsizeUtils"; import CloseIcon from "../components/CloseIcon"; import CheckmarkIcon from "../components/CheckmarkIcon"; // 为图标定义类型 type IconProps = { name: string; size: number; color: string; }; // 图标组件辅助函数 - 使用React.memo优化渲染 const IconComponent = React.memo(({ name, size, color }: IconProps) => { const Icon = Ionicons as any; return ; }); type SubcategoryItem = { id: string | number; title: string; icon: string; }; type CategoryContentType = { [key: string]: SubcategoryItem[]; }; export const HomeScreen = () => { const [activeIndex, setActiveIndex] = useState(0); const screenWidth = Dimensions.get("window").width; const navigation = useNavigation>(); const { t } = useTranslation(); const [showCategoryModal, setShowCategoryModal] = useState(false); const [selectedCategory, setSelectedCategory] = useState("Bijoux"); const [selectedHorizontalCategory, setSelectedHorizontalCategory] = useState("Tous"); const [refreshing, setRefreshing] = useState(false); const horizontalScrollRef = useRef(null); const [searchParams, setSearchParams] = useState({ keyword: "pen", page: 1, page_size: 20, sort_order: "desc", category_id: null, sort_by: "default", language: "en", }); const [products, setProducts] = useState([]); const flatListRef = useRef(null); const data = [ { imgUrl: require("../../assets/img/banner en (5).png") }, { imgUrl: require("../../assets/img/banner en (3).png") }, { imgUrl: require("../../assets/img/banner en (4).png") }, ]; const getProductData = async () => { try { const res = await productApi.getSearchProducts(searchParams); setProducts(res.products); } catch (error) { console.error("Error fetching products:", error); } }; const handleProductPress = useCallback((item: Product) => { InteractionManager.runAfterInteractions(() => { navigation.navigate("ProductDetail", { offer_id: item.offer_id, searchKeyword: searchParams.keyword, price: item.min_price, }); }); }, [navigation]); const onRefresh = useCallback(async () => { setRefreshing(true); try { await getProductData(); } finally { setRefreshing(false); } }, [searchParams]); useEffect(() => { getProductData(); }, []); const categories = [ "Tous", "Bijoux", "Maison et Cuisine", "Vêtements femme", "Grandes tailles femme", "Chaussures femme", "Pyjamas et Sous-vête-ments", "Accessoires beauté", "Soins cheveux", "Hygiène et Soins pour le corps", "Maquillage", ]; const defaultSubcategories: SubcategoryItem[] = [ { id: 1, title: "Jewelry", icon: "diamond-outline" }, { id: 2, title: "Earrings", icon: "ear-outline" }, { id: 3, title: "Bracelet", icon: "watch-outline" }, { id: 4, title: "Jewelry Sets", icon: "gift-outline" }, { id: 5, title: "Earrings", icon: "ear-outline" }, { id: 6, title: "Bracelet", icon: "watch-outline" }, ]; const categoryContent: CategoryContentType = { Tous: [], Bijoux: defaultSubcategories, "Maison et Cuisine": defaultSubcategories, "Vêtements femme": defaultSubcategories, "Grandes tailles femme": defaultSubcategories, "Chaussures femme": defaultSubcategories, "Pyjamas et Sous-vête-ments": defaultSubcategories, "Accessoires beauté": defaultSubcategories, "Soins cheveux": defaultSubcategories, "Hygiène et Soins pour le corps": defaultSubcategories, Maquillage: defaultSubcategories, }; useEffect(() => { // Ensure the content is available when category changes if (!categoryContent[selectedHorizontalCategory]) { setSelectedHorizontalCategory("Tous"); } }, [selectedHorizontalCategory]); // 导航到搜索页面 - 使用useCallback优化函数引用 const navigateToSearch = useCallback(() => { // 使用InteractionManager延迟执行导航操作,确保当前交互和动画已完成 InteractionManager.runAfterInteractions(() => { navigation.navigate("Search"); }); }, [navigation]); const navigateToShippingDetails = useCallback(() => { InteractionManager.runAfterInteractions(() => { navigation.navigate("ShippingDetailsSection"); }); }, [navigation]); const navigateToInquiry = useCallback(() => { InteractionManager.runAfterInteractions(() => { navigation.navigate("InquiryScreen"); }); }, [navigation]); const scrollToCategory = (category: string) => { const categoryIndex = categories.findIndex((c) => c === category); if (categoryIndex !== -1 && horizontalScrollRef.current) { const firstFourKeys = Object.keys(categoryContent).slice( 0, categoryIndex - 1 ); let str = ""; firstFourKeys.forEach((key, index) => { str += key; }); horizontalScrollRef.current.scrollTo({ x: str.length * fontSize(16) + (categoryIndex - 1 + 17), animated: true, }); } }; // 渲染产品列表项 const renderProductItem = ({ item }: { item: Product }) => ( handleProductPress(item)} activeOpacity={0.9} style={styles.beautyProductCard1} > VIP 1 {item.subject || "Soins de beauté soins de la peau/maquillage..."} {item.min_price || "300"} FCFA 3000FCFA {item.sold_out || "28000"}+ ventes ); // 渲染列表头部内容 const renderHeader = () => ( <> {/* 轮播图 */} setActiveIndex(index)} modeConfig={{ parallaxScrollingScale: 0.9, parallaxScrollingOffset: 50, }} renderItem={({ item }) => ( )} /> {/* 自定义指示器 */} {/* {data.map((_, index) => ( ))} */} {/* 搜索栏 - 定位在轮播图上方 */} {t("searchProducts")} {/* 内容区域 */} {/* 左侧区域 - 上下两个 */} {/* 右侧区域 - 一个 */} {categories.map((category, index) => ( setSelectedHorizontalCategory(category)} > {category} ))} setShowCategoryModal(true)}> {/* Subcategory Content */} {selectedHorizontalCategory && categoryContent[selectedHorizontalCategory] && categoryContent[selectedHorizontalCategory].length > 0 ? ( {categoryContent[selectedHorizontalCategory].map((item) => ( { // Handle subcategory selection }} > {item.title} ))} ) : null} ); return ( item.offer_id?.toString() || index.toString() } contentContainerStyle={{ paddingBottom: 15, backgroundColor: "transparent", }} ListHeaderComponent={renderHeader} refreshControl={ } /> {/* Categories Modal */} setShowCategoryModal(false)} > {t("popularCategories")} setShowCategoryModal(false)} > {categories.map((category, index) => ( { setSelectedCategory(category); setSelectedHorizontalCategory(category); setShowCategoryModal(false); scrollToCategory(category); }} > {category} {selectedCategory === category && ( )} ))} ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#fff", }, safeArea: { flex: 1, }, swpImg: { width: "100%", height: 180, }, searchOverlay: { position: "absolute", top: 60, left: 15, right: 15, zIndex: 10, }, searchBar: { flexDirection: "row", alignItems: "center", backgroundColor: "rgba(255, 255, 255, 0.9)", borderRadius: 20, paddingHorizontal: 15, height: 40, shadowColor: "#000", shadowOffset: { width: 0, height: 2, }, shadowOpacity: 0.1, shadowRadius: 3, elevation: 3, }, searchPlaceholder: { flex: 1, marginLeft: 8, fontSize: 16, }, cameraButton: { padding: 5, }, bannerContainer: { flexDirection: "row", marginTop: 20, paddingHorizontal: 15, width: "100%", }, leftContainer: { marginRight: "4%", }, leftTopItem: { height: widthUtils(90, 200).height, width: widthUtils(90, 200).width, borderRadius: 8, padding: 0, marginBottom: 10, overflow: "hidden", }, leftBottomItem: { height: widthUtils(90, 200).height, width: widthUtils(90, 200).width, borderRadius: 8, padding: 0, overflow: "hidden", }, rightContainer: { width: widthUtils(190, 180).width, height: widthUtils(190, 180).height, borderRadius: 8, padding: 0, overflow: "hidden", flex: 1, }, bannerIcon: { width: "100%", height: "100%", objectFit: "contain", }, bigbannerIcon: { width: "100%", height: "100%", objectFit: "contain", }, category: { width: "100%", paddingVertical: 10, flexDirection: "row", alignItems: "center", marginTop: 10, backgroundColor: "#fff", }, categoryScrollContainer: { flex: 1, position: "relative", overflow: "hidden", paddingRight: 55, }, categoryScroll: { paddingHorizontal: 15, }, categoryItem: { paddingHorizontal: 12, paddingVertical: 8, marginRight: 5, }, categoryItemActive: { borderBottomWidth: 2, borderBottomColor: "#000", }, categoryText: { fontSize: fontSize(16), color: "#747474", fontFamily: "Alexandria", fontWeight: "400", }, categoryTextActive: { color: "#000", fontWeight: "500", }, swiperContainer: { width: "100%", height: widthUtils(286, 430).height, paddingHorizontal: 0, }, swiper: { width: "100%", }, dot: { backgroundColor: "rgba(255,255,255,0.5)", width: 8, height: 8, borderRadius: 4, marginLeft: 3, marginRight: 3, }, activeDot: { backgroundColor: "#fff", width: 20, height: 8, borderRadius: 4, marginLeft: 3, marginRight: 3, }, slide: { flex: 1, justifyContent: "center", alignItems: "center", width: "100%", }, slideImage: { width: "100%", height: "100%", }, fadeGradient: { position: "absolute", right: 40, top: 0, bottom: 0, width: 40, zIndex: 1, backgroundColor: "transparent", }, categoryArrowContainer: { position: "absolute", right: 0, paddingRight: 15, height: "100%", justifyContent: "center", alignItems: "center", zIndex: 2, backgroundColor: "#fff", }, modalOverlay: { flex: 1, backgroundColor: "rgba(0, 0, 0, 0.5)", justifyContent: "flex-end", }, modalContent: { backgroundColor: "#fff", borderTopLeftRadius: 20, borderTopRightRadius: 20, maxHeight: "80%", }, modalHeader: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", padding: 16, borderBottomWidth: 1, borderBottomColor: "#f0f0f0", }, modalTitleContainer: { flexDirection: "row", alignItems: "center", }, modalTitle: { fontSize: fontSize(16), fontWeight: "600", marginLeft: 8, }, closeButton: { padding: 8, }, closeButtonText: { fontSize: fontSize(24), color: "#000", fontWeight: "300", }, modalScrollView: { padding: 16, }, categoryModalItem: { flexDirection: "row", justifyContent: "space-between", alignItems: "center", paddingVertical: 16, }, categoryModalText: { fontSize: fontSize(16), color: "#666", fontFamily: "Segoe UI", fontWeight: "700", }, selectedCategoryText: { color: "#000", fontWeight: "500", }, subcategoryContainer: { height: 100, // Fixed height for the subcategory container marginTop: 15, }, subcategoryScroll: { flex: 1, }, subcategoryContent: { paddingHorizontal: 15, }, subcategoryItem: { alignItems: "center", marginRight: 15, width: 60, }, subcategoryImagePlaceholder: { width: 60, height: 60, borderRadius: 30, backgroundColor: "#f5f5f5", justifyContent: "center", alignItems: "center", marginBottom: 8, }, subcategoryText: { fontSize: fontSize(12), color: "#333", textAlign: "center", fontFamily: "Alexandria", }, productContainer: { flex: 1, backgroundColor: "#fff", }, productCardList: { padding: 15, paddingTop: 0, }, productCardGroup: { justifyContent: "space-between", marginBottom: 15, paddingHorizontal: 15, }, beautyProductCard1: { width: "48%", }, beautyCardContainer1: { flexDirection: "column", alignItems: "flex-end", justifyContent: "center", width: "100%", paddingBottom: 160, backgroundColor: "transparent", borderRadius: 10, overflow: "hidden", }, vipButton: { width: 66, height: 30, justifyContent: "center", alignItems: "center", backgroundColor: "linear-gradient(32.02deg, rgba(240, 179, 46, 1) 29.07%, rgba(236, 212, 95, 1) 72.56%)", borderRadius: 10, }, vipButtonText: { fontStyle: "italic", fontWeight: "900", fontSize: 18, color: "transparent", }, vipLabelBold: { fontStyle: "italic", fontWeight: "900", fontSize: 18, color: "transparent", }, beautyProductCard: { marginTop: 9, }, beautyProductTitle: { fontSize: 14, fontWeight: "600", color: "black", lineHeight: 18, }, beautyProductInfoRow: { flexDirection: "row", alignItems: "center", }, flexRowCentered: { flexDirection: "row", alignItems: "center", }, highlightedText: { fontWeight: "700", fontSize: 24, color: "#ff5100", }, highlightedText1: { fontWeight: "700", fontSize: 14, color: "#ff5100", }, priceContainer1: { marginLeft: 5.75, }, priceLabel1: { fontSize: 12, fontWeight: "600", color: "#9a9a9a", }, beautySalesInfo: { marginTop: 6.75, fontSize: 14, fontWeight: "600", color: "#7c7c7c", }, indicatorContainer: { flexDirection: 'row', justifyContent: 'center', alignItems: 'center', position: 'absolute', bottom: 10, left: 0, right: 0, }, indicator: { marginHorizontal: 4, borderRadius: 3, }, activeIndicator: { width: 14, height: 6, backgroundColor: '#fff', }, inactiveIndicator: { width: 6, height: 6, backgroundColor: 'rgba(255, 255, 255, 0.5)', }, });