142 lines
4.7 KiB
TypeScript
142 lines
4.7 KiB
TypeScript
"use client"
|
|
|
|
import { useState, useEffect } from "react"
|
|
import { useRouter } from "next/navigation"
|
|
import { ChevronLeft, MapPin, Plus, Pencil, Trash2 } from "lucide-react"
|
|
import { useStore } from "@/lib/store"
|
|
|
|
type AddressItem = {
|
|
id: string
|
|
name: string
|
|
phone: string
|
|
province: string
|
|
city: string
|
|
district: string
|
|
detail: string
|
|
fullAddress: string
|
|
isDefault: boolean
|
|
}
|
|
|
|
export default function AddressesPage() {
|
|
const router = useRouter()
|
|
const { user } = useStore()
|
|
const [list, setList] = useState<AddressItem[]>([])
|
|
const [loading, setLoading] = useState(true)
|
|
|
|
useEffect(() => {
|
|
if (!user?.id) {
|
|
setList([])
|
|
setLoading(false)
|
|
return
|
|
}
|
|
fetch(`/api/user/addresses?userId=${user.id}`)
|
|
.then((res) => res.json())
|
|
.then((data) => {
|
|
if (data.success && data.list) setList(data.list)
|
|
setLoading(false)
|
|
})
|
|
.catch(() => setLoading(false))
|
|
}, [user?.id])
|
|
|
|
const handleDelete = async (id: string) => {
|
|
if (!confirm("确定要删除该收货地址吗?")) return
|
|
try {
|
|
const res = await fetch(`/api/user/addresses/${id}`, { method: "DELETE" })
|
|
const data = await res.json()
|
|
if (data.success) {
|
|
setList((prev) => prev.filter((a) => a.id !== id))
|
|
} else {
|
|
alert(data.message || "删除失败")
|
|
}
|
|
} catch {
|
|
alert("删除失败")
|
|
}
|
|
}
|
|
|
|
if (!user) {
|
|
return (
|
|
<div className="min-h-screen bg-black text-white flex items-center justify-center">
|
|
<div className="text-center">
|
|
<p className="text-white/60 mb-4">请先登录</p>
|
|
<button
|
|
onClick={() => router.push("/my")}
|
|
className="px-4 py-2 rounded-xl bg-[#00CED1] text-black font-medium"
|
|
>
|
|
去登录
|
|
</button>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<div className="min-h-screen bg-black text-white pb-24">
|
|
<header className="sticky top-0 z-40 bg-black/90 backdrop-blur-xl border-b border-white/5">
|
|
<div className="px-4 py-3 flex items-center">
|
|
<button
|
|
onClick={() => router.back()}
|
|
className="w-8 h-8 rounded-full bg-white/10 flex items-center justify-center"
|
|
>
|
|
<ChevronLeft className="w-5 h-5 text-white" />
|
|
</button>
|
|
<h1 className="flex-1 text-center text-lg font-semibold text-white">收货地址</h1>
|
|
<div className="w-8" />
|
|
</div>
|
|
</header>
|
|
|
|
<main className="px-4 py-4">
|
|
{loading ? (
|
|
<div className="py-12 text-center text-white/40 text-sm">加载中...</div>
|
|
) : list.length === 0 ? (
|
|
<div className="py-12 text-center">
|
|
<MapPin className="w-12 h-12 text-white/30 mx-auto mb-3" />
|
|
<p className="text-white/60 text-sm">暂无收货地址</p>
|
|
<p className="text-white/40 text-xs mt-1">点击下方按钮添加</p>
|
|
</div>
|
|
) : (
|
|
<div className="space-y-3">
|
|
{list.map((item) => (
|
|
<div
|
|
key={item.id}
|
|
className="rounded-xl bg-[#1c1c1e] border border-white/5 p-4"
|
|
>
|
|
<div className="flex items-center justify-between mb-2">
|
|
<span className="text-white font-medium">{item.name}</span>
|
|
<span className="text-white/50 text-sm">{item.phone}</span>
|
|
{item.isDefault && (
|
|
<span className="text-xs px-2 py-0.5 rounded bg-[#00CED1]/20 text-[#00CED1]">
|
|
默认
|
|
</span>
|
|
)}
|
|
</div>
|
|
<p className="text-white/60 text-sm leading-relaxed">{item.fullAddress}</p>
|
|
<div className="flex justify-end gap-4 mt-3 pt-3 border-t border-white/5">
|
|
<button
|
|
onClick={() => router.push(`/my/addresses/${item.id}`)}
|
|
className="flex items-center gap-1 text-[#00CED1] text-sm"
|
|
>
|
|
<Pencil className="w-4 h-4" /> 编辑
|
|
</button>
|
|
<button
|
|
onClick={() => handleDelete(item.id)}
|
|
className="flex items-center gap-1 text-red-400 text-sm"
|
|
>
|
|
<Trash2 className="w-4 h-4" /> 删除
|
|
</button>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
|
|
<button
|
|
onClick={() => router.push("/my/addresses/new")}
|
|
className="mt-6 w-full py-3 rounded-xl bg-[#00CED1] text-black font-medium flex items-center justify-center gap-2"
|
|
>
|
|
<Plus className="w-5 h-5" /> 新增收货地址
|
|
</button>
|
|
</main>
|
|
</div>
|
|
)
|
|
}
|