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"; import { getSubjectTransLanguage } from "../utils/languageUtils"; import useUserStore from "../store/user"; // 为图标定义类型 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 userStore = useUserStore(); const [searchParams, setSearchParams] = useState({ keyword: "pen", page: 1, page_size: 20, sort_order: "desc", sort_by: "default", language: "en", }); const [products, setProducts] = useState([]); const flatListRef = useRef(null); const data = [ { imgUrl: require("../../assets/img/banner en (5)_compressed.png"), add: "TikTokScreen", }, { imgUrl: require("../../assets/img/banner en (3)_compressed.png"), add: "MemberIntroduction", }, { imgUrl: require("../../assets/img/banner en (4)_compressed.png"), add: "CompanyScreen", }, ]; const getProductData = async () => { try { const currentParams = { ...searchParams, ...(userStore.user?.user_id ? { user_id: userStore.user.user_id } : {}), }; const res = await productApi.getSearchProducts(currentParams); 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(); } catch (error) { console.error("Error fetching products:", error); } finally { setRefreshing(false); } }, [searchParams]); useEffect(() => { console.log("userStore.user", userStore.user); getProductData(); }, [userStore.user]); 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} > {userStore.user?.user_id && ( VIP {userStore.user?.vip_level} )} {getSubjectTransLanguage(item)} {userStore.user?.user_id && ( {item.original_min_price || "0"} {item.currency || "FCFA"} )} {item.min_price || "0"} {item.currency || "FCFA"} {item.sold_out || "0"}+ ventes ); // 渲染列表头部内容 const renderHeader = () => ( <> {/* 轮播图 */} setActiveIndex(index)} modeConfig={{ parallaxScrollingScale: 0.9, parallaxScrollingOffset: 50, }} renderItem={({ item }) => ( navigation.navigate(item.add)} key={item.imgUrl} style={{ flex: 1, justifyContent: "center", alignItems: "center", backgroundColor: "#f2f2f2", borderRadius: 10, overflow: "hidden", }} > )} /> {/* 自定义指示器 */} {/* {data.map((_, index) => ( ))} */} {/* 搜索栏 - 定位在轮播图上方 */} 搜索商品 {/* 内容区域 */} {/* 左侧区域 - 上下两个 */} navigation.navigate("TikTokScreen")} > {/* 右侧区域 - 一个 */} {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)} > 推荐 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: 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: widthUtils(30, 66).width, height: widthUtils(30, 66).height, justifyContent: "center", alignItems: "center", backgroundColor: "#3b3b3b", borderRadius: 10, flexDirection: "row", }, vipButtonText: { fontStyle: "italic", fontWeight: "900", fontSize: fontSize(18), color: "#f1c355", }, vipLabelBold: { fontStyle: "italic", fontWeight: "900", fontSize: fontSize(18), color: "#f1c355", }, beautyProductCard: { marginTop: 9, }, beautyProductTitle: { fontSize: fontSize(14), fontWeight: "600", color: "black", lineHeight: 18, }, beautyProductInfoRow: { flexDirection: "row", alignItems: "center", }, flexRowCentered: {}, priceContainer: { flexDirection: "row", }, highlightedText: { fontWeight: "700", fontSize: fontSize(24), color: "#ff5100", marginLeft: 2, }, highlightedText1: { fontWeight: "700", fontSize: fontSize(14), color: "#ff5100", }, priceContainer1: {}, priceLabel1: { fontSize: fontSize(12), fontWeight: "600", color: "#9a9a9a", textDecorationLine: "line-through", }, beautySalesInfo: { marginTop: 6.75, fontSize: 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)", }, });