sync: soul-admin 页面 | 原因: 前端页面修改

This commit is contained in:
卡若
2026-03-08 11:27:11 +08:00
parent 133eed2cc4
commit 4a3d034233

View File

@@ -6,6 +6,7 @@ import {
import { Badge } from '@/components/ui/badge' import { Badge } from '@/components/ui/badge'
import { RefreshCw } from 'lucide-react' import { RefreshCw } from 'lucide-react'
import { Pagination } from '@/components/ui/Pagination' import { Pagination } from '@/components/ui/Pagination'
import { UserDetailModal } from '@/components/modules/user/UserDetailModal'
import { get } from '@/api/client' import { get } from '@/api/client'
interface MatchRecord { interface MatchRecord {
@@ -15,7 +16,7 @@ interface MatchRecord {
} }
const matchTypeLabels: Record<string, string> = { const matchTypeLabels: Record<string, string> = {
partner: '超级个体', investor: '资源对接', mentor: '导师顾问', team: '团队招募', partner: '找伙伴', investor: '资源对接', mentor: '导师顾问', team: '团队招募',
} }
export function MatchRecordsTab() { export function MatchRecordsTab() {
@@ -26,6 +27,7 @@ export function MatchRecordsTab() {
const [matchTypeFilter, setMatchTypeFilter] = useState('') const [matchTypeFilter, setMatchTypeFilter] = useState('')
const [isLoading, setIsLoading] = useState(true) const [isLoading, setIsLoading] = useState(true)
const [error, setError] = useState<string | null>(null) const [error, setError] = useState<string | null>(null)
const [detailUserId, setDetailUserId] = useState<string | null>(null)
async function loadRecords() { async function loadRecords() {
setIsLoading(true); setError(null) setIsLoading(true); setError(null)
@@ -43,6 +45,19 @@ export function MatchRecordsTab() {
const totalPages = Math.ceil(total / pageSize) || 1 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 ( return (
<div> <div>
{error && ( {error && (
@@ -52,7 +67,7 @@ export function MatchRecordsTab() {
</div> </div>
)} )}
<div className="flex justify-between items-center mb-4"> <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"> <div className="flex items-center gap-4">
<select value={matchTypeFilter} onChange={e => { setMatchTypeFilter(e.target.value); setPage(1) }} <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"> 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 => ( {records.map(r => (
<TableRow key={r.id} className="hover:bg-[#0a1628] border-gray-700/50"> <TableRow key={r.id} className="hover:bg-[#0a1628] border-gray-700/50">
<TableCell> <TableCell>
<div className="flex items-center gap-3"> <UserCell userId={r.userId} nickname={r.userNickname} avatar={r.userAvatar} />
<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>
</TableCell> </TableCell>
<TableCell> <TableCell>
<div className="flex items-center gap-3"> {r.matchedUserId ? (
<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"> <UserCell userId={r.matchedUserId} nickname={r.matchedNickname} avatar={r.matchedUserAvatar} />
{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> <span className="text-gray-500"></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>
</TableCell> </TableCell>
<TableCell><Badge className="bg-[#38bdac]/20 text-[#38bdac] border-0">{matchTypeLabels[r.matchType] || r.matchType}</Badge></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"> <TableCell className="text-sm">
{r.phone && <div>📱 {r.phone}</div>} {r.phone && <div className="text-green-400">📱 {r.phone}</div>}
{r.wechatId && <div>💬 {r.wechatId}</div>} {r.wechatId && <div className="text-blue-400">💬 {r.wechatId}</div>}
{!r.phone && !r.wechatId && '-'} {!r.phone && !r.wechatId && <span className="text-gray-600">-</span>}
</TableCell> </TableCell>
<TableCell className="text-gray-400">{r.createdAt ? new Date(r.createdAt).toLocaleString() : '-'}</TableCell> <TableCell className="text-gray-400">{r.createdAt ? new Date(r.createdAt).toLocaleString() : '-'}</TableCell>
</TableRow> </TableRow>
@@ -127,6 +128,13 @@ export function MatchRecordsTab() {
)} )}
</CardContent> </CardContent>
</Card> </Card>
<UserDetailModal
open={!!detailUserId}
onClose={() => setDetailUserId(null)}
userId={detailUserId}
onUserUpdated={loadRecords}
/>
</div> </div>
) )
} }