You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

178 lines
4.5 KiB

import React, { useState } from 'react';
import {
View,
Text,
FlatList,
TouchableOpacity,
StyleSheet,
Image,
Dimensions,
ListRenderItem,
Platform,
StatusBar,
SafeAreaView
} from 'react-native';
import fontSize from '../utils/fontsizeUtils';
import widthUtils from '../utils/widthUtils';
type Category = {
id: string;
name: string;
};
type Product = {
name: string;
img: string;
};
const categories: Category[] = [
{ id: 'fruit', name: '水果' },
{ id: 'snacks', name: '零食' },
{ id: 'clothes', name: '服饰' },
{ id: 'home', name: '家居' },
];
const productsData: Record<string, Product[]> = {
fruit: [
{ name: '苹果', img: 'https://via.placeholder.com/100?text=苹果' },
{ name: '香蕉', img: 'https://via.placeholder.com/100?text=香蕉' },
{ name: '西瓜', img: 'https://via.placeholder.com/100?text=西瓜' },
],
snacks: [
{ name: '薯片', img: 'https://via.placeholder.com/100?text=薯片' },
{ name: '饼干', img: 'https://via.placeholder.com/100?text=饼干' },
{ name: '巧克力', img: 'https://via.placeholder.com/100?text=巧克力' },
],
clothes: [
{ name: 'T恤', img: 'https://via.placeholder.com/100?text=T恤' },
{ name: '牛仔裤', img: 'https://via.placeholder.com/100?text=牛仔裤' },
{ name: '外套', img: 'https://via.placeholder.com/100?text=外套' },
],
home: [
{ name: '毛巾fdfd一定要人盯人一天的玉兔捣药', img: 'https://via.placeholder.com/100?text=毛巾' },
{ name: '椅子', img: 'https://via.placeholder.com/100?text=椅子' },
{ name: '灯具', img: 'https://via.placeholder.com/100?text=灯具' },
],
};
export const CategoryScreen = () => {
const [activeCategory, setActiveCategory] = useState<string>('fruit');
const renderCategoryItem: ListRenderItem<Category> = ({ item }) => (
<TouchableOpacity
style={[
styles.menuItem,
item.id === activeCategory && styles.menuItemActive,
]}
onPress={() => setActiveCategory(item.id)}
>
<Text
style={[
styles.menuText,
item.id === activeCategory && styles.menuTextActive,
]}
numberOfLines={1}
ellipsizeMode="tail"
>
{item.name}
</Text>
</TouchableOpacity>
);
const renderProductItem: ListRenderItem<Product> = ({ item }) => (
<View style={styles.productCard}>
<Image source={{ uri: item.img }} style={styles.productImage} />
<Text style={styles.productName} numberOfLines={1} ellipsizeMode="tail">{item.name}</Text>
</View>
);
return (
<SafeAreaView style={styles.safeArea}>
<StatusBar barStyle="dark-content" backgroundColor="#fff" />
<View style={styles.safeAreaContent}>
<View style={styles.container}>
<View style={styles.leftMenu}>
<FlatList
data={categories}
renderItem={renderCategoryItem}
keyExtractor={(item) => item.id}
/>
</View>
<View style={styles.rightContent}>
<FlatList
data={productsData[activeCategory]}
renderItem={renderProductItem}
keyExtractor={(_, index) => `${activeCategory}-${index}`}
numColumns={3}
contentContainerStyle={styles.productGrid}
/>
</View>
</View>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
safeArea: {
flex: 1,
backgroundColor: '#fff',
},
safeAreaContent: {
flex: 1,
paddingTop: Platform.OS === 'android' ? 0 : 0,
},
container: {
flex: 1,
flexDirection: 'row',
},
leftMenu: {
width: widthUtils(100,100).width,
backgroundColor: '#fff',
borderRightWidth: 1,
borderColor: '#eee',
},
menuItem: {
paddingVertical: 16,
alignItems: 'center',
borderBottomWidth: 1,
borderColor: '#f0f0f0',
},
menuItemActive: {
backgroundColor: '#f5f5f5',
},
menuText: {
fontSize: fontSize(14),
color: '#333',
},
menuTextActive: {
color: '#e60012',
fontWeight: 'bold',
},
rightContent: {
flex: 1,
backgroundColor: '#f8f8f8',
paddingHorizontal: 10,
paddingTop: 12,
},
productGrid: {
paddingBottom: 20,
},
productCard: {
flexBasis: '33.33%',
padding: 6,
alignItems: 'center',
},
productImage: {
width: '100%',
aspectRatio: 1,
borderRadius: 6,
backgroundColor: '#eee',
},
productName: {
fontSize: fontSize(13),
color: '#333',
marginTop: 6,
textAlign: 'center',
},
});