feat: 支持微信用户列表展示
This commit is contained in:
109
components/wx-users/wx-user-detail-dialog.tsx
Normal file
109
components/wx-users/wx-user-detail-dialog.tsx
Normal 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>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user