feat: 支持微信用户列表展示

This commit is contained in:
richarjiang
2026-04-05 20:19:08 +08:00
parent 7bce04a163
commit f8f6f17bd4
8 changed files with 508 additions and 1 deletions

View File

@@ -0,0 +1,109 @@
'use client'
import { WxUserWithProgress } from '@/types'
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogDescription,
} from '@/components/ui/dialog'
interface WxUserDetailDialogProps {
open: boolean
onOpenChange: (open: boolean) => void
user: WxUserWithProgress | null | undefined
}
export function WxUserDetailDialog({
open,
onOpenChange,
user,
}: WxUserDetailDialogProps) {
if (!user) return null
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent>
<DialogHeader>
<DialogTitle></DialogTitle>
<DialogDescription>
</DialogDescription>
</DialogHeader>
<div className="space-y-4">
<div className="flex items-center gap-4">
<div className="w-16 h-16 flex-shrink-0">
{user.avatarUrl ? (
<img
src={user.avatarUrl}
alt={user.nickname || 'User'}
className="w-16 h-16 rounded-full object-cover"
/>
) : (
<div className="w-16 h-16 rounded-full bg-gray-200 flex items-center justify-center text-xl font-medium text-gray-600">
{user.nickname?.[0]?.toUpperCase() || 'U'}
</div>
)}
</div>
<div>
<h2 className="text-xl font-semibold text-gray-900">
{user.nickname || '匿名用户'}
</h2>
<p className="text-sm text-gray-500 mt-1">
{new Date(user.createdAt).toLocaleDateString('zh-CN')}
</p>
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="bg-gray-50 rounded-lg p-4">
<p className="text-xs text-gray-500 uppercase tracking-wider mb-1"></p>
<p className="text-2xl font-bold text-orange-600">{user.points}</p>
</div>
<div className="bg-gray-50 rounded-lg p-4">
<p className="text-xs text-gray-500 uppercase tracking-wider mb-1"></p>
<p className="text-2xl font-bold text-green-600">{user.levelProgress.length}</p>
</div>
</div>
<div>
<p className="text-xs text-gray-500 uppercase tracking-wider mb-2">OpenID</p>
<code className="block bg-gray-100 text-gray-800 text-xs p-3 rounded-lg break-all">
{user.openid}
</code>
</div>
{user.levelProgress.length > 0 && (
<div>
<p className="text-xs text-gray-500 uppercase tracking-wider mb-2"></p>
<div className="space-y-2">
{user.levelProgress.map((progress) => (
<div
key={progress.id}
className="flex items-center justify-between bg-gray-50 rounded-lg px-3 py-2"
>
<div className="flex flex-col">
<span className="text-xs text-gray-400 font-mono">
{progress.levelId}
</span>
{progress.level && (
<span className="text-sm font-medium text-gray-900">
{progress.level.answer}
</span>
)}
</div>
<span className="text-xs text-gray-400">
{new Date(progress.completedAt).toLocaleDateString('zh-CN')}
</span>
</div>
))}
</div>
</div>
)}
</div>
</DialogContent>
</Dialog>
)
}