This commit is contained in:
shafi54 2026-01-28 09:14:02 +05:30
parent 4e54a8c6ee
commit d8271dd502
7 changed files with 82 additions and 17 deletions

View file

@ -66,6 +66,7 @@ interface OrderType {
unit: string;
isPackaged?: boolean;
isPackageVerified?: boolean;
productSize: number;
}[];
createdAt: string;
deliveryTime: string | null;
@ -437,7 +438,7 @@ const OrderItem = ({ order, refetch }: { order: OrderType; refetch: () => void }
<View key={idx} style={tw`py-2 border-b border-gray-50 last:border-0`}>
<View style={tw`flex-row items-center`}>
<View style={tw`bg-gray-100 px-2 py-1 rounded items-center justify-center mr-2`}>
<MyText style={tw`text-xs font-bold text-gray-600`}>{item.quantity} {item.unit}</MyText>
<MyText style={tw`text-xs font-bold text-gray-600`}>{item.quantity * item.productSize } {item.unit}</MyText>
</View>
<MyText style={tw`text-sm text-gray-800 flex-1`} numberOfLines={1} ellipsizeMode="tail">
{item.name.length > 30 ? `${item.name.substring(0, 30)}...` : item.name}

View file

@ -41,6 +41,7 @@ const ProductItemComponent: React.FC<ProductItemProps> = ({
const displayPrice = change.price !== undefined ? change.price : product.price;
const displayMarketPrice = change.marketPrice !== undefined ? change.marketPrice : product.marketPrice;
const displayFlashPrice = change.flashPrice !== undefined ? change.flashPrice : product.flashPrice;
const displayProductQuantity = change.productQuantity !== undefined ? change.productQuantity : product.productQuantity;
return (
<View style={tw`bg-white p-4 mb-3 rounded-xl border border-gray-200 shadow-sm`}>
@ -67,7 +68,7 @@ const ProductItemComponent: React.FC<ProductItemProps> = ({
resizeMode="cover"
/>
{/* Product name and Flash Checkbox */}
{/* Product name and Flash Checkbox */}
<View style={tw`flex-1 flex-row items-center`}>
<MyText style={tw`text-base font-medium text-gray-800`} numberOfLines={1}>
{product.name.length > 25 ? product.name.substring(0, 25) + '...' : product.name}
@ -92,12 +93,12 @@ const ProductItemComponent: React.FC<ProductItemProps> = ({
</View>
</View>
{/* Second row: Prices */}
{/* Prices and Product Size Row */}
<View style={tw`flex-row items-center justify-between`}>
{/* Our Price */}
<View style={tw`items-center flex-1`}>
<View style={tw`items-center`}>
<MyText style={tw`text-xs text-gray-500 mb-1`}>Our Price</MyText>
<View style={tw`flex-row items-center justify-center`}>
<View style={tw`flex-row items-center`}>
<MyText style={tw`text-sm font-bold text-green-600`}>{displayPrice}</MyText>
<TouchableOpacity onPress={() => openEditDialog(product)} style={tw`ml-1`}>
<MaterialIcons name="edit" size={14} color="#6b7280" />
@ -106,9 +107,9 @@ const ProductItemComponent: React.FC<ProductItemProps> = ({
</View>
{/* Market Price */}
<View style={tw`items-center flex-1`}>
<View style={tw`items-center`}>
<MyText style={tw`text-xs text-gray-500 mb-1`}>Market Price</MyText>
<View style={tw`flex-row items-center justify-center`}>
<View style={tw`flex-row items-center`}>
<MyText style={tw`text-sm text-gray-600`}>{displayMarketPrice ? `${displayMarketPrice}` : "N/A"}</MyText>
<TouchableOpacity onPress={() => openEditDialog(product)} style={tw`ml-1`}>
<MaterialIcons name="edit" size={14} color="#6b7280" />
@ -117,15 +118,26 @@ const ProductItemComponent: React.FC<ProductItemProps> = ({
</View>
{/* Flash Price */}
<View style={tw`items-center flex-1`}>
<View style={tw`items-center`}>
<MyText style={tw`text-xs text-gray-500 mb-1`}>Flash Price</MyText>
<View style={tw`flex-row items-center justify-center`}>
<View style={tw`flex-row items-center`}>
<MyText style={tw`text-sm text-orange-600`}>{displayFlashPrice ? `${displayFlashPrice}` : "N/A"}</MyText>
<TouchableOpacity onPress={() => openEditDialog(product)} style={tw`ml-1`}>
<MaterialIcons name="edit" size={14} color="#6b7280" />
</TouchableOpacity>
</View>
</View>
{/* Product Size */}
<View style={tw`items-center`}>
<MyText style={tw`text-xs text-gray-500 mb-1`}>Size</MyText>
<View style={tw`flex-row items-center`}>
<MyText style={tw`text-sm text-blue-600`}>{displayProductQuantity ? `${displayProductQuantity}${product.unit.shortNotation || ''}` : "N/A"}</MyText>
<TouchableOpacity onPress={() => openEditDialog(product)} style={tw`ml-1`}>
<MaterialIcons name="edit" size={14} color="#6b7280" />
</TouchableOpacity>
</View>
</View>
</View>
</View>
);
@ -135,6 +147,7 @@ interface PendingChange {
price?: number;
marketPrice?: number | null;
flashPrice?: number | null;
productQuantity?: number | null;
isFlashAvailable?: boolean;
}
@ -144,6 +157,7 @@ interface EditDialogState {
tempPrice: string;
tempMarketPrice: string;
tempFlashPrice: string;
tempProductQuantity: string;
}
export default function PricesOverview() {
@ -156,6 +170,7 @@ export default function PricesOverview() {
tempPrice: "",
tempMarketPrice: "",
tempFlashPrice: "",
tempProductQuantity: "",
});
const [showMenu, setShowMenu] = useState(false);
@ -211,6 +226,7 @@ export default function PricesOverview() {
tempPrice: (change.price ?? product.price)?.toString() || "",
tempMarketPrice: (change.marketPrice ?? product.marketPrice)?.toString() || "",
tempFlashPrice: (change.flashPrice ?? product.flashPrice)?.toString() || "",
tempProductQuantity: (change.productQuantity ?? product.productQuantity)?.toString() || "",
});
};
@ -219,6 +235,7 @@ export default function PricesOverview() {
const price = parseFloat(editDialog.tempPrice);
const marketPrice = editDialog.tempMarketPrice ? parseFloat(editDialog.tempMarketPrice) : null;
const flashPrice = editDialog.tempFlashPrice ? parseFloat(editDialog.tempFlashPrice) : null;
const productQuantity = editDialog.tempProductQuantity ? parseFloat(editDialog.tempProductQuantity) : null;
if (isNaN(price) || price <= 0) {
Alert.alert("Error", "Please enter a valid price");
@ -235,16 +252,22 @@ export default function PricesOverview() {
return;
}
if (editDialog.tempProductQuantity && (isNaN(productQuantity!) || productQuantity! <= 0)) {
Alert.alert("Error", "Please enter a valid product size");
return;
}
setPendingChanges(prev => ({
...prev,
[editDialog.product.id]: {
price: price !== editDialog.product.price ? price : undefined,
marketPrice: marketPrice !== editDialog.product.marketPrice ? marketPrice : undefined,
flashPrice: flashPrice !== editDialog.product.flashPrice ? flashPrice : undefined,
productQuantity: productQuantity !== editDialog.product.productQuantity ? productQuantity : undefined,
},
}));
setEditDialog({ open: false, product: null, tempPrice: "", tempMarketPrice: "", tempFlashPrice: "" });
setEditDialog({ open: false, product: null, tempPrice: "", tempMarketPrice: "", tempFlashPrice: "", tempProductQuantity: "" });
};
// Handle save all changes
@ -254,6 +277,7 @@ export default function PricesOverview() {
if (change.price !== undefined) update.price = change.price;
if (change.marketPrice !== undefined) update.marketPrice = change.marketPrice;
if (change.flashPrice !== undefined) update.flashPrice = change.flashPrice;
if (change.productQuantity !== undefined) update.productQuantity = change.productQuantity;
if (change.isFlashAvailable !== undefined) update.isFlashAvailable = change.isFlashAvailable;
return update;
});
@ -351,7 +375,7 @@ export default function PricesOverview() {
)}
{/* Edit Dialog */}
<BottomDialog open={editDialog.open} onClose={() => setEditDialog({ ...editDialog, open: false, tempFlashPrice: "" })}>
<BottomDialog open={editDialog.open} onClose={() => setEditDialog({ ...editDialog, open: false, tempFlashPrice: "", tempMarketPrice: "", tempPrice: "", tempProductQuantity: "" })}>
<View style={tw`p-4`}>
<MyText style={tw`text-lg font-bold mb-4`}>{editDialog.product?.name}</MyText>
@ -388,6 +412,17 @@ export default function PricesOverview() {
/>
</View>
<View style={tw`mb-4`}>
<MyText style={tw`text-sm font-medium mb-1`}>Product Size</MyText>
<TextInput
style={tw`border border-gray-300 rounded-md px-3 py-2`}
value={editDialog.tempProductQuantity}
onChangeText={(text) => setEditDialog({ ...editDialog, tempProductQuantity: text })}
keyboardType="decimal-pad"
placeholder="Enter product size"
/>
</View>
<TouchableOpacity
style={tw`bg-blue-600 py-3 rounded-md items-center`}
onPress={saveEditDialog}

View file

@ -775,6 +775,7 @@ export const orderRouter = router({
amount:
parseFloat(item.quantity) * parseFloat(item.price.toString()),
unit: item.product.unit?.shortNotation || "",
productSize: item.product.productQuantity,
isPackaged: item.is_packaged,
isPackageVerified: item.is_package_verified,
}))

View file

@ -143,10 +143,22 @@ export default function Dashboard() {
const initialBatchRaw = products;
// Filter to include only products with available slots
const initialBatch = initialBatchRaw.filter(product => {
const slot = getQuickestSlot(product.id);
return slot !== null && slot !== undefined && !product.isOutOfStock;
});
// const initialBatch = initialBatchRaw.filter(product => {
// const slot = getQuickestSlot(product.id);
// return !product.isOutOfStock;
// });
const initialBatch = initialBatchRaw.sort((a, b) => {
const slotA = getQuickestSlot(a.id);
const slotB = getQuickestSlot(b.id);
if (slotA && !slotB) return -1;
if (!slotA && slotB) return 1;
if(a.isOutOfStock && !b.isOutOfStock) return 1;
if(!a.isOutOfStock && b.isOutOfStock) return -1;
return 0;
})
setDisplayedProducts(initialBatch);
setHasMore(products.length > 10);
@ -593,6 +605,9 @@ export default function Dashboard() {
/>
</View>
)}
initialNumToRender={4}
maxToRenderPerBatch={4}
windowSize={4}
// onEndReached={() => {
// if (!isLoadingMore && hasMore) {
// loadMoreProducts();

View file

@ -350,10 +350,12 @@ export function SlotProducts({ slotId:slotIdParent, storeId:storeIdParent, baseU
const productsQuery = trpc.user.product.getAllProductsSummary.useQuery();
const { addToCart = () => { } } = useAddToCart({ showSuccessAlert: false, showErrorAlert: false, refetchCart: true }, "flash") || {};
const { addToCart = () => { } } = useAddToCart({ showSuccessAlert: false, showErrorAlert: false, refetchCart: true }, "regular") || {};
const handleAddToCart = (productId: number) => {
setIsLoadingDialogOpen(true);
// console.log({productId})
addToCart(productId, 1, slotId || 0, () => setIsLoadingDialogOpen(false));
};

View file

@ -305,11 +305,16 @@ export default function CartPage({ isFlashDelivery = false }: CartPageProps) {
// Auto-select delivery slots for each cart item
useEffect(() => {
const cartSlotIds = cartData?.items.reduce((acc,item) => {
acc[item.id] = item.slotId;
return acc;
}, {} as Record<number, number>);
if (cartItems.length > 0) {
const newSelectedSlots = { ...selectedSlots };
cartItems.forEach(item => {
const existingSlotId = selectedSlots[item.id];
// const existingSlotId = selectedSlots[item.id];
const existingSlotId = cartSlotIds ? cartSlotIds[item.id] : undefined;
if (isFlashDelivery) {
newSelectedSlots[item.id] = 0;
@ -325,6 +330,8 @@ export default function CartPage({ isFlashDelivery = false }: CartPageProps) {
);
if (upcomingSlots.length > 0) {
console.log({upcomingSlots, existingSlotId, cartSlotIds})
if (existingSlotId) {
const slotStillValid = upcomingSlots.some(slot => slot.id === existingSlotId);
if (slotStillValid) {

View file

@ -91,6 +91,8 @@ const addToLocalCart = async (productId: number, quantity: number, slotId?: numb
items.push(cartItem);
}
console.log({items})
await saveLocalCart(items, cartType);
return items;
};
@ -301,6 +303,8 @@ export function useAddToCart(options?: {
const addToCart = (productId: number, quantity = 1, slotId?: number, onSettled?: (data: any, error: any) => void) => {
// console.log({productId, quantity, slotId})
if (slotId == null) {
throw new Error('slotId is required for adding to cart');
}