import React, { useEffect, useState } from 'react'; import { View, Text, FlatList, Image, TouchableOpacity, StyleSheet, ActivityIndicator, RefreshControl, Alert, } from 'react-native'; import { AntDesign, MaterialCommunityIcons } from '@expo/vector-icons'; import { useWishlist } from '../../hooks/useWishlist'; const COLORS = { primary: '#FF6B6B', secondary: '#4ECDC4', background: '#F7F9FC', white: '#FFFFFF', text: '#2C3E50', lightText: '#95A5A6', border: '#E0E0E0', success: '#27AE60', }; interface WishlistItem { id?: number; wishlistId?: number; productId: number; productName: string; productImage: string; price: number; description: string; addedAt: string; } const WishlistScreen = () => { const { wishlists, loading, error, totalElements, currentPage, totalPages, fetchWishlists, removeFromWishlist, clearError, } = useWishlist(); const [refreshing, setRefreshing] = useState(false); const [currentSort, setCurrentSort] = useState<'createdAt' | 'price' | 'name'>('createdAt'); useEffect(() => { fetchWishlists(0, 10, currentSort); }, [currentSort, fetchWishlists]); useEffect(() => { if (error) { Alert.alert('Lỗi', error, [{ text: 'OK', onPress: clearError }]); } }, [error, clearError]); const handleRefresh = async () => { setRefreshing(true); await fetchWishlists(currentPage, 10, currentSort); setRefreshing(false); }; const handleRemoveFromWishlist = (item: WishlistItem) => { Alert.alert( 'Xóa khỏi ưu thích', `Bạn có chắc chắn muốn xóa "${item.productName}" khỏi danh sách ưu thích?`, [ { text: 'Hủy', onPress: () => {}, style: 'cancel' }, { text: 'Xóa', onPress: async () => { const result = await removeFromWishlist(item.productId); if (result.success) { Alert.alert('Thành công', result.message); } else { Alert.alert('Lỗi', result.message); } }, style: 'destructive', }, ] ); }; const handleLoadMore = () => { if (currentPage < totalPages - 1 && !loading) { fetchWishlists(currentPage + 1, 10, currentSort); } }; const formatPrice = (price: number) => { return new Intl.NumberFormat('vi-VN', { style: 'currency', currency: 'VND', }).format(price); }; const formatDate = (dateString: string) => { const date = new Date(dateString); return date.toLocaleDateString('vi-VN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', }); }; const renderWishlistItem = ({ item }: { item: WishlistItem | any }) => { // Kiểm tra dữ liệu hợp lệ if (!item || !item.productId) { return null; } return ( {item.productName} {item.description} {formatPrice(item.price)} {formatDate(item.addedAt)} handleRemoveFromWishlist(item)} > ); }; const renderEmptyState = () => ( Danh sách ưu thích trống Thêm những sản phẩm yêu thích của bạn vào đây ); return ( {/* Header */} Danh sách ưu thích {totalElements} {/* Sort Options */} setCurrentSort('createdAt')} > Mới nhất setCurrentSort('price')} > Giá setCurrentSort('name')} > Tên {/* Content */} {loading && wishlists.length === 0 ? ( Đang tải... ) : ( { // Use only item.id with fallback to index to ensure proper typing return item?.id?.toString() ?? index.toString(); }} contentContainerStyle={styles.listContent} ListEmptyComponent={renderEmptyState()} refreshControl={ } onEndReached={handleLoadMore} onEndReachedThreshold={0.5} ListFooterComponent={ loading && wishlists.length > 0 ? ( ) : null } /> )} {/* Pagination Info */} {totalElements > 0 && ( Trang {currentPage + 1}/{totalPages} )} ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: COLORS.background, }, header: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingHorizontal: 16, paddingVertical: 16, backgroundColor: COLORS.white, borderBottomWidth: 1, borderBottomColor: COLORS.border, }, headerTitle: { fontSize: 24, fontWeight: '700', color: COLORS.text, }, countBadge: { backgroundColor: COLORS.primary, borderRadius: 20, paddingHorizontal: 12, paddingVertical: 6, }, countText: { color: COLORS.white, fontWeight: '600', fontSize: 12, }, sortContainer: { flexDirection: 'row', paddingHorizontal: 16, paddingVertical: 12, backgroundColor: COLORS.white, gap: 8, }, sortButton: { paddingHorizontal: 12, paddingVertical: 8, borderRadius: 20, borderWidth: 1, borderColor: COLORS.border, backgroundColor: COLORS.white, }, sortButtonActive: { backgroundColor: COLORS.primary, borderColor: COLORS.primary, }, sortButtonText: { fontSize: 12, fontWeight: '600', color: COLORS.text, }, sortButtonTextActive: { color: COLORS.white, }, listContent: { paddingHorizontal: 16, paddingTop: 12, paddingBottom: 20, }, itemContainer: { flexDirection: 'row', backgroundColor: COLORS.white, borderRadius: 12, marginBottom: 12, overflow: 'hidden', shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 4, elevation: 3, }, itemImage: { width: 100, height: 120, backgroundColor: COLORS.background, }, itemContent: { flex: 1, paddingHorizontal: 12, paddingVertical: 10, justifyContent: 'space-between', }, itemName: { fontSize: 14, fontWeight: '700', color: COLORS.text, marginBottom: 4, }, itemDescription: { fontSize: 12, color: COLORS.lightText, marginBottom: 8, }, priceContainer: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', }, price: { fontSize: 14, fontWeight: '700', color: COLORS.primary, }, addedDate: { fontSize: 10, color: COLORS.lightText, }, deleteButton: { justifyContent: 'center', alignItems: 'center', paddingHorizontal: 12, paddingVertical: 10, }, centerContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', }, loadingText: { marginTop: 12, fontSize: 14, color: COLORS.lightText, }, emptyContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', paddingHorizontal: 32, }, emptyText: { fontSize: 18, fontWeight: '700', color: COLORS.text, marginTop: 16, }, emptySubText: { fontSize: 14, color: COLORS.lightText, marginTop: 8, textAlign: 'center', }, footerLoader: { paddingVertical: 16, justifyContent: 'center', alignItems: 'center', }, paginationInfo: { paddingHorizontal: 16, paddingVertical: 12, backgroundColor: COLORS.white, borderTopWidth: 1, borderTopColor: COLORS.border, alignItems: 'center', }, paginationText: { fontSize: 12, color: COLORS.lightText, fontWeight: '600', }, }); export default WishlistScreen;