All checks were successful
Build & Deploy Costco Grocery List / build (push) Successful in 49s
Build & Deploy Costco Grocery List / verify-images (push) Successful in 1s
Build & Deploy Costco Grocery List / deploy (push) Successful in 14s
Build & Deploy Costco Grocery List / notify (push) Successful in 0s
147 lines
4.0 KiB
JavaScript
147 lines
4.0 KiB
JavaScript
import { useEffect, useState } from "react";
|
|
import "../../styles/ConfirmBuyModal.css";
|
|
|
|
export default function ConfirmBuyModal({
|
|
item,
|
|
onConfirm,
|
|
onCancel,
|
|
allItems = [],
|
|
onNavigate
|
|
}) {
|
|
const [quantity, setQuantity] = useState(item.quantity);
|
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
const maxQuantity = item.quantity;
|
|
|
|
useEffect(() => {
|
|
setQuantity(item.quantity);
|
|
setIsSubmitting(false);
|
|
}, [item.id, item.quantity]);
|
|
|
|
const currentIndex = allItems.findIndex((listItem) => listItem.id === item.id);
|
|
const hasPrev = currentIndex > 0;
|
|
const hasNext = currentIndex < allItems.length - 1;
|
|
|
|
const handleIncrement = () => {
|
|
if (!isSubmitting && quantity < maxQuantity) {
|
|
setQuantity((prev) => prev + 1);
|
|
}
|
|
};
|
|
|
|
const handleDecrement = () => {
|
|
if (!isSubmitting && quantity > 1) {
|
|
setQuantity((prev) => prev - 1);
|
|
}
|
|
};
|
|
|
|
const handleConfirm = async () => {
|
|
if (isSubmitting) return;
|
|
|
|
setIsSubmitting(true);
|
|
try {
|
|
await onConfirm(quantity);
|
|
} finally {
|
|
setIsSubmitting(false);
|
|
}
|
|
};
|
|
|
|
const handlePrev = () => {
|
|
if (isSubmitting) return;
|
|
|
|
if (hasPrev && onNavigate) {
|
|
onNavigate(allItems[currentIndex - 1]);
|
|
}
|
|
};
|
|
|
|
const handleNext = () => {
|
|
if (isSubmitting) return;
|
|
|
|
if (hasNext && onNavigate) {
|
|
onNavigate(allItems[currentIndex + 1]);
|
|
}
|
|
};
|
|
|
|
const imageUrl = item.item_image && item.image_mime_type
|
|
? `data:${item.image_mime_type};base64,${item.item_image}`
|
|
: null;
|
|
|
|
return (
|
|
<div
|
|
className="confirm-buy-modal-overlay"
|
|
onClick={() => {
|
|
if (!isSubmitting) {
|
|
onCancel();
|
|
}
|
|
}}
|
|
>
|
|
<div className="confirm-buy-modal" onClick={(event) => event.stopPropagation()}>
|
|
<div className="confirm-buy-header">
|
|
{item.zone && <div className="confirm-buy-zone">{item.zone}</div>}
|
|
<h2 className="confirm-buy-item-name">{item.item_name}</h2>
|
|
</div>
|
|
|
|
<div className="confirm-buy-image-section">
|
|
<button
|
|
className="confirm-buy-nav-btn confirm-buy-nav-prev"
|
|
onClick={handlePrev}
|
|
style={{ visibility: hasPrev ? "visible" : "hidden" }}
|
|
disabled={!hasPrev || isSubmitting}
|
|
>
|
|
{"<"}
|
|
</button>
|
|
|
|
<div className="confirm-buy-image-container">
|
|
{imageUrl ? (
|
|
<img src={imageUrl} alt={item.item_name} className="confirm-buy-image" />
|
|
) : (
|
|
<div className="confirm-buy-image-placeholder">[ ]</div>
|
|
)}
|
|
</div>
|
|
|
|
<button
|
|
className="confirm-buy-nav-btn confirm-buy-nav-next"
|
|
onClick={handleNext}
|
|
style={{ visibility: hasNext ? "visible" : "hidden" }}
|
|
disabled={!hasNext || isSubmitting}
|
|
>
|
|
{">"}
|
|
</button>
|
|
</div>
|
|
|
|
<div className="confirm-buy-quantity-section">
|
|
<div className="confirm-buy-counter">
|
|
<button
|
|
onClick={handleDecrement}
|
|
className="confirm-buy-counter-btn"
|
|
disabled={quantity <= 1 || isSubmitting}
|
|
>
|
|
-
|
|
</button>
|
|
<input
|
|
type="number"
|
|
value={quantity}
|
|
readOnly
|
|
className="confirm-buy-counter-display"
|
|
/>
|
|
<button
|
|
onClick={handleIncrement}
|
|
className="confirm-buy-counter-btn"
|
|
disabled={quantity >= maxQuantity || isSubmitting}
|
|
>
|
|
+
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="confirm-buy-actions">
|
|
<button onClick={onCancel} className="confirm-buy-cancel" disabled={isSubmitting}>
|
|
Cancel
|
|
</button>
|
|
<button onClick={handleConfirm} className="confirm-buy-confirm" disabled={isSubmitting}>
|
|
{isSubmitting ? "Saving..." : "Mark as Bought"}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|