修正團體管理的 BUG

This commit is contained in:
2025-09-19 18:36:35 +08:00
parent 95c0c4cb23
commit 8ec5ead183
11 changed files with 367 additions and 137 deletions

View File

@@ -372,7 +372,7 @@ export function CompetitionDetailDialog({
<div
key={member.id}
className={`border rounded-lg p-4 ${
member.id === team.leader ? "border-green-300 bg-green-50" : "border-gray-200"
member.role === '隊長' ? "border-green-300 bg-green-50" : "border-gray-200"
}`}
>
<div className="flex items-center space-x-3">
@@ -383,7 +383,7 @@ export function CompetitionDetailDialog({
<div className="flex-1">
<div className="flex items-center space-x-2">
<h4 className="font-semibold">{member.name}</h4>
{member.id === team.leader && (
{member.role === '隊長' && (
<Badge variant="secondary" className="bg-green-100 text-green-800">
</Badge>

View File

@@ -453,7 +453,7 @@ export function PopularityRankings() {
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 px-8">
{currentTeams.map((team, index) => {
const globalRank = startIndex + index + 1
const leader = team.members.find((m: any) => m.id === team.leader)
const leader = team.members.find((m: any) => m.role === '隊長')
return (
<Card
@@ -474,7 +474,7 @@ export function PopularityRankings() {
<div className="flex-1 min-w-0">
<h4 className="font-bold text-gray-900 mb-1 truncate">{team.name}</h4>
<p className="text-sm text-gray-600 mb-2">{leader?.name}</p>
<p className="text-sm text-gray-600 mb-2">{leader?.name || '未知隊長'}</p>
<div className="flex flex-wrap gap-1">
<Badge variant="outline" className="bg-green-100 text-green-800 border-green-200 text-xs">
@@ -496,7 +496,13 @@ export function PopularityRankings() {
{member.name[0]}
</div>
<span className="text-gray-600">{member.name}</span>
<span className="text-gray-400">({member.role})</span>
<span className={`text-xs px-1 py-0.5 rounded ${
member.role === '隊長'
? 'bg-yellow-100 text-yellow-800'
: 'text-gray-400'
}`}>
{member.role}
</span>
</div>
))}
{team.members.length > 3 && (

View File

@@ -71,7 +71,13 @@ const getIconComponent = (iconName: string) => {
// App data for team apps - get from team data
const getAppDetails = (appId: string, team: any) => {
const appDetail = team.appsDetails?.find((app: any) => app.id === appId);
// 首先嘗試從 appsDetails 獲取
let appDetail = team.appsDetails?.find((app: any) => app.id === appId);
// 如果沒有找到,嘗試從 apps 獲取
if (!appDetail) {
appDetail = team.apps?.find((app: any) => app.id === appId);
}
if (appDetail) {
return {
@@ -311,7 +317,7 @@ export function TeamDetailDialog({ open, onOpenChange, team }: TeamDetailDialogP
<div className="flex-1">
<div className="flex items-center space-x-2">
<h4 className="font-medium">{member.name}</h4>
{member.id === team.leader && (
{member.role === '隊長' && (
<Badge variant="default" className="bg-yellow-100 text-yellow-800 text-xs">
</Badge>
@@ -334,19 +340,36 @@ export function TeamDetailDialog({ open, onOpenChange, team }: TeamDetailDialogP
</CardHeader>
<CardContent>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{team.apps.map((appId: string) => {
const app = getAppDetails(appId, team)
{team.apps.map((app: any) => {
// 如果 app 是字符串 ID使用 getAppDetails 獲取詳情
// 如果 app 是對象,直接使用
const appData = typeof app === 'string' ? getAppDetails(app, team) : {
id: app.id,
name: app.name || "未命名應用",
type: app.type || "未知類型",
description: app.description || "無描述",
icon: getIconComponent(app.icon) || Brain,
iconColor: app.icon_color || "from-blue-500 to-purple-500",
author: app.creator_name || "未知作者",
department: app.creator_department || "未知部門",
category: app.category || "未分類",
likes: app.likes_count || 0,
views: app.views_count || 0,
rating: Number(app.rating) || 0,
createdAt: app.created_at
}
// 如果沒有圖標,使用默認的 Brain 圖標
const IconComponent = app.icon || Brain
const likes = app.likes || 0
const views = app.views || 0
const rating = app.rating || 0
const IconComponent = appData.icon || Brain
const likes = appData.likes || 0
const views = appData.views || 0
const rating = appData.rating || 0
return (
<Card
key={appId}
key={appData.id}
className="hover:shadow-md transition-all duration-200 cursor-pointer group"
onClick={() => handleAppClick(appId)}
onClick={() => handleAppClick(appData.id)}
>
<CardContent className="p-4 flex flex-col h-full">
<div className="flex items-start space-x-3 mb-3">
@@ -356,16 +379,16 @@ export function TeamDetailDialog({ open, onOpenChange, team }: TeamDetailDialogP
<div className="flex-1">
<div className="flex items-center space-x-2">
<h4 className="font-medium text-gray-900 group-hover:text-blue-600 transition-colors">
{app.name}
{appData.name}
</h4>
<ExternalLink className="w-3 h-3 text-gray-400 group-hover:text-blue-500 opacity-0 group-hover:opacity-100 transition-all" />
</div>
<Badge variant="outline" className={`${getTypeColor(app.type)} text-xs mt-1`}>
{app.type}
<Badge variant="outline" className={`${getTypeColor(appData.type)} text-xs mt-1`}>
{appData.type}
</Badge>
</div>
</div>
<p className="text-sm text-gray-600 mb-3 line-clamp-2">{app.description}</p>
<p className="text-sm text-gray-600 mb-3 line-clamp-2">{appData.description}</p>
<div className="flex items-center justify-between mt-auto">
<div className="flex items-center space-x-3 text-xs text-gray-500">
<div className="flex items-center space-x-1">
@@ -379,7 +402,7 @@ export function TeamDetailDialog({ open, onOpenChange, team }: TeamDetailDialogP
</div>
<div onClick={(e) => e.stopPropagation()}>
<LikeButton
appId={appId}
appId={appData.id}
size="sm"
likeCount={likes}
showCount={true}