import React, { useState , useEffect } from 'react';
import { View, TouchableOpacity, Alert, TextInput, ActivityIndicator } from 'react-native';
import { AppContainer, MyText, tw, MyFlatList, BottomDialog, BottomDropdown, Checkbox, theme, MyTextInput } from 'common-ui';
import { trpc } from '../../../src/trpc-client';
import { useRouter, useLocalSearchParams } from 'expo-router';
import dayjs from 'dayjs';
import MaterialIcons from '@expo/vector-icons/MaterialIcons';
import { Entypo } from '@expo/vector-icons';
import CancelOrderDialog from '@/components/CancelOrderDialog';
const AdminNotesForm = ({ orderId, existingNotes, onClose, refetch }: { orderId: string; existingNotes?: string | null; onClose: () => void; refetch: () => void }) => {
const [notesText, setNotesText] = useState(existingNotes || '');
const updateNotesMutation = trpc.admin.order.updateNotes.useMutation();
return (
Admin Notes
{
updateNotesMutation.mutate(
{ orderId: parseInt(orderId), adminNotes: notesText },
{
onSuccess: () => {
onClose();
Alert.alert('Success', 'Notes updated successfully');
refetch();
},
onError: (error: any) => {
Alert.alert('Error', error.message || 'Failed to update notes');
},
}
);
}}
>
Save
);
};
interface OrderType {
id: number;
orderId: string;
readableId: number;
customerName: string | null;
address: string;
totalAmount: number;
deliveryCharge: number;
items: {
id?: number;
name: string;
quantity: number;
price: number;
amount: number;
unit: string;
isPackaged?: boolean;
isPackageVerified?: boolean;
}[];
createdAt: string;
deliveryTime: string | null;
status: 'pending' | 'delivered' | 'cancelled';
isPackaged: boolean;
isDelivered: boolean;
isCod: boolean;
isFlashDelivery: boolean;
couponCode?: string;
couponDescription?: string;
discountAmount?: number;
adminNotes?: string | null;
userNotes?: string | null;
}
const OrderItem = ({ order, refetch }: { order: OrderType; refetch: () => void }) => {
const id = order.orderId;
const router = useRouter();
const [menuOpen, setMenuOpen] = useState(false);
const [itemsDialogOpen, setItemsDialogOpen] = useState(false);
const [notesDialogOpen, setNotesDialogOpen] = useState(false);
const [cancelDialogOpen, setCancelDialogOpen] = useState(false);
const [userNotesDialogOpen, setUserNotesDialogOpen] = useState(false);
const [adminNotesDialogOpen, setAdminNotesDialogOpen] = useState(false);
const [updatingItems, setUpdatingItems] = useState>(new Set());
const updatePackagedMutation = trpc.admin.order.updatePackaged.useMutation();
const updateDeliveredMutation = trpc.admin.order.updateDelivered.useMutation();
const updateItemPackagingMutation = trpc.admin.order.updateOrderItemPackaging.useMutation();
const handleOrderPress = () => {
router.push(`/order-details/${order.orderId}` as any);
};
const handleMenuOption = () => {
setMenuOpen(false);
router.push(`/order-details/${order.orderId}` as any);
};
const handleMarkPackaged = (isPackaged: boolean) => {
updatePackagedMutation.mutate(
{ orderId: order.orderId.toString(), isPackaged },
{
onSuccess: () => {
setMenuOpen(false);
refetch();
},
}
);
};
const handleMarkDelivered = (isDelivered: boolean) => {
updateDeliveredMutation.mutate(
{ orderId: order.orderId.toString(), isDelivered },
{
onSuccess: () => {
setMenuOpen(false);
refetch();
},
}
);
};
const handleItemPackagingToggle = (itemId: number, field: 'isPackaged' | 'isPackageVerified', value: boolean) => {
setUpdatingItems(prev => new Set(prev).add(itemId));
updateItemPackagingMutation.mutate(
{ orderItemId: itemId, [field]: value },
{
onSuccess: () => {
setUpdatingItems(prev => {
const newSet = new Set(prev);
newSet.delete(itemId);
return newSet;
});
refetch();
},
onError: (error: any) => {
setUpdatingItems(prev => {
const newSet = new Set(prev);
newSet.delete(itemId);
return newSet;
});
Alert.alert("Error", error.message || "Failed to update packaging status");
},
}
);
};
const getStatusColor = (status: string) => {
switch (status) {
case 'delivered': return 'bg-green-100 text-green-800';
case 'cancelled': return 'bg-red-100 text-red-800';
default: return 'bg-yellow-100 text-yellow-800';
}
};
if(order.id === 162)
console.log({order})
return (
<>
{/* Header Section */}
{order.customerName || 'Unknown Customer'}
#{order.readableId}
{order.isFlashDelivery && (
FLASH
)}
{dayjs(order.createdAt).format('MMM D, h:mm A')}
setMenuOpen(true)}
style={tw`p-2 -mr-2 -mt-2 rounded-full`}
>
{/* Main Content */}
{/* Status Badges */}
{/*
{order.status}
*/}
{/* {order.isCod && (
COD
)} */}
Packaged
handleMarkPackaged(!order.isPackaged)}
onPress={() => {}}
size={18}
fillColor={theme.colors.gray500}
checkColor="#FFFFFF"
/>
Delivered
handleMarkDelivered(!order.isDelivered)}
size={18}
fillColor="#10B981"
checkColor="#FFFFFF"
/>
{/* Delivery Info */}
Delivery Address
{order.address}
{order.isFlashDelivery ? "Flash Delivery:" : "Slot:"} {order.isFlashDelivery ? dayjs(order.createdAt).add(30, 'minutes').format('MMM D, h:mm A') : order.deliveryTime ? dayjs(order.deliveryTime).format("ddd, MMM D • h:mm A") : 'Not scheduled'}
{order.isFlashDelivery && (
30-Minute Delivery • High Priority
)}
{/* Items Summary & Total */}
setItemsDialogOpen(true)}
style={tw`flex-row items-center py-2 px-3 bg-blue-50 rounded-lg flex-1 mr-3`}
>
{order.items.length} {order.items.length === 1 ? 'item' : 'items'}
{order.isFlashDelivery && (
⚡
)}
Total:
₹{order.totalAmount}
{/* Coupons */}
{order.couponCode && (
Applied Coupons
{order.couponCode}
{order.couponDescription && (
{order.couponDescription}
)}
{order.discountAmount && (
Discount: ₹{order.discountAmount}
)}
)}
{/* Notes Section */}
{order.userNotes && (
setUserNotesDialogOpen(true)}
>
User Notes
)}
{order.adminNotes && (
setNotesDialogOpen(true)}
>
Admin Notes
)}
{/* Footer / Delivery Charge */}
{order.deliveryCharge > 0 && (
Delivery Charge
₹{order.deliveryCharge}
)}
setMenuOpen(false)}>
Order Options
{order.isFlashDelivery && (
Flash Delivery Order
Deliver within 30 minutes • High Priority
)}
handleMarkPackaged(!order.isPackaged)}
>
{order.isPackaged ? 'Mark Not Packaged' : 'Mark Packaged'}
{order.isPackaged && (
handleMarkDelivered(!order.isDelivered)}
>
{order.isDelivered ? 'Mark Not Delivered' : 'Mark Delivered'}
)}
Order Details
{
setMenuOpen(false);
setNotesDialogOpen(true);
}}
>
Admin Notes
{order.status !== 'cancelled' && (
{
setMenuOpen(false);
setCancelDialogOpen(true);
}}
>
Cancel Order
)}
setItemsDialogOpen(false)}>
Order Items
{order.isFlashDelivery && (
FLASH
)}
Total: ₹{order.totalAmount}
{order.items.map((item, idx) => (
{item.quantity} {item.unit}
{item.name.length > 30 ? `${item.name.substring(0, 30)}...` : item.name}
{item.isPackaged !== undefined && item.isPackageVerified !== undefined && (
<>
pkg
handleItemPackagingToggle(item.id!, 'isPackaged', !item.isPackaged)}
size={18}
fillColor={updatingItems.has(item.id!) ? "#F59E0B" : "#10B981"}
checkColor="#FFFFFF"
/>
verf
handleItemPackagingToggle(item.id!, 'isPackageVerified', !item.isPackageVerified)}
size={18}
fillColor={updatingItems.has(item.id!) ? "#F59E0B" : "#10B981"}
checkColor="#FFFFFF"
/>
{updatingItems.has(item.id!) && (
)}
>
)}
))}
setNotesDialogOpen(false)}>
setNotesDialogOpen(false)} refetch={refetch} />
setCancelDialogOpen(false)}
onSuccess={refetch}
/>
setUserNotesDialogOpen(false)}>
User Notes
{order.userNotes}
setAdminNotesDialogOpen(false)}>
Admin Notes
{order.adminNotes}
>
);
};
export default function Orders() {
const router = useRouter();
const { filter } = useLocalSearchParams<{ filter?: string }>();
const [selectedSlot, setSelectedSlot] = useState(null);
const [selectedSlotType, setSelectedSlotType] = useState<'slot' | 'flash' | null>(null);
const [packagedFilter, setPackagedFilter] = useState<'all' | 'packaged' | 'not_packaged'>('all');
const [packagedChecked, setPackagedChecked] = useState(false);
const [notPackagedChecked, setNotPackagedChecked] = useState(false);
const [deliveredFilter, setDeliveredFilter] = useState<'all' | 'delivered' | 'not_delivered'>('all');
const [deliveredChecked, setDeliveredChecked] = useState(false);
const [notDeliveredChecked, setNotDeliveredChecked] = useState(false);
const [cancellationFilter, setCancellationFilter] = useState<'all' | 'cancelled' | 'not_cancelled'>('all');
const [cancelledChecked, setCancelledChecked] = useState(false);
const [notCancelledChecked, setNotCancelledChecked] = useState(false);
const [flashDeliveryFilter, setFlashDeliveryFilter] = useState<'all' | 'flash' | 'regular'>('all');
const [flashChecked, setFlashChecked] = useState(false);
const [regularChecked, setRegularChecked] = useState(false);
const [filterDialogOpen, setFilterDialogOpen] = useState(false);
// Handle initial filter from URL params
useEffect(() => {
if (filter === 'flash') {
setSelectedSlotType('flash');
setFlashDeliveryFilter('flash');
setFlashChecked(true);
setRegularChecked(false);
}
}, [filter]);
const { data: slotsData } = trpc.admin.slots.getAll.useQuery();
const { data, isLoading, isFetchingNextPage, fetchNextPage, hasNextPage, refetch } = trpc.admin.order.getAll.useInfiniteQuery(
{
limit: 20,
slotId: selectedSlotType === 'slot' ? selectedSlot : null,
packagedFilter,
deliveredFilter,
cancellationFilter,
flashDeliveryFilter: selectedSlotType === 'flash' ? 'flash' : flashDeliveryFilter
},
{
getNextPageParam: (lastPage) => lastPage?.nextCursor,
}
);
const orders = data?.pages.flatMap(page => page?.orders) || [];
if (isLoading) {
return (
Loading orders...
);
}
const slotOptions = [
{ label: '⚡ Flash Deliveries', value: 'flash' },
...(slotsData?.slots?.map(slot => ({
label: dayjs(slot.deliveryTime).format('ddd DD MMM, h:mm a'),
value: slot.id.toString(),
})) || [])
];
return (
<>
item!.orderId}
renderItem={({ item }) => item ? : null}
onEndReached={() => {
if (hasNextPage && !isFetchingNextPage) {
fetchNextPage();
}
}}
onEndReachedThreshold={0.5}
onRefresh={() => refetch()}
ListHeaderComponent={
<>
{
if (val === 'flash') {
setSelectedSlotType('flash');
setSelectedSlot(null);
setFlashDeliveryFilter('flash');
// Reset other filters when switching to flash
setPackagedFilter('all');
setPackagedChecked(false);
setNotPackagedChecked(false);
setDeliveredFilter('all');
setDeliveredChecked(false);
setNotDeliveredChecked(false);
setCancellationFilter('all');
setCancelledChecked(false);
setNotCancelledChecked(false);
} else {
setSelectedSlotType('slot');
setSelectedSlot(val ? Number(val) : null);
setFlashDeliveryFilter('all');
}
}}
placeholder="All slots"
/>
setFilterDialogOpen(true)}
style={tw`p-2`}
>
{!isLoading && selectedSlotType && (
{selectedSlotType === 'flash'
? `${orders.length} Flash delivery orders`
: `${orders.length} Orders in slot`
}
)}
>
}
ListFooterComponent={
isFetchingNextPage ? (
Loading more...
) : null
}
/>
setFilterDialogOpen(false)}>
Packaged Status
{
const newValue = !packagedChecked;
setPackagedChecked(newValue);
if (newValue && notPackagedChecked) {
setPackagedFilter('all');
} else if (newValue) {
setPackagedFilter('packaged');
} else if (notPackagedChecked) {
setPackagedFilter('not_packaged');
} else {
setPackagedFilter('all');
}
}}
/>
Packaged
{
const newValue = !notPackagedChecked;
setNotPackagedChecked(newValue);
if (packagedChecked && newValue) {
setPackagedFilter('all');
} else if (newValue) {
setPackagedFilter('not_packaged');
} else if (packagedChecked) {
setPackagedFilter('packaged');
} else {
setPackagedFilter('all');
}
}}
/>
Not Packaged
Delivered Status
{
const newValue = !deliveredChecked;
setDeliveredChecked(newValue);
if (newValue && notDeliveredChecked) {
setDeliveredFilter('all');
} else if (newValue) {
setDeliveredFilter('delivered');
} else if (notDeliveredChecked) {
setDeliveredFilter('not_delivered');
} else {
setDeliveredFilter('all');
}
}}
/>
Delivered
{
const newValue = !notDeliveredChecked;
setNotDeliveredChecked(newValue);
if (deliveredChecked && newValue) {
setDeliveredFilter('all');
} else if (newValue) {
setDeliveredFilter('not_delivered');
} else if (deliveredChecked) {
setDeliveredFilter('delivered');
} else {
setDeliveredFilter('all');
}
}}
/>
Not Delivered
Cancellation Status
{
const newValue = !cancelledChecked;
setCancelledChecked(newValue);
if (newValue && notCancelledChecked) {
setCancellationFilter('all');
} else if (newValue) {
setCancellationFilter('cancelled');
} else if (notCancelledChecked) {
setCancellationFilter('not_cancelled');
} else {
setCancellationFilter('all');
}
}}
/>
Cancelled
{
const newValue = !notCancelledChecked;
setNotCancelledChecked(newValue);
if (cancelledChecked && newValue) {
setCancellationFilter('all');
} else if (newValue) {
setCancellationFilter('not_cancelled');
} else if (cancelledChecked) {
setCancellationFilter('cancelled');
} else {
setCancellationFilter('all');
}
}}
/>
Not Cancelled
Delivery Type
{
const newValue = !flashChecked;
setFlashChecked(newValue);
if (newValue && regularChecked) {
setFlashDeliveryFilter('all');
} else if (newValue) {
setFlashDeliveryFilter('flash');
} else if (regularChecked) {
setFlashDeliveryFilter('regular');
} else {
setFlashDeliveryFilter('all');
}
}}
/>
⚡ Flash Delivery
{
const newValue = !regularChecked;
setRegularChecked(newValue);
if (flashChecked && newValue) {
setFlashDeliveryFilter('all');
} else if (newValue) {
setFlashDeliveryFilter('regular');
} else if (flashChecked) {
setFlashDeliveryFilter('flash');
} else {
setFlashDeliveryFilter('all');
}
}}
/>
Regular Delivery
>
);
}