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.

196 lines
4.7 KiB

3 weeks ago
import React, { useState, useEffect } from 'react';
import {
View,
Text,
FlatList,
TouchableOpacity,
StyleSheet,
Image,
Dimensions,
ListRenderItem,
3 weeks ago
Platform,
StatusBar,
3 weeks ago
SafeAreaView,
ActivityIndicator
} from 'react-native';
import fontSize from '../utils/fontsizeUtils';
import widthUtils from '../utils/widthUtils';
3 weeks ago
import { categoriesApi, Category } from '../services/api/categories';
3 weeks ago
export const CategoryScreen = () => {
const [mainCategories, setMainCategories] = useState<Category[]>([]);
const [subCategories, setSubCategories] = useState<Category[]>([]);
const [activeMainCategory, setActiveMainCategory] = useState<number | null>(null);
const [loading, setLoading] = useState(true);
const [subLoading, setSubLoading] = useState(false);
3 weeks ago
useEffect(() => {
fetchMainCategories();
}, []);
3 weeks ago
useEffect(() => {
if (activeMainCategory) {
fetchSubCategories(activeMainCategory);
}
}, [activeMainCategory]);
3 weeks ago
const fetchMainCategories = async () => {
try {
const response = await categoriesApi.getCategories();
setMainCategories(response);
if (response.length > 0) {
setActiveMainCategory(response[0].category_id);
}
} catch (error) {
console.error('Error fetching main categories:', error);
} finally {
setLoading(false);
}
};
2 months ago
3 weeks ago
const fetchSubCategories = async (parentId: number) => {
setSubLoading(true);
try {
const response = await categoriesApi.getCategory(parentId);
if (Array.isArray(response)) {
setSubCategories(response);
}
} catch (error) {
console.error('Error fetching sub categories:', error);
} finally {
setSubLoading(false);
}
};
3 weeks ago
const renderMainCategoryItem: ListRenderItem<Category> = ({ item }) => (
<TouchableOpacity
style={[
styles.menuItem,
3 weeks ago
item.category_id === activeMainCategory && styles.menuItemActive,
]}
3 weeks ago
onPress={() => setActiveMainCategory(item.category_id)}
>
<Text
style={[
styles.menuText,
3 weeks ago
item.category_id === activeMainCategory && styles.menuTextActive,
]}
numberOfLines={1}
ellipsizeMode="tail"
>
3 weeks ago
{item.name_cn}
</Text>
</TouchableOpacity>
);
3 weeks ago
const renderSubCategoryItem: ListRenderItem<Category> = ({ item }) => (
<TouchableOpacity
style={[
styles.menuItem,
]}
onPress={() => {}}
>
<Text
style={styles.menuText}
numberOfLines={1}
ellipsizeMode="tail"
>
{item.name_cn}
</Text>
</TouchableOpacity>
);
2 months ago
3 weeks ago
if (loading) {
return (
<View style={styles.loadingContainer}>
<ActivityIndicator size="large" color="#e60012" />
</View>
);
}
return (
3 weeks ago
<SafeAreaView style={styles.safeArea}>
<StatusBar barStyle="dark-content" backgroundColor="#fff" />
<View style={styles.safeAreaContent}>
<View style={styles.container}>
<View style={styles.leftMenu}>
<FlatList
3 weeks ago
data={mainCategories}
renderItem={renderMainCategoryItem}
keyExtractor={(item) => item.category_id.toString()}
3 weeks ago
/>
</View>
<View style={styles.rightContent}>
3 weeks ago
{subLoading ? (
<View style={styles.loadingContainer}>
<ActivityIndicator size="large" color="#e60012" />
</View>
) : (
<FlatList
data={subCategories}
renderItem={renderSubCategoryItem}
keyExtractor={(item) => item.category_id.toString()}
numColumns={3}
contentContainerStyle={styles.productGrid}
/>
)}
3 weeks ago
</View>
</View>
</View>
3 weeks ago
</SafeAreaView>
);
}
const styles = StyleSheet.create({
3 weeks ago
safeArea: {
flex: 1,
backgroundColor: '#fff',
},
safeAreaContent: {
flex: 1,
paddingTop: Platform.OS === 'android' ? 0 : 0,
3 weeks ago
},
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: {
2 months ago
flex: 1,
backgroundColor: '#f8f8f8',
paddingHorizontal: 10,
paddingTop: 12,
2 months ago
},
productGrid: {
paddingBottom: 20,
2 months ago
},
3 weeks ago
loadingContainer: {
flex: 1,
justifyContent: 'center',
2 months ago
alignItems: 'center',
3 weeks ago
backgroundColor: '#fff',
2 months ago
},
});