import React, { useEffect, useState, useCallback } from 'react'; import { View, Text, ScrollView, ActivityIndicator, TouchableOpacity, } from 'react-native'; import { useRoute, useNavigation } from '@react-navigation/native'; import { StackNavigationProp } from '@react-navigation/stack'; import { RouteProp } from '@react-navigation/native'; import { Header, OrderStatusTimeline, ProductRatingModal } from '@components'; import { useAppTheme } from '@theme'; import { getStyles } from './orderDetailsScreen.styles'; import { RootState, useAppDispatch, useAppSelector } from '@store'; import { getOrderByIdThunk } from '../checkoutPaymentScreen'; import { formatDate, formatTime } from '@utils/helper'; import { submitReview } from './thunk'; import { giveRatingPayload, OrderItem } from '@interfaces'; import { AppStackParamList } from '@navigation'; type OrderDetailsRouteProp = RouteProp; type OrderDetailsNavProp = StackNavigationProp; export const OrderDetailsScreen: React.FC = () => { const { colors } = useAppTheme(); const styles = getStyles(colors); const route = useRoute(); const navigation = useNavigation(); const dispatch = useAppDispatch(); const orderId = route.params?.orderId; const { orderDetails, orderDetailsLoading, orderDetailsError } = useAppSelector((state: RootState) => state.paymentMethods); // ── Rating modal state ──────────────────────────────────────────────────── const [ratingModalItem, setRatingModalItem] = useState( null, ); /** Tracks which productIds have already been rated this session */ const [ratedProductIds, setRatedProductIds] = useState>( new Set(), ); const isDelivered = orderDetails?.status === 'DELIVERED'; useEffect(() => { if (orderId) { dispatch(getOrderByIdThunk(orderId)); } }, [dispatch, orderId]); const handleRatingSubmit = useCallback( (payload: giveRatingPayload) => { if (!ratingModalItem) return; // Dispatch the API call: POST /products/:productId/ratings dispatch( submitReview({ id: ratingModalItem.productId, payload: { rating: payload.rating, comment: payload.comment, images: payload.images, orderId: orderDetails?.id ?? '', }, }), ) .unwrap() .then(() => { setRatedProductIds(prev => new Set(prev).add(ratingModalItem.productId), ); }); }, [dispatch, ratingModalItem, orderDetails?.id], ); const handleModalClose = useCallback(() => { setRatingModalItem(null); }, []); // ── Loading ─────────────────────────────────────────────────────────────── if (orderDetailsLoading) { return (
navigation.goBack()} /> Fetching order details... ); } if (orderDetailsError || !orderDetails) { return (
navigation.goBack()} /> {orderDetailsError || 'Could not load order details.'} ); } const orderDate = orderDetails.createdAt ? `${formatDate(orderDetails.createdAt)} at ${formatTime( orderDetails.createdAt, )}` : ''; return (
navigation.goBack()} /> {/* Top Info Section */} Order {orderDetails.orderNumber?.split('-').pop() || ''} {orderDetails.status} Placed on {orderDate} Payment: {orderDetails.paymentMethod} {/* Merchant Info */} 🏪 {orderDetails.merchant?.name || 'Store'} {/* Order Status Timeline Section */} Order Status {/* Order Items Section */} Order Items {/* Rate all hint — shown only when delivered */} {isDelivered && ( Tap any item below to rate it )} {orderDetails.orderItems?.map((item, index) => { const isRated = ratedProductIds.has(item.productId); return ( { if (isDelivered) { setRatingModalItem(item); } }} disabled={!isDelivered} > {item.quantity}x {item.name} {/* Rating status pill — only shown when DELIVERED */} {isDelivered && ( {isRated ? ( ✓ Rated ) : ( ⭐ Rate this )} )} ₹{item.totalAmount} ); })} {/* Bill Summary Section */} Bill Summary Item Total ₹{orderDetails.subtotal} Delivery Fee ₹{orderDetails.deliveryFee} Platform Fee ₹{orderDetails.platformFee} Taxes ₹{orderDetails.taxAmount} Grand Total ₹{orderDetails.totalAmount} {/* Delivery Address Section */} Delivery Details {orderDetails.dropAddress?.label || 'Home'} {orderDetails.dropAddress?.houseNumber ? `${orderDetails.dropAddress.houseNumber}, ` : ''} {orderDetails.dropAddress?.addressLine1} {orderDetails.dropAddress?.landmark ? `Landmark: ${orderDetails.dropAddress.landmark}` : ''} Phone: {orderDetails.dropAddress?.phone} {/* Payment Info */} {orderDetails.payments && orderDetails.payments.length > 0 && ( Payment Details 💳 Paid via {orderDetails.payments[0].method} ( {orderDetails.payments[0].status}) )} {/* Product Rating Modal */} ); }; export default OrderDetailsScreen;