競賽資訊完整版 ( 只剩評分、競賽得獎 )
This commit is contained in:
@@ -77,8 +77,8 @@ export async function GET(request: NextRequest, { params }: { params: { id: stri
|
||||
likes_count: app.likes_count || 0,
|
||||
views_count: app.views_count || 0,
|
||||
rating: Math.round(avgRating * 10) / 10, // 四捨五入到小數點後一位
|
||||
creator_name: "未知作者",
|
||||
creator_department: "未知部門",
|
||||
creator_name: app.creator_name || "未知作者",
|
||||
creator_department: app.creator_department || "未知部門",
|
||||
team_name: team.name,
|
||||
created_at: app.created_at
|
||||
};
|
||||
|
@@ -39,6 +39,11 @@ import {
|
||||
Trophy,
|
||||
Award,
|
||||
Medal,
|
||||
Bot,
|
||||
Code,
|
||||
Database,
|
||||
Palette,
|
||||
Volume2,
|
||||
} from "lucide-react"
|
||||
import { FavoriteButton } from "./favorite-button"
|
||||
import { ReviewSystem } from "./reviews/review-system"
|
||||
@@ -48,15 +53,21 @@ interface AppDetailDialogProps {
|
||||
open: boolean
|
||||
onOpenChange: (open: boolean) => void
|
||||
app: {
|
||||
id: number
|
||||
id: string
|
||||
name: string
|
||||
type: string
|
||||
department: string
|
||||
description: string
|
||||
icon: any
|
||||
iconColor?: string
|
||||
creator: string
|
||||
featured: boolean
|
||||
judgeScore: number
|
||||
likesCount?: number
|
||||
viewsCount?: number
|
||||
rating?: number
|
||||
reviewsCount?: number
|
||||
createdAt?: string
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,11 +123,17 @@ export function AppDetailDialog({ open, onOpenChange, app }: AppDetailDialogProp
|
||||
// 圖標映射函數
|
||||
const getIconComponent = (iconName: string) => {
|
||||
const iconMap: { [key: string]: any } = {
|
||||
'Bot': Brain,
|
||||
'ImageIcon': ImageIcon,
|
||||
'Brain': Brain,
|
||||
'Bot': Bot,
|
||||
'Code': Code,
|
||||
'Database': Database,
|
||||
'Palette': Palette,
|
||||
'Volume2': Volume2,
|
||||
'Search': Search,
|
||||
'BarChart3': BarChart3,
|
||||
'Mic': Mic,
|
||||
'ImageIcon': ImageIcon,
|
||||
'MessageSquare': MessageSquare,
|
||||
'Settings': Settings,
|
||||
'Zap': Zap,
|
||||
'TrendingUp': TrendingUp,
|
||||
'Star': Star,
|
||||
@@ -128,21 +145,23 @@ export function AppDetailDialog({ open, onOpenChange, app }: AppDetailDialogProp
|
||||
'Target': Target,
|
||||
'Users': Users,
|
||||
'Lightbulb': Lightbulb,
|
||||
'Search': Search,
|
||||
'Plus': Plus,
|
||||
'X': X,
|
||||
'ChevronLeft': ChevronLeft,
|
||||
'ChevronRight': ChevronRight,
|
||||
'ArrowLeft': ArrowLeft
|
||||
'ArrowLeft': ArrowLeft,
|
||||
'Settings': Settings
|
||||
}
|
||||
return iconMap[iconName] || Brain // 預設使用 Brain 圖標
|
||||
}
|
||||
|
||||
const IconComponent = getIconComponent(app.icon || 'Bot')
|
||||
const likes = (app as any).likesCount || 0
|
||||
const views = (app as any).viewsCount || 0
|
||||
const rating = (app as any).rating || 0
|
||||
const reviewsCount = (app as any).reviewsCount || 0
|
||||
// 優先使用從 API 載入的實際數據,如果沒有則使用 app 對象的數據
|
||||
const likes = appStats.basic?.likes || (app as any).likesCount || 0
|
||||
const views = appStats.basic?.views || (app as any).viewsCount || 0
|
||||
const rating = appStats.basic?.rating || (app as any).rating || 0
|
||||
const reviewsCount = appStats.basic?.reviewCount || (app as any).reviewsCount || 0
|
||||
const favorites = appStats.basic?.favorites || 0
|
||||
// 使用從 API 載入的實際數據
|
||||
const usageStats = appStats.usage
|
||||
|
||||
@@ -169,13 +188,27 @@ export function AppDetailDialog({ open, onOpenChange, app }: AppDetailDialogProp
|
||||
if (department) params.append('department', department)
|
||||
|
||||
const url = `/api/apps/${app.id}/stats${params.toString() ? `?${params.toString()}` : ''}`
|
||||
console.log('🔍 調用統計 API:', url)
|
||||
console.log('🔍 應用 ID:', app.id)
|
||||
|
||||
const response = await fetch(url)
|
||||
console.log('🔍 API 響應狀態:', response.status, response.statusText)
|
||||
|
||||
if (!response.ok) {
|
||||
console.error('❌ API 響應錯誤:', response.status, response.statusText)
|
||||
return
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
console.log('🔍 API 響應數據:', data)
|
||||
|
||||
if (data.success) {
|
||||
console.log('📊 應用統計數據加載成功:', data.data)
|
||||
setAppStats(data.data)
|
||||
setCurrentRating(data.data.basic.rating)
|
||||
setReviewCount(data.data.basic.reviewCount)
|
||||
} else {
|
||||
console.error('❌ 應用統計數據加載失敗:', data)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('載入應用統計數據錯誤:', error)
|
||||
@@ -489,7 +522,7 @@ export function AppDetailDialog({ open, onOpenChange, app }: AppDetailDialogProp
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold text-purple-600">
|
||||
{isLoadingStats ? '...' : (appStats.basic as any).favorites || 0}
|
||||
{isLoadingStats ? '...' : favorites}
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">用戶收藏數量</p>
|
||||
</CardContent>
|
||||
|
@@ -70,16 +70,19 @@ const getAppDetails = (appId: string, team: any) => {
|
||||
type: appDetail.type || "未知類型",
|
||||
description: appDetail.description || "無描述",
|
||||
icon: getIconComponent(appDetail.icon) || Brain,
|
||||
iconColor: appDetail.icon_color || "from-blue-500 to-purple-500",
|
||||
fullDescription: appDetail.description || "無描述",
|
||||
features: [],
|
||||
author: appDetail.creator_name || "未知作者",
|
||||
department: appDetail.creator_department || "未知部門",
|
||||
category: appDetail.category || "未分類",
|
||||
tags: [],
|
||||
demoUrl: "",
|
||||
sourceUrl: "",
|
||||
likes: appDetail.likes_count || 0,
|
||||
views: appDetail.views_count || 0,
|
||||
rating: Number(appDetail.rating) || 0
|
||||
rating: Number(appDetail.rating) || 0,
|
||||
createdAt: appDetail.created_at
|
||||
};
|
||||
}
|
||||
|
||||
@@ -126,17 +129,22 @@ export function TeamDetailDialog({ open, onOpenChange, team }: TeamDetailDialogP
|
||||
const appDetails = getAppDetails(appId, team)
|
||||
// Create app object that matches AppDetailDialog interface
|
||||
const app = {
|
||||
id: Number.parseInt(appId),
|
||||
id: appId, // 保持為字符串,API 期望字符串 ID
|
||||
name: appDetails.name,
|
||||
type: appDetails.type,
|
||||
department: team.department, // Use team's department
|
||||
department: appDetails.department, // Use app's creator department
|
||||
description: appDetails.description,
|
||||
icon: appDetails.icon,
|
||||
iconColor: appDetails.iconColor, // Pass icon color
|
||||
creator: appDetails.author,
|
||||
featured: false,
|
||||
judgeScore: appDetails.rating || 0,
|
||||
likes: appDetails.likes || 0,
|
||||
views: appDetails.views || 0,
|
||||
// 使用 AppDetailDialog 期望的屬性名
|
||||
likesCount: appDetails.likes || 0,
|
||||
viewsCount: appDetails.views || 0,
|
||||
rating: appDetails.rating || 0,
|
||||
reviewsCount: 0, // 可以從 API 獲取,暫時設為 0
|
||||
createdAt: appDetails.createdAt, // Pass creation date
|
||||
}
|
||||
setSelectedApp(app)
|
||||
setAppDetailOpen(true)
|
||||
|
@@ -1151,10 +1151,14 @@ export class TeamService {
|
||||
static async getTeamApps(teamId: string): Promise<any[]> {
|
||||
console.log('🔍 TeamService.getTeamApps 被調用, teamId:', teamId);
|
||||
const sql = `
|
||||
SELECT id, name, description, category, type, icon, icon_color, app_url, likes_count, views_count, rating
|
||||
FROM apps
|
||||
WHERE team_id = ? AND is_active = TRUE
|
||||
ORDER BY created_at DESC
|
||||
SELECT
|
||||
a.id, a.name, a.description, a.category, a.type, a.icon, a.icon_color,
|
||||
a.app_url, a.likes_count, a.views_count, a.rating, a.created_at,
|
||||
u.name as creator_name, u.department as creator_department
|
||||
FROM apps a
|
||||
LEFT JOIN users u ON a.creator_id = u.id
|
||||
WHERE a.team_id = ? AND a.is_active = TRUE
|
||||
ORDER BY a.created_at DESC
|
||||
`;
|
||||
console.log('📝 getTeamApps SQL:', sql);
|
||||
console.log('📝 getTeamApps 參數:', [teamId]);
|
||||
|
Reference in New Issue
Block a user