import React, { useState, useEffect } from "react";
import { View, ScrollView, Alert, TextInput, ActivityIndicator, KeyboardAvoidingView, Platform } from "react-native";
import { Image } from 'expo-image';
import { useLocalSearchParams, useRouter } from "expo-router";
import { AppContainer, MyText, tw, MyTouchableOpacity, theme, BottomDialog } from "common-ui";
import { trpc } from "@/src/trpc-client";
import MaterialIcons from "@expo/vector-icons/MaterialIcons";
import Ionicons from '@expo/vector-icons/Ionicons';
import dayjs from "dayjs";
import ComplaintForm from "@/components/ComplaintForm";
export default function OrderDetails() {
const { id } = useLocalSearchParams<{ id: string }>();
const router = useRouter();
const {
data: orderData,
isLoading,
error,
refetch,
} = trpc.user.order.getOrderById.useQuery(
{ orderId: id },
{ enabled: !!id }
);
const [isEditingNotes, setIsEditingNotes] = useState(false);
const [notesText, setNotesText] = useState("");
const [notesInput, setNotesInput] = useState("");
const [cancelDialogOpen, setCancelDialogOpen] = useState(false);
const [cancelReason, setCancelReason] = useState("");
const [complaintDialogOpen, setComplaintDialogOpen] = useState(false);
const updateNotesMutation = trpc.user.order.updateUserNotes.useMutation({
onSuccess: () => {
setNotesText(notesInput);
setIsEditingNotes(false);
refetch();
Alert.alert('Success', 'Notes updated successfully');
},
onError: (error: any) => {
Alert.alert('Error', error.message || 'Failed to update notes');
},
});
const cancelOrderMutation = trpc.user.order.cancelOrder.useMutation({
onSuccess: () => {
setCancelDialogOpen(false);
setCancelReason("");
refetch();
Alert.alert('Success', 'Order cancelled successfully');
},
onError: (error: any) => {
Alert.alert('Error', error.message || 'Failed to cancel order');
},
});
const handleCancelOrder = () => {
if (!cancelReason.trim()) {
Alert.alert('Error', 'Please enter a reason for cancellation');
return;
}
cancelOrderMutation.mutate({ id: order.orderId, reason: cancelReason });
};
useEffect(() => {
if (orderData?.userNotes) {
setNotesText(orderData.userNotes);
setNotesInput(orderData.userNotes);
}
}, [orderData]);
if (isLoading) {
return (
Loading details...
);
}
if (error || !orderData) {
return (
Failed to load
router.back()}
style={tw`mt-6 bg-slate-900 px-6 py-2 rounded-xl`}
>
Go Back
);
}
const order = orderData;
const getStatusConfig = (status: string) => {
const s = status.toLowerCase();
switch (s) {
case "delivered":
case "success":
return { label: "Delivered", color: "#10B981" };
case "cancelled":
case "failed":
return { label: "Cancelled", color: "#EF4444" };
case "pending":
case "processing":
return { label: "Pending", color: "#F59E0B" };
default:
return { label: status, color: theme.colors.brand500 };
}
};
const subtotal = order.items.reduce((sum, item) => sum + item.amount, 0);
const discountAmount = order.discountAmount || 0;
const totalAmount = order.orderAmount;
const statusConfig = getStatusConfig(order.deliveryStatus || "pending");
return (
{/* Simple Header */}
Order #{order.orderId}
{dayjs(order.orderDate).format("DD MMM, h:mm A")}
{order.isFlashDelivery && (
⚡ 30-Minute Flash Delivery
)}
{statusConfig.label}
{order.isFlashDelivery && (
⚡
)}
{/* Flash Delivery Banner */}
{order.isFlashDelivery && (
Flash Delivery Order
Your order will be delivered within 30 minutes of placement
)}
{/* Main Info Card */}
Payment Method
{order.paymentMode?.toUpperCase() === "COD" ? "Cash on Delivery" : order.paymentMode}
Status
{order.paymentStatus}
{(order.deliveryDate || order.isFlashDelivery) && ["delivered", "success"].includes(order.deliveryStatus?.toLowerCase() || "") && (
{order.isFlashDelivery ? (
) : (
)}
{order.isFlashDelivery
? `Flash Delivered on ${dayjs(order.createdAt || order.orderDate).add(30, 'minutes').format("DD MMM YYYY, h:mm A")}`
: `Delivered on ${dayjs(order.deliveryDate).format("DD MMM YYYY, h:mm A")}`
}
)}
{/* Flash Delivery Info */}
{order.isFlashDelivery && !["delivered", "success"].includes(order.deliveryStatus?.toLowerCase() || "") && (
Flash Delivery: {dayjs(order.createdAt || order.orderDate).add(30, 'minutes').format("DD MMM YYYY, h:mm A")}
)}
{/* Special Instructions */}
Special Instructions
{isEditingNotes ? (
{
setIsEditingNotes(false);
setNotesInput(notesText);
}}
style={tw`px-3 py-1 bg-slate-100 rounded-lg`}
>
Cancel
{
updateNotesMutation.mutate({ id: order.orderId, userNotes: notesInput });
}}
disabled={updateNotesMutation.isPending}
style={tw`px-3 py-1 bg-brand500 rounded-lg`}
>
{updateNotesMutation.isPending ? 'Saving...' : 'Save'}
) : (
{
setNotesInput(notesText || "");
setIsEditingNotes(true);
}}
style={tw`flex-row items-center px-2 py-1 bg-slate-50 rounded-lg`}
>
{notesText ? 'Edit' : 'Add'}
)}
{isEditingNotes ? (
) : (
{notesText || "No instructions added"}
)}
{/* Cancellation Detail */}
{order.cancelReason && (
Cancellation Reason
{order.cancelReason}
{order.refundAmount && (
Refund Amount
₹{order.refundAmount}
)}
)}
{/* Items Section */}
Order Items
{order.items.map((item: any, index: number) => (
{item.productName}
{item.quantity} × ₹{item.price}
₹{item.amount}
))}
{/* Coupon */}
{order.couponCode && (
{order.couponCode}
Coupon Applied
-₹{order.discountAmount}
)}
{/* Summary Section */}
Subtotal
₹{subtotal}
{discountAmount > 0 && (
Discount
-₹{discountAmount}
)}
Total Amount
₹{totalAmount}
{/* Footer Actions */}
router.back()}
style={tw`flex-1 bg-slate-100 py-3.5 rounded-xl items-center`}
>
Dismiss
setComplaintDialogOpen(true)}
style={[tw`flex-1 py-3.5 rounded-xl items-center`, { backgroundColor: theme.colors.brand600 }]}
>
Raise Complaint
{/* Additional Actions */}
{order.deliveryStatus !== 'success' && order.deliveryStatus !== 'cancelled' && (
setCancelDialogOpen(true)}
style={tw`bg-red-50 border border-red-100 py-3.5 rounded-xl items-center flex-row justify-center`}
>
Cancel Order
)}
{/* Cancel Order Dialog */}
setCancelDialogOpen(false)}>
Cancel Order
setCancelDialogOpen(false)}>
Are you sure you want to cancel this order? This action cannot be undone.
Reason for cancellation
{cancelOrderMutation.isPending ? (
) : (
Confirm Cancellation
)}
{/* Raise Complaint Dialog */}
setComplaintDialogOpen(false)}>
{
setComplaintDialogOpen(false);
refetch();
}}
orderId={order.orderId}
/>
);
}