Ensure compatibility with both default and named imports for hook. #VERCEL_SKIP Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
97 lines
3.3 KiB
TypeScript
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>
|
|
)
|
|
}
|