修正得獎資訊團體賽的名稱
This commit is contained in:
@@ -140,7 +140,11 @@ export async function GET(request: NextRequest) {
|
|||||||
id: award.id,
|
id: award.id,
|
||||||
competition_name: (award as any).competition_name,
|
competition_name: (award as any).competition_name,
|
||||||
competition_type: (award as any).competition_type,
|
competition_type: (award as any).competition_type,
|
||||||
competition_id: award.competition_id
|
competition_id: award.competition_id,
|
||||||
|
team_name_from_teams: (award as any).team_name_from_teams,
|
||||||
|
team_name: (award as any).team_name,
|
||||||
|
app_name: (award as any).app_name,
|
||||||
|
team_id: (award as any).team_id
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -156,9 +160,9 @@ export async function GET(request: NextRequest) {
|
|||||||
awardType: award.award_type,
|
awardType: award.award_type,
|
||||||
teamName: (award as any).team_name_from_teams || award.team_name,
|
teamName: (award as any).team_name_from_teams || award.team_name,
|
||||||
appName: award.app_name,
|
appName: award.app_name,
|
||||||
applicationLinks: award.application_links ? JSON.parse(award.application_links) : null,
|
applicationLinks: (award as any).application_links ? JSON.parse((award as any).application_links) : null,
|
||||||
documents: award.documents ? JSON.parse(award.documents) : [],
|
documents: (award as any).documents ? JSON.parse((award as any).documents) : [],
|
||||||
photos: award.photos ? JSON.parse(award.photos) : [],
|
photos: (award as any).photos ? JSON.parse((award as any).photos) : [],
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -398,7 +398,7 @@ export default function CompetitionPage() {
|
|||||||
{monthAwards.map((award) => (
|
{monthAwards.map((award) => (
|
||||||
<Card
|
<Card
|
||||||
key={award.id}
|
key={award.id}
|
||||||
className="relative overflow-hidden border-0 shadow-lg bg-gradient-to-br from-white to-gray-50 hover:shadow-xl transition-shadow cursor-pointer"
|
className="relative overflow-hidden border-0 shadow-lg bg-gradient-to-br from-white to-gray-50 hover:shadow-xl transition-shadow cursor-pointer h-[320px] flex flex-col"
|
||||||
onClick={() => handleShowAwardDetail(award)}
|
onClick={() => handleShowAwardDetail(award)}
|
||||||
>
|
>
|
||||||
{/* Rank Badge */}
|
{/* Rank Badge */}
|
||||||
@@ -422,7 +422,7 @@ export default function CompetitionPage() {
|
|||||||
|
|
||||||
<div className="absolute top-4 right-4 text-3xl">{award.icon}</div>
|
<div className="absolute top-4 right-4 text-3xl">{award.icon}</div>
|
||||||
|
|
||||||
<CardHeader className="pb-3 pt-12">
|
<CardHeader className="pb-3 pt-12 flex-shrink-0">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<div className="flex flex-wrap gap-2">
|
<div className="flex flex-wrap gap-2">
|
||||||
<Badge
|
<Badge
|
||||||
@@ -450,11 +450,33 @@ export default function CompetitionPage() {
|
|||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<CardTitle className="text-lg line-clamp-2">
|
<CardTitle className="text-lg line-clamp-2 min-h-[2.5rem]">
|
||||||
{award.competitionType === "team"
|
{(() => {
|
||||||
? (award.teamName || "團隊名稱")
|
console.log('🔍 獎項資料:', {
|
||||||
: (award.appName || award.proposalTitle || "應用名稱")
|
id: award.id,
|
||||||
|
competitionType: award.competitionType,
|
||||||
|
teamName: award.teamName,
|
||||||
|
appName: award.appName,
|
||||||
|
proposalTitle: award.proposalTitle,
|
||||||
|
team_name: (award as any).team_name,
|
||||||
|
team_name_from_teams: (award as any).team_name_from_teams
|
||||||
|
});
|
||||||
|
|
||||||
|
// 團體賽優先顯示團隊名稱
|
||||||
|
if (award.competitionType === "team") {
|
||||||
|
// 優先使用從teams表查詢的團隊名稱,其次使用獎項表中的團隊名稱
|
||||||
|
const teamName = (award as any).team_name_from_teams || award.teamName || (award as any).team_name;
|
||||||
|
return teamName || "團隊名稱";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 提案賽顯示提案標題
|
||||||
|
if (award.competitionType === "proposal") {
|
||||||
|
return award.proposalTitle || "提案標題";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 個人賽顯示應用名稱
|
||||||
|
return award.appName || "應用名稱";
|
||||||
|
})()}
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
<p className="text-sm text-gray-500">by {award.creator}</p>
|
<p className="text-sm text-gray-500">by {award.creator}</p>
|
||||||
<div className="text-xs text-gray-400">
|
<div className="text-xs text-gray-400">
|
||||||
@@ -463,8 +485,8 @@ export default function CompetitionPage() {
|
|||||||
</div>
|
</div>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
|
|
||||||
<CardContent className="pt-0">
|
<CardContent className="pt-0 flex-grow flex flex-col justify-between">
|
||||||
<div className="space-y-4">
|
<div className="space-y-4 flex-grow">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<span className="text-sm text-gray-600">
|
<span className="text-sm text-gray-600">
|
||||||
{award.competitionType === "proposal"
|
{award.competitionType === "proposal"
|
||||||
@@ -483,9 +505,10 @@ export default function CompetitionPage() {
|
|||||||
: award.score}
|
: award.score}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
className="w-full bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-700 hover:to-pink-700"
|
className="w-full bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-700 hover:to-pink-700 mt-4"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
handleShowAwardDetail(award)
|
handleShowAwardDetail(award)
|
||||||
@@ -493,7 +516,6 @@ export default function CompetitionPage() {
|
|||||||
>
|
>
|
||||||
查看得獎詳情
|
查看得獎詳情
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
))}
|
))}
|
||||||
|
30
app/page.tsx
30
app/page.tsx
@@ -798,7 +798,7 @@ export default function AIShowcasePlatform() {
|
|||||||
{monthAwards.map((award) => (
|
{monthAwards.map((award) => (
|
||||||
<Card
|
<Card
|
||||||
key={award.id}
|
key={award.id}
|
||||||
className="relative overflow-hidden border-0 shadow-lg bg-gradient-to-br from-white to-gray-50 hover:shadow-xl transition-shadow cursor-pointer"
|
className="relative overflow-hidden border-0 shadow-lg bg-gradient-to-br from-white to-gray-50 hover:shadow-xl transition-shadow cursor-pointer h-[320px] flex flex-col"
|
||||||
onClick={() => handleShowAwardDetail(award)}
|
onClick={() => handleShowAwardDetail(award)}
|
||||||
>
|
>
|
||||||
{/* Rank Badge */}
|
{/* Rank Badge */}
|
||||||
@@ -822,7 +822,7 @@ export default function AIShowcasePlatform() {
|
|||||||
|
|
||||||
<div className="absolute top-4 right-4 text-3xl">{award.icon}</div>
|
<div className="absolute top-4 right-4 text-3xl">{award.icon}</div>
|
||||||
|
|
||||||
<CardHeader className="pb-3 pt-12">
|
<CardHeader className="pb-3 pt-12 flex-shrink-0">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<div className="flex flex-wrap gap-2">
|
<div className="flex flex-wrap gap-2">
|
||||||
<Badge
|
<Badge
|
||||||
@@ -850,8 +850,22 @@ export default function AIShowcasePlatform() {
|
|||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<CardTitle className="text-lg line-clamp-2">
|
<CardTitle className="text-lg line-clamp-2 min-h-[2.5rem]">
|
||||||
{award.appName || award.awardName}
|
{(() => {
|
||||||
|
// 團體賽優先顯示團隊名稱
|
||||||
|
if (award.competitionType === "team") {
|
||||||
|
const teamName = (award as any).team_name_from_teams || award.teamName || (award as any).team_name;
|
||||||
|
return teamName || "團隊名稱";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提案賽顯示提案標題
|
||||||
|
if (award.competitionType === "proposal") {
|
||||||
|
return award.proposalTitle || "提案標題";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 個人賽顯示應用名稱
|
||||||
|
return award.appName || award.awardName || "應用名稱";
|
||||||
|
})()}
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
<p className="text-sm text-gray-500">by {award.creator}</p>
|
<p className="text-sm text-gray-500">by {award.creator}</p>
|
||||||
<div className="text-xs text-gray-400">
|
<div className="text-xs text-gray-400">
|
||||||
@@ -860,8 +874,8 @@ export default function AIShowcasePlatform() {
|
|||||||
</div>
|
</div>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
|
|
||||||
<CardContent className="pt-0">
|
<CardContent className="pt-0 flex-grow flex flex-col justify-between">
|
||||||
<div className="space-y-4">
|
<div className="space-y-4 flex-grow">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<span className="text-sm text-gray-600">
|
<span className="text-sm text-gray-600">
|
||||||
{award.awardType === "popular"
|
{award.awardType === "popular"
|
||||||
@@ -878,9 +892,10 @@ export default function AIShowcasePlatform() {
|
|||||||
: award.score}
|
: award.score}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
className="w-full bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-700 hover:to-pink-700"
|
className="w-full bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-700 hover:to-pink-700 mt-4"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
handleShowAwardDetail(award)
|
handleShowAwardDetail(award)
|
||||||
@@ -888,7 +903,6 @@ export default function AIShowcasePlatform() {
|
|||||||
>
|
>
|
||||||
查看得獎詳情
|
查看得獎詳情
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
))}
|
))}
|
||||||
|
@@ -4046,12 +4046,12 @@ export function CompetitionManagement() {
|
|||||||
const paginatedAwards = filteredAwards.slice(startIndex, endIndex)
|
const paginatedAwards = filteredAwards.slice(startIndex, endIndex)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 min-h-[400px]" style={{ gridAutoRows: 'max-content' }}>
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 min-h-[400px]">
|
||||||
{paginatedAwards.map((award: any) => (
|
{paginatedAwards.map((award: any) => (
|
||||||
<Card key={award.id} className="relative overflow-hidden hover:shadow-lg transition-shadow">
|
<Card key={award.id} className="relative overflow-hidden hover:shadow-lg transition-shadow h-[280px] flex flex-col">
|
||||||
<div className="absolute top-4 right-4 text-2xl">{award.icon}</div>
|
<div className="absolute top-4 right-4 text-2xl">{award.icon}</div>
|
||||||
<CardContent className="p-4">
|
<CardContent className="p-4 flex-grow flex flex-col justify-between">
|
||||||
<div className="space-y-3">
|
<div className="space-y-3 flex-grow">
|
||||||
{/* 獎項基本資訊 */}
|
{/* 獎項基本資訊 */}
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Badge
|
<Badge
|
||||||
@@ -4074,8 +4074,22 @@ export function CompetitionManagement() {
|
|||||||
>
|
>
|
||||||
{award.award_name}
|
{award.award_name}
|
||||||
</Badge>
|
</Badge>
|
||||||
<h4 className="font-semibold text-lg pr-8">
|
<h4 className="font-semibold text-lg pr-8 min-h-[2.5rem] line-clamp-2">
|
||||||
{award.team_name || award.app_name || "作品"}
|
{(() => {
|
||||||
|
// 團體賽優先顯示團隊名稱
|
||||||
|
if (award.competition_type === "team") {
|
||||||
|
const teamName = award.team_name_from_teams || award.team_name;
|
||||||
|
return teamName || "團隊名稱";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提案賽顯示提案標題
|
||||||
|
if (award.competition_type === "proposal") {
|
||||||
|
return award.proposal_title || "提案標題";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 個人賽顯示應用名稱
|
||||||
|
return award.app_name || "應用名稱";
|
||||||
|
})()}
|
||||||
</h4>
|
</h4>
|
||||||
<p className="text-sm text-gray-600">by {award.creator}</p>
|
<p className="text-sm text-gray-600">by {award.creator}</p>
|
||||||
|
|
||||||
@@ -8811,7 +8825,21 @@ export function CompetitionManagement() {
|
|||||||
<div>
|
<div>
|
||||||
<h3 className="text-xl font-bold text-gray-900">{selectedAward.awardName}</h3>
|
<h3 className="text-xl font-bold text-gray-900">{selectedAward.awardName}</h3>
|
||||||
<p className="text-gray-600 mt-1">
|
<p className="text-gray-600 mt-1">
|
||||||
{(selectedAward as any).app_name || (selectedAward as any).team_name || "團隊作品"} • by {selectedAward.creator}
|
{(() => {
|
||||||
|
// 團體賽優先顯示團隊名稱
|
||||||
|
if (selectedAward.competitionType === "team") {
|
||||||
|
const teamName = (selectedAward as any).team_name_from_teams || (selectedAward as any).team_name;
|
||||||
|
return teamName || "團隊名稱";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提案賽顯示提案標題
|
||||||
|
if (selectedAward.competitionType === "proposal") {
|
||||||
|
return (selectedAward as any).proposal_title || "提案標題";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 個人賽顯示應用名稱
|
||||||
|
return (selectedAward as any).app_name || "應用名稱";
|
||||||
|
})()} • by {selectedAward.creator}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center space-x-3">
|
<div className="flex items-center space-x-3">
|
||||||
|
@@ -4597,7 +4597,11 @@ export class AwardService extends DatabaseServiceBase {
|
|||||||
id: result[0].id,
|
id: result[0].id,
|
||||||
competition_name: (result[0] as any).competition_name,
|
competition_name: (result[0] as any).competition_name,
|
||||||
competition_type: (result[0] as any).competition_type,
|
competition_type: (result[0] as any).competition_type,
|
||||||
competition_id: result[0].competition_id
|
competition_id: result[0].competition_id,
|
||||||
|
team_name_from_teams: (result[0] as any).team_name_from_teams,
|
||||||
|
team_name: (result[0] as any).team_name,
|
||||||
|
app_name: (result[0] as any).app_name,
|
||||||
|
team_id: (result[0] as any).team_id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4698,7 +4702,21 @@ export class AwardService extends DatabaseServiceBase {
|
|||||||
|
|
||||||
// 根據年份獲取獎項
|
// 根據年份獲取獎項
|
||||||
static async getAwardsByYear(year: number): Promise<Award[]> {
|
static async getAwardsByYear(year: number): Promise<Award[]> {
|
||||||
const sql = 'SELECT * FROM awards WHERE year = ? ORDER BY month DESC, rank ASC';
|
const sql = `
|
||||||
|
SELECT
|
||||||
|
a.*,
|
||||||
|
c.name as competition_name,
|
||||||
|
c.type as competition_type,
|
||||||
|
c.description as competition_description,
|
||||||
|
c.start_date as competition_start_date,
|
||||||
|
c.end_date as competition_end_date,
|
||||||
|
t.name as team_name_from_teams
|
||||||
|
FROM awards a
|
||||||
|
LEFT JOIN competitions c ON a.competition_id = c.id
|
||||||
|
LEFT JOIN teams t ON a.team_id = t.id
|
||||||
|
WHERE a.year = ?
|
||||||
|
ORDER BY a.month DESC, a.rank ASC
|
||||||
|
`;
|
||||||
return await db.query<Award>(sql, [year]);
|
return await db.query<Award>(sql, [year]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user