/** * AnalysisCard — 워크스페이스 단일 분석 아이템 카드. * * 한 카드에 리포트 + 플랜이 같이 묶입니다. * - 카드 본문 클릭 → 리포트 보기 (기본 동작) * - [리포트 보기] / [플랜 보기 | + 플랜 만들기] 명시적 버튼 * - 분석 대상 플랫폼 칩(URL/핸들) 표시 */ import { Link, useNavigate } from 'react-router'; import { Calendar, ArrowUpRight, FileText, Sparkles } from 'lucide-react'; import { PlatformChips } from '../PlatformChips'; import type { WorkspacePlan, WorkspaceRun } from '../../types/workspace'; function statusBadge(status: WorkspaceRun['status']) { const map = { completed: { label: '완료', cls: 'bg-status-good-bg text-status-good-text border-status-good-border' }, running: { label: '진행 중', cls: 'bg-status-info-bg text-status-info-text border-status-info-border' }, queued: { label: '대기', cls: 'bg-slate-50 text-slate-500 border-slate-200' }, failed: { label: '실패', cls: 'bg-status-critical-bg text-status-critical-text border-status-critical-border' }, } as const; return map[status]; } function formatScore(score: number | null) { return score == null ? '—' : String(Math.round(score)); } function formatDate(iso: string) { const d = new Date(iso); return `${d.getFullYear()}.${String(d.getMonth() + 1).padStart(2, '0')}.${String(d.getDate()).padStart(2, '0')}`; } interface AnalysisCardProps { clinicId: string; run: WorkspaceRun; /** 모든 run 은 1:1 로 연결된 plan 을 가짐 */ plan: WorkspacePlan; /** 최신 row 강조 */ highlighted?: boolean; } export function AnalysisCard({ clinicId, run, plan, highlighted = false }: AnalysisCardProps) { const navigate = useNavigate(); const status = statusBadge(run.status); // 가라데이터 데모 — 실제 리포트/플랜 ID 대신 view-clinic 데모 데이터로 진입. // 실 데이터 연동 시 `/clinics/${clinicId}/report/${run.runId}` 등으로 복원. void clinicId; void run.runId; void plan.planId; const reportHref = '/report/view-clinic'; const planHref = '/plan/view-clinic'; const goToReport = () => navigate(reportHref); const stop = (e: React.MouseEvent) => e.stopPropagation(); return (
{ if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); goToReport(); } }} role="button" tabIndex={0} className="group cursor-pointer rounded-2xl border border-slate-100 bg-white transition-all hover:border-[#D5CDF5] hover:shadow-[3px_4px_18px_rgba(79,29,161,0.08)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-purple/30" >
{/* Score block */}
{formatScore(run.overallScore)} /100
{/* Center: meta + targets */}
{status.label} {formatDate(run.startedAt)} {highlighted && ( 최신 )}
{/* Right: actions */}
리포트 보기 기획 보기
); }