diff --git a/frontend/src/components/ScheduleBoard.tsx b/frontend/src/components/ScheduleBoard.tsx index 439784e..863875f 100644 --- a/frontend/src/components/ScheduleBoard.tsx +++ b/frontend/src/components/ScheduleBoard.tsx @@ -3,7 +3,7 @@ import { Link } from "react-router-dom"; import { timeOnly, dateKey } from "@/lib/format"; import { getLive, type LiveData } from "@/lib/api"; import { type Lang, dict, teamShort, roundLabel as tRound, dayName, monthEn } from "@/lib/i18n"; -import type { League, Match, MatchPhase } from "@/lib/types"; +import type { League, Match, MatchPhase, ModelName, Outcome } from "@/lib/types"; import TeamFlag from "./TeamFlag"; import StandingsTable from "./StandingsTable"; @@ -435,6 +435,29 @@ function RankBadge({ rank, lang = "ko" }: { rank?: number | null; lang?: Lang }) ); } +// AI 픽 아이콘 (일정 카드용 — Arena 와 동일 공식 로고) +const MODEL_ICON: Record = { + GPT: "/icons/gpt.png", + Claude: "/icons/claude.jpg", + Gemini: "/icons/gemini.jpeg", +}; + +function AiPickIcons({ models }: { models: ModelName[] }) { + return ( + <> + {models.map((m) => ( + {m} + ))} + + ); +} + function MatchCard({ match, lang, @@ -490,6 +513,15 @@ function MatchCard({ const rightSt = flip ? match.extras?.standings?.a : match.extras?.standings?.b; const flagCls = isClub ? "h-7 w-7 shrink-0" : "h-6 w-9 shrink-0"; + // AI 픽: 픽한 팀 아래에 모델 아이콘 배치 (무승부 픽은 가운데) + const picksFor = (o: Outcome) => + match.predictions.filter((p) => p.outcome === o).map((p) => p.model); + const leftPicks = picksFor(flip ? "TEAM_B_WIN" : "TEAM_A_WIN"); + const rightPicks = picksFor(flip ? "TEAM_A_WIN" : "TEAM_B_WIN"); + const drawPicks = picksFor("DRAW"); + const showAiRow = + match.votable && phase !== "cancelled" && match.predictions.length > 0; + // 비투표(타 조)는 클릭 비활성, 투표 가능 조(A)는 상세로 이동 const inner = ( <> @@ -558,6 +590,24 @@ function MatchCard({ + {/* AI 픽: 각 모델 아이콘을 픽한 팀 아래에 표시 (무승부 픽은 가운데) */} + {showAiRow && ( +
+
+ +
+
+ +
+
+ +
+
+ )} + {/* 야구: 선발 매치업 (프리뷰 캐시 있을 때만) */} {isBaseball && !match.result && (match.extras?.starterA || match.extras?.starterB) && (
@@ -578,13 +628,9 @@ function MatchCard({
)} - {/* 투표 가능 조만: AI 픽 갈림 + 참여수 + 이동 화살표 (취소 경기는 숨김) */} + {/* 투표 가능 조만: 참여수 + 이동 화살표 (AI 픽은 위의 아이콘 행이 담당, 취소 경기는 숨김) */} {match.votable && phase !== "cancelled" && ( -
- - {t.aiPicks}{" "} - {aiSplit(match, lang).join(" · ")} - +
{t.joined((match.crowd?.total ?? 0).toLocaleString())}