253 lines
5.9 KiB
TypeScript
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,
|
|
},
|
|
}); |