From 10d13408d38bc569f8c7d91415fed4eca23d039a Mon Sep 17 00:00:00 2001
From: shafi54 <108669266+shafi-aviz@users.noreply.github.com>
Date: Fri, 20 Feb 2026 12:42:59 +0530
Subject: [PATCH] enh
---
apps/user-ui/components/floating-cart-bar.tsx | 45 ++--
.../src/components/AddToCartDialog.tsx | 207 ++++++++++--------
packages/ui/index.ts | 4 +-
3 files changed, 148 insertions(+), 108 deletions(-)
diff --git a/apps/user-ui/components/floating-cart-bar.tsx b/apps/user-ui/components/floating-cart-bar.tsx
index fa76b2a..cbf7e79 100644
--- a/apps/user-ui/components/floating-cart-bar.tsx
+++ b/apps/user-ui/components/floating-cart-bar.tsx
@@ -36,21 +36,32 @@ interface FloatingCartBarProps {
}
// Smart time window formatting function
- const formatTimeRange = (deliveryTime: string) => {
- const time = dayjs(deliveryTime);
- const endTime = time.add(1, 'hour');
- const startPeriod = time.format('A');
- const endPeriod = endTime.format('A');
+const formatTimeRange = (deliveryTime: string) => {
+ const time = dayjs(deliveryTime);
+ const endTime = time.add(1, 'hour');
+ const startPeriod = time.format('A');
+ const endPeriod = endTime.format('A');
- let timeRange;
- if (startPeriod === endPeriod) {
- timeRange = `${time.format('h')}-${endTime.format('h')} ${startPeriod}`;
- } else {
- timeRange = `${time.format('h:mm')} ${startPeriod} - ${endTime.format('h:mm')} ${endPeriod}`;
- }
+ let timeRange;
+ if (startPeriod === endPeriod) {
+ timeRange = `${time.format('h')}-${endTime.format('h')} ${startPeriod}`;
+ } else {
+ timeRange = `${time.format('h:mm')} ${startPeriod} - ${endTime.format('h:mm')} ${endPeriod}`;
+ }
- return `${time.format('ddd, DD MMM ')}${timeRange}`;
- };
+ return `${time.format('ddd, DD MMM ')}${timeRange}`;
+};
+
+// Product name component with quantity
+const ProductNameWithQuantity = ({ name, productQuantity, unitNotation }: { name: string; productQuantity: number; unitNotation: string }) => {
+ const truncatedName = name.length > 25 ? name.substring(0, 25) + '...' : name;
+ const unit = unitNotation ? ` ${unitNotation}` : '';
+ return (
+
+ {truncatedName} ({productQuantity}{unit})
+
+ );
+};
const FloatingCartBar: React.FC = ({
isFlashDelivery = false,
@@ -252,9 +263,11 @@ useEffect(() => {
-
- {item.product.name.length > 30 ? item.product.name.substring(0, 30) + '...' : item.product.name}
-
+
{
diff --git a/apps/user-ui/src/components/AddToCartDialog.tsx b/apps/user-ui/src/components/AddToCartDialog.tsx
index 6a22d4a..5aa717c 100644
--- a/apps/user-ui/src/components/AddToCartDialog.tsx
+++ b/apps/user-ui/src/components/AddToCartDialog.tsx
@@ -6,7 +6,7 @@ import MaterialIcons from '@expo/vector-icons/MaterialIcons';
import { useCartStore } from '@/src/store/cartStore';
import { useFlashCartStore } from '@/src/store/flashCartStore';
import { trpc } from '@/src/trpc-client';
-import { useAddToCart, useGetCart, useUpdateCartItem } from '@/hooks/cart-query-hooks';
+import { useAddToCart, useGetCart, useUpdateCartItem, useRemoveFromCart } from '@/hooks/cart-query-hooks';
import { useGetEssentialConsts } from '@/src/api-hooks/essential-consts.api';
import dayjs from 'dayjs';
import { SafeAreaView } from 'react-native-safe-area-context';
@@ -17,15 +17,15 @@ export default function AddToCartDialog() {
const [quantity, setQuantity] = useState(1);
const [selectedSlotId, setSelectedSlotId] = useState(null);
const [selectedFlashDelivery, setSelectedFlashDelivery] = useState(false);
-
+
const { data: slotsData } = trpc.user.slots.getSlotsWithProducts.useQuery();
const { data: cartData } = useGetCart();
const { data: constsData } = useGetEssentialConsts();
// const isFlashDeliveryEnabled = constsData?.isFlashDeliveryEnabled === true;
const isFlashDeliveryEnabled = true;
-
-
-
+
+
+
const addToCart = useAddToCart({
showSuccessAlert: false,
showErrorAlert: false,
@@ -38,8 +38,14 @@ export default function AddToCartDialog() {
refetchCart: true,
});
+ const removeFromCart = useRemoveFromCart({
+ showSuccessAlert: false,
+ showErrorAlert: false,
+ refetchCart: true,
+ });
+
const isOpen = !!addedToCartProduct;
-
+
const product = addedToCartProduct?.product;
@@ -49,10 +55,10 @@ export default function AddToCartDialog() {
if (isOpen && product) {
const cartItem = cartData?.items?.find((item: any) => item.productId === product.id);
const cartQuantity = cartItem?.quantity || 0;
-
+
// Set quantity: 0 → 1, >1 → keep as is
setQuantity(cartQuantity === 0 ? 1 : cartQuantity);
-
+
if (cartItem?.slotId) {
setSelectedSlotId(cartItem.slotId);
} else {
@@ -64,11 +70,11 @@ export default function AddToCartDialog() {
const { slotMap, productSlotIdsMap } = useMemo(() => {
const slotMap: Record = {};
const productSlotIdsMap: Record = {};
-
+
if (slotsData?.slots) {
slotsData.slots.forEach((slot: any) => {
slotMap[slot.id] = slot;
-
+
slot.products?.forEach((p: any) => {
if (!productSlotIdsMap[p.id]) {
productSlotIdsMap[p.id] = [];
@@ -77,12 +83,12 @@ export default function AddToCartDialog() {
});
});
}
-
+
return { slotMap, productSlotIdsMap };
}, [slotsData]);
const availableSlotIds = productSlotIdsMap[product?.id] || [];
-
+
const availableSlots = availableSlotIds
.map((slotId) => slotMap[slotId])
.filter(Boolean);
@@ -91,7 +97,7 @@ export default function AddToCartDialog() {
const cartItem = cartData?.items?.find((item: any) => item.productId === product?.id);
// Determine if updating existing item (quantity > 1 means it's an update)
- const isUpdate = (cartItem?.quantity || 0) > 1;
+ const isUpdate = (cartItem?.quantity || 0) >= 1;
// Check if flash delivery option should be shown
const showFlashOption = product?.isFlashAvailable === true && isFlashDeliveryEnabled;
@@ -122,99 +128,120 @@ export default function AddToCartDialog() {
return (
-
-
-
-
+
+
+
+
+
+
+ Select Delivery Slot
+ {product?.name && (
+
+ {product.name} ({product.productQuantity}{product.unitNotation ? ` ${product.unitNotation}` : ''})
+
+ )}
+
-
- Select Delivery Slot
- {product?.name && (
- {product.name}
- )}
-
-
-
- {availableSlots.map((slot: any) => (
+
+ {availableSlots.map((slot: any) => (
+ {
+ setSelectedSlotId(slot.id);
+ setSelectedFlashDelivery(false);
+ }}
+ activeOpacity={0.7}
+ >
+
+
+
+ {dayjs(slot.deliveryTime).format('ddd, DD MMM • h:mm A')}
+
+
+ {selectedSlotId === slot.id ? (
+
+ ) : (
+
+ )}
+
+ ))}
+
+
+ {showFlashOption && (
{
- setSelectedSlotId(slot.id);
- setSelectedFlashDelivery(false);
+ setSelectedFlashDelivery(true);
+ setSelectedSlotId(null);
}}
activeOpacity={0.7}
>
-
+
-
- {dayjs(slot.deliveryTime).format('ddd, DD MMM • h:mm A')}
-
+ 1 hr Delivery
- {selectedSlotId === slot.id ? (
-
+ {selectedFlashDelivery ? (
+
) : (
-
+
)}
- ))}
-
+ )}
- {showFlashOption && (
- {
- setSelectedFlashDelivery(true);
- setSelectedSlotId(null);
- }}
- activeOpacity={0.7}
- >
-
-
- 1 hr Delivery
+
+ Quantity
+
+
+
+
+ {isUpdate && (
+ {
+ if (cartItem?.id) {
+ removeFromCart.mutate(
+ { itemId: cartItem.id },
+ { onSuccess: () => clearAddedToCartProduct() }
+ );
+ } else {
+ clearAddedToCartProduct();
+ }
+ }}
+ style={tw`p-2 ml-3 bg-red-50 rounded-lg border border-red-200`}
+ >
+
+
+ )}
- {selectedFlashDelivery ? (
-
- ) : (
-
- )}
-
- )}
+
-
- Quantity
-
+
+
+
+ {addToCart.isLoading || updateCartItem.isLoading ? (isUpdate ? 'Updating...' : 'Adding...') : (isUpdate ? 'Update Item' : 'Add to Cart')}
+
+
+
+ Cancel
+
+
-
-
-
-
- {addToCart.isLoading || updateCartItem.isLoading ? (isUpdate ? 'Updating...' : 'Adding...') : (isUpdate ? 'Update Item' : 'Add to Cart')}
-
-
-
- Cancel
-
-
-
);
diff --git a/packages/ui/index.ts b/packages/ui/index.ts
index e320050..7d8362d 100755
--- a/packages/ui/index.ts
+++ b/packages/ui/index.ts
@@ -63,8 +63,8 @@ const isDevMode = Constants.executionEnvironment !== "standalone";
// const BASE_API_URL = API_URL;
// const BASE_API_URL = 'http://10.0.2.2:4000';
// const BASE_API_URL = 'http://192.168.100.101:4000';
-const BASE_API_URL = 'http://192.168.1.3:4000';
-// let BASE_API_URL = "https://mf.freshyo.in";
+// const BASE_API_URL = 'http://192.168.1.3:4000';
+let BASE_API_URL = "https://mf.freshyo.in";
// let BASE_API_URL = 'http://192.168.100.104:4000';
// let BASE_API_URL = 'http://192.168.29.176:4000';