Files
users/app/user-portrait/[id]/page.tsx
v0 ce0a716d02 fix: support default and named export for useDebounce hook
Ensure compatibility with both default and named imports for hook.

#VERCEL_SKIP

Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
2025-09-23 07:09:47 +00:00

97 lines
3.3 KiB
TypeScript

"use client"
import { useEffect, useState } from "react"
import { useParams } from "next/navigation"
import MobileHeader from "@/app/components/MobileHeader"
import BottomNav from "@/app/components/BottomNav"
import Section from "@/components/user-portrait/mobile/section"
import ProfileHeader from "@/components/user-portrait/mobile/profile-header"
import MetricsRFM from "@/components/user-portrait/mobile/metrics-rfm"
import InteractionsList from "@/components/user-portrait/mobile/interactions-list"
import PurchaseHistory from "@/components/user-portrait/mobile/purchase-history"
import WechatAccounts from "@/components/user-portrait/mobile/wechat-accounts"
type Detail = {
id: string
name: string
avatar?: string
email: string
phone: string
tags: string[]
recency: number
frequency: number
monetary: number
rfmScore: number
lastActivity: string
interactions: { id: string; type: string; time: string; note?: string }[]
purchaseHistory: { id: string; amount: number; time: string; item: string }[]
wechatAccounts: { id: string; nickname: string; avatar?: string }[]
status: "活跃" | "沉睡" | "流失风险"
}
export default function UserDetailPage() {
const params = useParams<{ id: string }>()
const [data, setData] = useState<Detail | null>(null)
const [loading, setLoading] = useState(true)
useEffect(() => {
if (!params?.id) return
setLoading(true)
fetch(`/api/users?id=${params.id}`)
.then((r) => r.json())
.then((res) => setData(res?.data ?? null))
.finally(() => setLoading(false))
}, [params?.id])
return (
<div className="min-h-screen bg-gradient-to-br from-slate-50 via-white to-purple-50">
<MobileHeader onMenuToggle={() => {}} title="用户详情" />
<main className="container mx-auto px-4 pb-24 space-y-4">
{loading ? (
<div className="rounded-xl bg-white/60 backdrop-blur p-6 text-sm text-muted-foreground">
</div>
) : data ? (
<div className="space-y-4">
<section className="rounded-2xl bg-white/60 backdrop-blur-md p-4 shadow-sm border">
<ProfileHeader
name={data.name}
avatar={data.avatar}
email={data.email}
phone={data.phone}
tags={data.tags}
/>
</section>
<Section title="RFM 指标">
<MetricsRFM
recency={data.recency}
frequency={data.frequency}
monetary={data.monetary}
rfmScore={data.rfmScore}
/>
</Section>
<Section title="互动记录">
<InteractionsList items={data.interactions} />
</Section>
<Section title="购买历史">
<PurchaseHistory items={data.purchaseHistory} />
</Section>
<Section title="绑定微信账号">
<WechatAccounts accounts={data.wechatAccounts.map((w) => ({ id: w.id, nickname: w.nickname, avatar: w.avatar }))} />
</Section>
</div>
) : (
<div className="rounded-xl bg-white/60 backdrop-blur p-6 text-sm text-red-600">
</div>
)}
</main>
<BottomNav />
</div>
)
}