diff --git a/app/[locale]/cart/page.tsx b/app/[locale]/cart/page.tsx index 103cf34..4a8d9c4 100644 --- a/app/[locale]/cart/page.tsx +++ b/app/[locale]/cart/page.tsx @@ -171,7 +171,7 @@ export default function CartPage() { {Object.entries(itemsBySeller).map( ([sellerId, { seller, items }]) => (
-

{seller.name}

+ {/*

{seller.name}

*/}
{items.map((item) => { const price = parseFloat( diff --git a/features/cart/components/CartItemCard.tsx b/features/cart/components/CartItemCard.tsx index cd9aa93..4c0d767 100644 --- a/features/cart/components/CartItemCard.tsx +++ b/features/cart/components/CartItemCard.tsx @@ -48,6 +48,7 @@ export default function CartItemCard({ item, onUpdate }: CartItemCardProps) { const pendingQuantityRef = useRef(null); const retryCountRef = useRef(0); const retryTimerRef = useRef(undefined); + const isInitializedRef = useRef(false); // Track if component has been initialized // Function refs to solve circular dependency const syncToServerRef = useRef<((quantity: number) => void) | null>(null); @@ -62,6 +63,10 @@ export default function CartItemCard({ item, onUpdate }: CartItemCardProps) { // Initialize from server state useEffect(() => { setLocalQuantity(item.quantity); + // Mark as initialized after first render + if (!isInitializedRef.current) { + isInitializedRef.current = true; + } }, [item.quantity]); // Save to sessionStorage @@ -81,13 +86,13 @@ export default function CartItemCard({ item, onUpdate }: CartItemCardProps) { sessionStorage.setItem( PENDING_CART_UPDATES_KEY, - JSON.stringify(pending) + JSON.stringify(pending), ); } catch (error) { console.error("Failed to save pending update:", error); } }, - [item.product_id] + [item.product_id], ); // Remove from sessionStorage @@ -103,7 +108,7 @@ export default function CartItemCard({ item, onUpdate }: CartItemCardProps) { } else { sessionStorage.setItem( PENDING_CART_UPDATES_KEY, - JSON.stringify(pending) + JSON.stringify(pending), ); } } @@ -200,7 +205,7 @@ export default function CartItemCard({ item, onUpdate }: CartItemCardProps) { retrySyncRef.current?.(quantity); }, - } + }, ); } }, @@ -211,13 +216,16 @@ export default function CartItemCard({ item, onUpdate }: CartItemCardProps) { removeItem, onUpdate, clearPendingUpdate, - ] + ], ); // Update ref syncToServerRef.current = syncToServer; // Load pending updates from sessionStorage on mount + // DISABLED: This was causing automatic sync on mount, sending 0 quantity to server + // Users should manually refresh or re-add items if there were pending updates + /* useEffect(() => { const loadPendingUpdates = () => { try { @@ -246,9 +254,15 @@ export default function CartItemCard({ item, onUpdate }: CartItemCardProps) { loadPendingUpdates(); }, [item.product_id, item.quantity]); + */ // Debounced sync useEffect(() => { + // Don't sync on initial mount - only sync after user interaction + if (!isInitializedRef.current) { + return; + } + // Clear existing timers if (debounceTimerRef.current) { clearTimeout(debounceTimerRef.current); @@ -259,6 +273,14 @@ export default function CartItemCard({ item, onUpdate }: CartItemCardProps) { return; } + // Don't sync if quantity is 0 or invalid (unless it's a delete operation) + if (localQuantity <= 0 && item.quantity > 0) { + // This is a delete operation, allow it + } else if (localQuantity <= 0) { + // Invalid state, don't sync + return; + } + // Save to sessionStorage immediately savePendingUpdate(localQuantity); @@ -336,14 +358,14 @@ export default function CartItemCard({ item, onUpdate }: CartItemCardProps) {

{item.product.name}

-

+ {/*

{item.seller?.name || "Store"} -

- {availableStock <= 5 && ( +

*/} + {/* {availableStock <= 5 && (

{t("only_left", { count: availableStock })}

- )} + )} */}
- )} + )} +
- + + {/* Modal */} + {isModalOpen && ( +
+ {/* Top Bar */} +
+
+
+
+ {productName} +
+ +
+
+ + {/* Main Image Area */} +
+ {/* Left Arrow - Desktop */} + {images.length > 1 && ( + + )} + + {/* Image Container */} +
1 ? (isDragging ? "grabbing" : "grab") : "default" }} + > +
+ {productName} +
+
+ + {/* Right Arrow - Desktop */} + {images.length > 1 && ( + + )} +
+ + {/* Bottom Control Bar */} +
+
+ {/* Mobile Layout */} +
+ {/* Row 1: Navigation */} + {images.length > 1 && ( +
+ +
+ + {selectedImage + 1} / {images.length} + +
+ +
+ )} + + {/* Row 2: Zoom & Rotate */} +
+
+ +
+ {Math.round(zoom * 100)}% +
+ +
+ +
+ + +
+ + +
+
+ + {/* Desktop Layout */} +
+ + +
+ +
+ {Math.round(zoom * 100)}% +
+ +
+ +
+ +
+ + +
+ + + +
+ + + + {images.length > 1 && ( + <> +
+
+ + {selectedImage + 1} / {images.length} + +
+ + )} +
+
+
+
+ )} + ); } \ No newline at end of file diff --git a/i18n/messages/ru.json b/i18n/messages/ru.json index c5e360e..cbdcbe2 100644 --- a/i18n/messages/ru.json +++ b/i18n/messages/ru.json @@ -19,6 +19,7 @@ "loading": "Загрузка...", "all_collections_loaded": "Все коллекции загружены" }, + "category": "Категория", "checkout": "Оформить заказ", "price_label": "Цена:", diff --git a/next.config.ts b/next.config.ts index b351501..73d2e7e 100644 --- a/next.config.ts +++ b/next.config.ts @@ -11,8 +11,8 @@ const nextConfig: NextConfig = { unoptimized: true, remotePatterns: [ { - protocol: "http", - hostname: "shop.post.tm", + protocol: "https", + hostname: "hyzmat.app", // port: "8080", }, ],