Files
soul-yongping/app/view/my/addresses/[id]/page.tsx

162 lines
6.4 KiB
TypeScript
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 { useState, useEffect } from "react"
import { useRouter, useParams } from "next/navigation"
import { ChevronLeft } from "lucide-react"
import { useStore } from "@/lib/store"
export default function EditAddressPage() {
const router = useRouter()
const params = useParams()
const id = params?.id as string
const { user } = useStore()
const [loading, setLoading] = useState(false)
const [fetching, setFetching] = useState(true)
const [name, setName] = useState("")
const [phone, setPhone] = useState("")
const [province, setProvince] = useState("")
const [city, setCity] = useState("")
const [district, setDistrict] = useState("")
const [detail, setDetail] = useState("")
const [isDefault, setIsDefault] = useState(false)
useEffect(() => {
if (!id || !user?.id) {
setFetching(false)
return
}
fetch(`/api/user/addresses/${id}`)
.then((res) => res.json())
.then((data) => {
if (data.success && data.item) {
const a = data.item
setName(a.name || "")
setPhone(a.phone || "")
setProvince(a.province || "")
setCity(a.city || "")
setDistrict(a.district || "")
setDetail(a.detail || "")
setIsDefault(!!a.isDefault)
}
})
.finally(() => setFetching(false))
}, [id, user?.id])
if (!user?.id) {
return (
<div className="min-h-screen bg-black text-white flex items-center justify-center">
<p className="text-white/60"></p>
</div>
)
}
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
if (!name.trim()) {
alert("请输入收货人姓名")
return
}
if (!/^1[3-9]\d{9}$/.test(phone)) {
alert("请输入正确的手机号")
return
}
if (!detail.trim()) {
alert("请输入详细地址")
return
}
setLoading(true)
try {
const res = await fetch(`/api/user/addresses/${id}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
name: name.trim(),
phone: phone.trim(),
province: (province ?? "").trim(),
city: (city ?? "").trim(),
district: (district ?? "").trim(),
detail: detail.trim(),
isDefault,
}),
})
const data = await res.json()
if (data.success) {
router.push("/view/my/addresses")
} else {
alert(data.message || "保存失败")
}
} catch {
alert("保存失败")
} finally {
setLoading(false)
}
}
if (fetching) {
return (
<div className="min-h-screen bg-black text-white flex items-center justify-center">
<div className="animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-[#00CED1]" />
</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>
<form onSubmit={handleSubmit} className="px-4 py-4 space-y-4">
<div className="rounded-2xl bg-[#1c1c1e] border border-white/5 overflow-hidden">
<div className="flex items-center justify-between p-4 border-b border-white/5">
<label className="text-white text-sm w-24"></label>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="请输入收货人姓名"
className="flex-1 bg-transparent text-white text-sm text-right placeholder-white/30 outline-none"
/>
</div>
<div className="flex items-center justify-between p-4 border-b border-white/5">
<label className="text-white text-sm w-24"></label>
<input
type="tel"
maxLength={11}
value={phone}
onChange={(e) => setPhone(e.target.value.replace(/\D/g, ""))}
placeholder="请输入手机号"
className="flex-1 bg-transparent text-white text-sm text-right placeholder-white/30 outline-none"
/>
</div>
<div className="flex items-center justify-between p-4 border-b border-white/5">
<label className="text-white text-sm w-24"></label>
<div className="flex-1 flex gap-2 justify-end">
<input type="text" value={province} onChange={(e) => setProvince(e.target.value)} placeholder="省" className="flex-1 max-w-24 bg-transparent text-white text-sm text-right placeholder-white/30 outline-none" />
<input type="text" value={city} onChange={(e) => setCity(e.target.value)} placeholder="市" className="flex-1 max-w-24 bg-transparent text-white text-sm text-right placeholder-white/30 outline-none" />
<input type="text" value={district} onChange={(e) => setDistrict(e.target.value)} placeholder="区" className="flex-1 max-w-24 bg-transparent text-white text-sm text-right placeholder-white/30 outline-none" />
</div>
</div>
<div className="flex items-start justify-between p-4">
<label className="text-white text-sm w-24 pt-2"></label>
<textarea value={detail} onChange={(e) => setDetail(e.target.value)} placeholder="街道、楼栋、门牌号等" rows={3} className="flex-1 bg-transparent text-white text-sm text-right placeholder-white/30 outline-none resize-none" />
</div>
<div className="flex items-center justify-between p-4 border-t border-white/5">
<span className="text-white text-sm"></span>
<input type="checkbox" checked={isDefault} onChange={(e) => setIsDefault(e.target.checked)} className="w-5 h-5 rounded accent-[#00CED1]" />
</div>
</div>
<button type="submit" disabled={loading} className="w-full py-3 rounded-xl bg-[#00CED1] text-black font-medium disabled:opacity-50">
{loading ? "保存中..." : "保存"}
</button>
</form>
</div>
)
}