fake_shop/app/good/[id]/page.jsx

198 lines
5.3 KiB
React
Raw Normal View History

2025-02-10 19:24:19 +08:00
"use client";
import { useParams } from "next/navigation";
import { useEffect, useState } from "react";
import Image from "next/image";
import { useRouter } from "next/navigation";
import toast from "react-hot-toast";
import AddToCartModal from "@/components/AddToCartModal";
export default function ProductDetail() {
const params = useParams();
const [product, setProduct] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [quantity, setQuantity] = useState(1);
const router = useRouter();
const [showModal, setShowModal] = useState(false);
useEffect(() => {
const fetchProduct = async () => {
try {
const res = await fetch(`/api/products/${params.id}`);
if (!res.ok) {
throw new Error("获取商品详情失败");
}
const data = await res.json();
setProduct(data);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchProduct();
}, [params.id]);
const handleAddToCart = async () => {
try {
const token = localStorage.getItem("token");
if (!token) {
router.push("/login");
return;
}
const res = await fetch("/api/cart", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
productId: params.id,
quantity: quantity,
}),
});
if (!res.ok) {
throw new Error("添加购物车失败");
}
toast.success("添加成功");
handleModalClose();
} catch (error) {
toast.error(error.message);
}
};
const handleBuyNow = () => {
const token = localStorage.getItem("token");
if (!token) {
router.push("/login");
return;
}
router.push(`/checkout?products=${params.id}&quantity=${quantity}`);
};
const handleAddToCartClick = () => {
const token = localStorage.getItem("token");
if (!token) {
router.push("/login");
return;
}
setShowModal(true);
};
const handleModalClose = () => {
setShowModal(false);
};
if (loading) {
return <div className="p-4">加载中...</div>;
}
if (error) {
return <div className="p-4 text-red-500">错误: {error}</div>;
}
if (!product) {
return <div className="p-4">商品不存在</div>;
}
return (
<div className="flex flex-col min-h-screen pb-20 bg-gray-50">
{/* 商品图片 */}
<div className="relative aspect-square">
<Image
src={product.imageUrl}
alt={product.title}
fill
className="object-cover"
/>
</div>
{/* 商品信息 */}
<div className="flex-1 p-4 bg-white">
<div className="flex items-center">
<span className="text-2xl text-red-500 font-bold">
¥{product.price}
</span>
{product.isVip && (
<span className="ml-2 px-2 py-0.5 text-xs text-yellow-600 border border-yellow-600 rounded">
VIP
</span>
)}
</div>
<h1 className="mt-2 text-lg font-medium">{product.title}</h1>
<div className="mt-2 text-sm text-gray-500">
<span>库存: {product.stock}</span>
<span className="ml-4">销量: {product.sales}</span>
</div>
{/* 配送信息 */}
<div className="mt-4 p-3 bg-gray-50 rounded-lg">
<div className="flex justify-between items-center">
<span className="text-gray-500">配送</span>
<span>{product.delivery}</span>
</div>
<div className="mt-2 flex justify-between items-center">
<span className="text-gray-500">服务</span>
<div className="flex gap-2">
{product.services.map((service, index) => (
<span key={index} className="text-sm text-gray-600">
{service}
</span>
))}
</div>
</div>
</div>
{/* 商品描述 */}
<div className="mt-6">
<h2 className="text-lg font-bold mb-2">商品详情</h2>
<p className="text-gray-600">{product.description}</p>
<h3 className="mt-4 font-bold">产品特点</h3>
<ul className="mt-2 space-y-2">
{product.features.map((feature, index) => (
<li key={index} className="flex items-center text-gray-600">
<span className="mr-2"></span>
{feature}
</li>
))}
</ul>
</div>
</div>
{/* 底部购买栏 */}
<div className="fixed bottom-0 left-0 right-0 flex items-center p-4 bg-white border-t">
<button
className="flex-1 bg-yellow-400 text-white py-2 rounded-full"
onClick={handleAddToCartClick}
>
加入购物车
</button>
<button
className="flex-1 ml-2 bg-red-500 text-white py-2 rounded-full"
onClick={handleBuyNow}
>
立即购买
</button>
</div>
<AddToCartModal
isOpen={showModal}
onClose={handleModalClose}
product={product}
quantity={quantity}
setQuantity={setQuantity}
onAddToCart={handleAddToCart}
/>
</div>
);
}