Files
project_it207_client/app/(tabs)/cart.tsx
2025-11-14 14:44:46 +07:00

253 lines
5.9 KiB
TypeScript

import React from 'react';
import {
View,
Text,
FlatList,
StyleSheet,
TouchableOpacity,
ActivityIndicator,
Alert,
RefreshControl,
} from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Ionicons } from '@expo/vector-icons';
import { useFocusEffect } from '@react-navigation/native';
import { useCart } from '../../hooks/useCart';
import CartItemCard from '../../components/CartItemCard';
export default function CartScreen() {
const {
cart,
loading,
refreshing,
refreshCart,
updateQuantity,
removeItem,
clearCart,
} = useCart();
// Tự động refresh cart mỗi khi vào trang
useFocusEffect(
React.useCallback(() => {
console.log('=== CartScreen focused - Refreshing cart ===');
refreshCart();
}, [refreshCart])
);
const handleClearCart = () => {
Alert.alert(
'Xác nhận',
'Bạn có chắc muốn xóa tất cả sản phẩm trong giỏ hàng?',
[
{ text: 'Hủy', style: 'cancel' },
{
text: 'Xóa tất cả',
onPress: clearCart,
style: 'destructive'
},
]
);
};
const handleCheckout = () => {
Alert.alert('Thông báo', 'Chức năng thanh toán đang được phát triển');
};
const formatPrice = (price: number) => {
return new Intl.NumberFormat('vi-VN', {
style: 'currency',
currency: 'VND',
}).format(price);
};
if (loading && !cart) {
return (
<SafeAreaView style={styles.container}>
<View style={styles.loadingContainer}>
<ActivityIndicator size="large" color="#ff6b6b" />
<Text style={styles.loadingText}>Đang tải giỏ hàng...</Text>
</View>
</SafeAreaView>
);
}
if (!cart || cart.items.length === 0) {
return (
<SafeAreaView style={styles.container}>
<View style={styles.header}>
<Text style={styles.headerTitle}>Giỏ hàng</Text>
</View>
<View style={styles.emptyContainer}>
<Ionicons name="cart-outline" size={100} color="#ccc" />
<Text style={styles.emptyText}>Giỏ hàng trống</Text>
<Text style={styles.emptySubtext}>
Hãy thêm sản phẩm vào giỏ hàng đ mua sắm
</Text>
</View>
</SafeAreaView>
);
}
return (
<SafeAreaView style={styles.container}>
<View style={styles.header}>
<Text style={styles.headerTitle}>Giỏ hàng</Text>
<TouchableOpacity onPress={handleClearCart} style={styles.clearButton}>
<Ionicons name="trash-outline" size={22} color="#ff4444" />
<Text style={styles.clearText}>Xóa tất cả</Text>
</TouchableOpacity>
</View>
<FlatList
data={cart.items}
keyExtractor={(item) => item.cartItemId.toString()}
renderItem={({ item }) => (
<CartItemCard
item={item}
onUpdateQuantity={updateQuantity}
onRemove={removeItem}
/>
)}
contentContainerStyle={styles.listContent}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={refreshCart}
colors={['#ff6b6b']}
/>
}
/>
<View style={styles.footer}>
<View style={styles.summaryRow}>
<Text style={styles.summaryLabel}>Tổng số lượng:</Text>
<Text style={styles.summaryValue}>{cart.totalItems} sản phẩm</Text>
</View>
<View style={styles.summaryRow}>
<Text style={styles.totalLabel}>Tổng tiền:</Text>
<Text style={styles.totalValue}>
{formatPrice(cart.totalAmount)}
</Text>
</View>
<TouchableOpacity
style={styles.checkoutButton}
onPress={handleCheckout}
>
<Text style={styles.checkoutText}>Thanh toán</Text>
<Ionicons name="arrow-forward" size={20} color="#fff" />
</TouchableOpacity>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f5f5f5',
},
header: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
padding: 16,
backgroundColor: '#fff',
borderBottomWidth: 1,
borderBottomColor: '#e0e0e0',
},
headerTitle: {
fontSize: 24,
fontWeight: '700',
color: '#333',
},
clearButton: {
flexDirection: 'row',
alignItems: 'center',
padding: 8,
},
clearText: {
fontSize: 14,
color: '#ff4444',
marginLeft: 4,
fontWeight: '500',
},
loadingContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
loadingText: {
marginTop: 12,
fontSize: 16,
color: '#666',
},
emptyContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 32,
},
emptyText: {
fontSize: 20,
fontWeight: '600',
color: '#666',
marginTop: 16,
},
emptySubtext: {
fontSize: 14,
color: '#999',
marginTop: 8,
textAlign: 'center',
},
listContent: {
padding: 16,
},
footer: {
backgroundColor: '#fff',
padding: 16,
borderTopWidth: 1,
borderTopColor: '#e0e0e0',
},
summaryRow: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 12,
},
summaryLabel: {
fontSize: 15,
color: '#666',
},
summaryValue: {
fontSize: 15,
color: '#333',
fontWeight: '500',
},
totalLabel: {
fontSize: 18,
fontWeight: '600',
color: '#333',
},
totalValue: {
fontSize: 20,
fontWeight: '700',
color: '#ff6b6b',
},
checkoutButton: {
backgroundColor: '#ff6b6b',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
padding: 16,
borderRadius: 12,
marginTop: 16,
},
checkoutText: {
fontSize: 17,
fontWeight: '700',
color: '#fff',
marginRight: 8,
},
});