122 lines
4.8 KiB
React
122 lines
4.8 KiB
React
import { View, Text, Image, TouchableOpacity, ActivityIndicator, Alert } from 'react-native'
|
|
import React, { useState } from 'react'
|
|
import { useNavigation } from '@react-navigation/native'
|
|
import { fetchProductById } from '../api'
|
|
|
|
export default function CancelledOrder({ orders = [], navigation: propNavigation }) {
|
|
// Use provided navigation prop if available, otherwise get from hook
|
|
const navigation = propNavigation || useNavigation();
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
// Safe number formatting helper
|
|
const formatCurrency = (value) => {
|
|
if (value === undefined || value === null) return '0.00';
|
|
if (typeof value === 'number') return value.toFixed(2);
|
|
if (typeof value === 'string') {
|
|
const num = parseFloat(value);
|
|
return isNaN(num) ? '0.00' : num.toFixed(2);
|
|
}
|
|
return '0.00';
|
|
};
|
|
|
|
const handleReOrder = async (order) => {
|
|
console.log('Order data:', order);
|
|
|
|
// Use order_items as primary source, fallback to items if order_items is empty
|
|
const orderItems = (order.order_items && order.order_items.length > 0) ? order.order_items : order.items;
|
|
console.log('Order items:', orderItems);
|
|
|
|
if (!orderItems || orderItems.length === 0) {
|
|
Alert.alert('Error', 'No items found in this order');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
setLoading(true);
|
|
const firstItem = orderItems[0];
|
|
console.log('First item:', firstItem);
|
|
|
|
const productId = firstItem.product || firstItem.product_id || firstItem.id;
|
|
console.log('Product ID:', productId);
|
|
|
|
if (!productId) {
|
|
Alert.alert('Error', 'Could not find product ID');
|
|
return;
|
|
}
|
|
|
|
const product = await fetchProductById(productId);
|
|
console.log('Fetched product:', product);
|
|
|
|
if (!product) {
|
|
Alert.alert('Error', 'Product not found');
|
|
return;
|
|
}
|
|
|
|
navigation.navigate('ProductDetails', { id: product.id });
|
|
} catch (error) {
|
|
console.error('Error in handleReOrder:', error);
|
|
Alert.alert('Error', 'Failed to load product details. Please try again.');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
if (!orders || orders.length === 0) {
|
|
return (
|
|
<View className="flex-1 justify-center items-center py-10">
|
|
<Text className="text-gray-500">No cancelled orders found</Text>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<View className={`mx-4`}>
|
|
{orders.map((order, index) => {
|
|
const orderItems = (order.order_items && order.order_items.length > 0) ? order.order_items : order.items;
|
|
return (
|
|
<View key={index} className="mb-6 border rounded-lg border-gray-200 overflow-hidden">
|
|
<View className="bg-gray-100 p-3 border-b border-gray-200">
|
|
<Text className="font-bold">Order #{order.id}</Text>
|
|
<Text className="text-gray-500">
|
|
{new Date(order.created_at || order.date).toLocaleDateString()} |
|
|
Status: <Text className="text-red-500 font-medium capitalize">{order.status}</Text>
|
|
</Text>
|
|
</View>
|
|
|
|
{orderItems && orderItems.map((item, itemIndex) => (
|
|
<View key={itemIndex} className={`flex-row items-center gap-6 py-3 px-3 ${itemIndex < orderItems.length - 1 ? 'border-b border-gray-200' : ''}`}>
|
|
<Image
|
|
source={{ uri: item.product_image || item.product?.image || 'https://via.placeholder.com/100' }}
|
|
className="size-[90px] rounded-lg"
|
|
defaultSource={require('../../assets/images/favicon.png')}
|
|
/>
|
|
<View className={`flex-1 flex-col gap-2`}>
|
|
<Text className={`font-medium text-lg`}>{item.product_name || item.product?.title || 'Product'}</Text>
|
|
<Text className={`text-sm`}>Qty: {item.quantity}</Text>
|
|
<View className={`flex-row justify-between items-start`}>
|
|
<Text className={`text-lg font-bold`}>${formatCurrency(item.price || item.subtotal)}</Text>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
))}
|
|
|
|
<View className="bg-gray-50 p-3 border-t border-gray-200 flex-row justify-between items-center">
|
|
<Text className="font-bold">Total: ${formatCurrency(order.total_price || order.total_amount)}</Text>
|
|
<TouchableOpacity
|
|
onPress={() => handleReOrder(order)}
|
|
className={`bg-primary rounded-full px-4 py-2`}
|
|
disabled={loading}
|
|
>
|
|
{loading ? (
|
|
<ActivityIndicator color="white" />
|
|
) : (
|
|
<Text className={`text-white font-medium`}>Re-Order</Text>
|
|
)}
|
|
</TouchableOpacity>
|
|
</View>
|
|
</View>
|
|
);
|
|
})}
|
|
</View>
|
|
);
|
|
} |