sync: soul-admin 页面 | 原因: 前端页面修改
This commit is contained in:
@@ -6,6 +6,7 @@ import {
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { RefreshCw } from 'lucide-react'
|
||||
import { Pagination } from '@/components/ui/Pagination'
|
||||
import { UserDetailModal } from '@/components/modules/user/UserDetailModal'
|
||||
import { get } from '@/api/client'
|
||||
|
||||
interface MatchRecord {
|
||||
@@ -15,7 +16,7 @@ interface MatchRecord {
|
||||
}
|
||||
|
||||
const matchTypeLabels: Record<string, string> = {
|
||||
partner: '超级个体', investor: '资源对接', mentor: '导师顾问', team: '团队招募',
|
||||
partner: '找伙伴', investor: '资源对接', mentor: '导师顾问', team: '团队招募',
|
||||
}
|
||||
|
||||
export function MatchRecordsTab() {
|
||||
@@ -26,6 +27,7 @@ export function MatchRecordsTab() {
|
||||
const [matchTypeFilter, setMatchTypeFilter] = useState('')
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const [detailUserId, setDetailUserId] = useState<string | null>(null)
|
||||
|
||||
async function loadRecords() {
|
||||
setIsLoading(true); setError(null)
|
||||
@@ -43,6 +45,19 @@ export function MatchRecordsTab() {
|
||||
|
||||
const totalPages = Math.ceil(total / pageSize) || 1
|
||||
|
||||
const UserCell = ({ userId, nickname, avatar }: { userId: string; nickname?: string; avatar?: string }) => (
|
||||
<div className="flex items-center gap-3 cursor-pointer group" onClick={() => setDetailUserId(userId)}>
|
||||
<div className="w-9 h-9 rounded-full bg-[#38bdac]/20 flex items-center justify-center text-sm font-medium text-[#38bdac] flex-shrink-0 overflow-hidden">
|
||||
{avatar ? <img src={avatar} alt="" className="w-full h-full object-cover" onError={e => { (e.currentTarget as HTMLImageElement).style.display = 'none' }} /> : null}
|
||||
<span className={avatar ? 'hidden' : ''}>{(nickname || userId || '?').charAt(0)}</span>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-white group-hover:text-[#38bdac] transition-colors">{nickname || userId}</div>
|
||||
<div className="text-xs text-gray-500 font-mono">{userId?.slice(0, 16)}{userId?.length > 16 ? '...' : ''}</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
return (
|
||||
<div>
|
||||
{error && (
|
||||
@@ -52,7 +67,7 @@ export function MatchRecordsTab() {
|
||||
</div>
|
||||
)}
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<p className="text-gray-400">共 {total} 条匹配记录</p>
|
||||
<p className="text-gray-400">共 {total} 条匹配记录 · 点击用户名查看详情</p>
|
||||
<div className="flex items-center gap-4">
|
||||
<select value={matchTypeFilter} onChange={e => { setMatchTypeFilter(e.target.value); setPage(1) }}
|
||||
className="bg-[#0f2137] border border-gray-700 text-white rounded-lg px-3 py-2 text-sm">
|
||||
@@ -86,34 +101,20 @@ export function MatchRecordsTab() {
|
||||
{records.map(r => (
|
||||
<TableRow key={r.id} className="hover:bg-[#0a1628] border-gray-700/50">
|
||||
<TableCell>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-9 h-9 rounded-full bg-[#38bdac]/20 flex items-center justify-center text-sm font-medium text-[#38bdac] flex-shrink-0 overflow-hidden">
|
||||
{r.userAvatar ? <img src={r.userAvatar} alt="" className="w-full h-full object-cover" onError={e => { (e.currentTarget as HTMLImageElement).style.display = 'none' }} /> : null}
|
||||
<span className={r.userAvatar ? 'hidden' : ''}>{(r.userNickname || r.userId || '?').charAt(0)}</span>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-white">{r.userNickname || r.userId}</div>
|
||||
<div className="text-xs text-gray-500 font-mono">{r.userId.slice(0, 16)}...</div>
|
||||
</div>
|
||||
</div>
|
||||
<UserCell userId={r.userId} nickname={r.userNickname} avatar={r.userAvatar} />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-9 h-9 rounded-full bg-[#38bdac]/20 flex items-center justify-center text-sm font-medium text-[#38bdac] flex-shrink-0 overflow-hidden">
|
||||
{r.matchedUserAvatar ? <img src={r.matchedUserAvatar} alt="" className="w-full h-full object-cover" onError={e => { (e.currentTarget as HTMLImageElement).style.display = 'none' }} /> : null}
|
||||
<span className={r.matchedUserAvatar ? 'hidden' : ''}>{(r.matchedNickname || r.matchedUserId || '?').charAt(0)}</span>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-white">{r.matchedNickname || r.matchedUserId}</div>
|
||||
<div className="text-xs text-gray-500 font-mono">{r.matchedUserId.slice(0, 16)}...</div>
|
||||
</div>
|
||||
</div>
|
||||
{r.matchedUserId ? (
|
||||
<UserCell userId={r.matchedUserId} nickname={r.matchedNickname} avatar={r.matchedUserAvatar} />
|
||||
) : (
|
||||
<span className="text-gray-500">—</span>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell><Badge className="bg-[#38bdac]/20 text-[#38bdac] border-0">{matchTypeLabels[r.matchType] || r.matchType}</Badge></TableCell>
|
||||
<TableCell className="text-gray-400 text-sm">
|
||||
{r.phone && <div>📱 {r.phone}</div>}
|
||||
{r.wechatId && <div>💬 {r.wechatId}</div>}
|
||||
{!r.phone && !r.wechatId && '-'}
|
||||
<TableCell className="text-sm">
|
||||
{r.phone && <div className="text-green-400">📱 {r.phone}</div>}
|
||||
{r.wechatId && <div className="text-blue-400">💬 {r.wechatId}</div>}
|
||||
{!r.phone && !r.wechatId && <span className="text-gray-600">-</span>}
|
||||
</TableCell>
|
||||
<TableCell className="text-gray-400">{r.createdAt ? new Date(r.createdAt).toLocaleString() : '-'}</TableCell>
|
||||
</TableRow>
|
||||
@@ -127,6 +128,13 @@ export function MatchRecordsTab() {
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<UserDetailModal
|
||||
open={!!detailUserId}
|
||||
onClose={() => setDetailUserId(null)}
|
||||
userId={detailUserId}
|
||||
onUserUpdated={loadRecords}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user