fake_shop/app/address/page.jsx

217 lines
6.4 KiB
JavaScript

"use client";
import React, { useState, useEffect, Suspense } from "react";
import { useRouter, useSearchParams } from "next/navigation";
function AddressContent() {
const router = useRouter();
const searchParams = useSearchParams();
const [addresses, setAddresses] = useState([]);
const [showForm, setShowForm] = useState(false);
const [formData, setFormData] = useState({
name: "",
phone: "",
address: "",
isDefault: false,
});
useEffect(() => {
const token = localStorage.getItem("token");
if (!token) {
router.push("/login");
return;
}
fetchAddresses();
}, [router]);
const fetchAddresses = async () => {
try {
const res = await fetch("/api/address", {
headers: {
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
});
const data = await res.json();
setAddresses(data);
} catch (error) {
console.error("获取地址失败:", error);
}
};
const handleSelectAddress = (address) => {
const returnUrl = searchParams.get("returnUrl");
const items = searchParams.get("items");
const products = searchParams.get("products");
const quantity = searchParams.get("quantity");
localStorage.setItem("selectedAddress", JSON.stringify(address));
if (returnUrl) {
let finalUrl = returnUrl;
if (items) {
finalUrl += `?items=${items}`;
} else if (products && quantity) {
finalUrl += `?products=${products}&quantity=${quantity}`;
}
router.replace(finalUrl);
} else {
router.replace("/checkout");
}
};
const handleSubmit = async (e) => {
e.preventDefault();
try {
const res = await fetch("/api/address", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
body: JSON.stringify(formData),
});
if (!res.ok) {
throw new Error("添加地址失败");
}
setShowForm(false);
setFormData({ name: "", phone: "", address: "", isDefault: false });
await fetchAddresses();
} catch (error) {
console.error("添加地址失败:", error);
}
};
return (
<div className="min-h-screen bg-gray-50 p-4">
<div className="max-w-md mx-auto">
<h1 className="text-xl font-bold mb-4">收货地址</h1>
{/* 地址列表 */}
<div className="space-y-4 mb-6">
{addresses.map((address) => (
<div
key={address._id}
className="bg-white p-4 rounded-lg shadow-sm"
onClick={() => handleSelectAddress(address)}
>
<div className="flex justify-between items-center mb-2">
<span className="font-medium">{address.name}</span>
<span>{address.phone}</span>
</div>
<p className="text-gray-600 text-sm">{address.address}</p>
{address.isDefault && (
<span className="mt-2 inline-block px-2 py-1 text-xs text-yellow-600 border border-yellow-600 rounded">
默认地址
</span>
)}
</div>
))}
</div>
{/* 添加地址按钮 */}
{!showForm && (
<button
onClick={() => setShowForm(true)}
className="w-full bg-yellow-400 text-white py-3 rounded-lg"
>
添加新地址
</button>
)}
{/* 添加地址表单 */}
{showForm && (
<form onSubmit={handleSubmit} className="bg-white p-4 rounded-lg">
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
联系人
</label>
<input
type="text"
required
className="w-full px-3 py-2 border rounded-lg"
value={formData.name}
onChange={(e) =>
setFormData({ ...formData, name: e.target.value })
}
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
手机号
</label>
<input
type="tel"
required
className="w-full px-3 py-2 border rounded-lg"
value={formData.phone}
onChange={(e) =>
setFormData({ ...formData, phone: e.target.value })
}
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
详细地址
</label>
<textarea
required
className="w-full px-3 py-2 border rounded-lg"
rows="3"
value={formData.address}
onChange={(e) =>
setFormData({ ...formData, address: e.target.value })
}
/>
</div>
<div className="flex items-center">
<input
type="checkbox"
id="isDefault"
checked={formData.isDefault}
onChange={(e) =>
setFormData({ ...formData, isDefault: e.target.checked })
}
className="mr-2"
/>
<label htmlFor="isDefault" className="text-sm text-gray-700">
设为默认地址
</label>
</div>
</div>
<div className="mt-6 flex gap-4">
<button
type="button"
onClick={() => setShowForm(false)}
className="flex-1 py-2 border border-gray-300 rounded-lg"
>
取消
</button>
<button
type="submit"
className="flex-1 bg-yellow-400 text-white py-2 rounded-lg"
>
保存
</button>
</div>
</form>
)}
</div>
</div>
);
}
export default function AddressPage() {
return (
<Suspense fallback={<div className="p-4">加载中...</div>}>
<AddressContent />
</Suspense>
);
}