Files
group-2-threaded-project-pe…/web/components/ProductCard.js
augmentedpotato 4d91d8b331 Stripe Payment
2026-04-09 22:27:03 -06:00

98 lines
2.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import Link from "next/link";
import { useState } from "react";
import { useRouter } from "next/navigation";
import { useAuth } from "@/context/AuthContext";
import { useCart } from "@/context/CartContext";
export default function ProductCard({ prodId, prodName, categoryName, prodPrice, imageUrl }) {
const { user } = useAuth();
const { addItem, selectedStoreId } = useCart();
const router = useRouter();
const [quantity, setQuantity] = useState(1);
const [adding, setAdding] = useState(false);
const [feedback, setFeedback] = useState(null);
async function handleAddToCart(e) {
e.preventDefault();
if (!user) {
router.push("/login");
return;
}
if (!selectedStoreId) {
setFeedback("Please select a store first");
setTimeout(() => setFeedback(null), 2500);
return;
}
setAdding(true);
setFeedback(null);
try {
await addItem(prodId, quantity);
setFeedback("Added!");
setTimeout(() => setFeedback(null), 1500);
} catch (err) {
setFeedback(err.message || "Failed to add");
setTimeout(() => setFeedback(null), 2500);
} finally {
setAdding(false);
}
}
return (
<div className="pet-card product-card-wrapper">
<Link href={`/products/${prodId}`} className="product-card-link">
<div className="pet-card-image-wrapper">
<img
src={imageUrl || "/images/pet-placeholder.png"}
alt={prodName}
className="pet-card-image"
onError={(e) => {
e.currentTarget.onerror = null;
e.currentTarget.src = "/images/pet-placeholder.png";
}}
/>
</div>
<div className="pet-card-body">
<h3 className="pet-card-name">{prodName}</h3>
<p className="pet-card-species">{categoryName}</p>
{prodPrice != null && (
<span className="product-card-price">${parseFloat(prodPrice).toFixed(2)}</span>
)}
</div>
</Link>
<div className="product-card-actions">
<div className="product-card-qty-row">
<button
className="product-card-qty-btn"
type="button"
onClick={() => setQuantity((q) => Math.max(1, q - 1))}
disabled={adding}
>
</button>
<span className="product-card-qty-val">{quantity}</span>
<button
className="product-card-qty-btn"
type="button"
onClick={() => setQuantity((q) => q + 1)}
disabled={adding}
>
+
</button>
</div>
<button
className="product-card-add-btn"
type="button"
onClick={handleAddToCart}
disabled={adding}
>
{adding ? "Adding…" : "Add to Cart"}
</button>
{feedback && <p className="product-card-feedback">{feedback}</p>}
</div>
</div>
);
}