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)",
},
});