diff --git a/src/pages/music/MusicStudio.css b/src/pages/music/MusicStudio.css index f799685..b709d2c 100644 --- a/src/pages/music/MusicStudio.css +++ b/src/pages/music/MusicStudio.css @@ -3279,3 +3279,41 @@ .ms-error { color: #f87171; } + +/* === PipelineTab === */ +.pipeline-container { padding:16px; } +.pipeline-toolbar { display:flex; gap:12px; margin-bottom:16px; align-items:center; } +.pipeline-toolbar select { padding:6px 10px; background:rgba(255,255,255,.04); + border:1px solid var(--ms-line, #2a2a3a); border-radius:8px; color:var(--ms-text, #f0f0f5); font-size:13px; } +.pipeline-grid { display:grid; grid-template-columns:repeat(auto-fill, minmax(320px, 1fr)); gap:16px; } +.pipeline-card { background:rgba(0,0,0,.3); border:1px solid var(--ms-line, #2a2a3a); + border-radius:14px; padding:16px; display:flex; flex-direction:column; gap:8px; } +.pipeline-card__head { display:flex; justify-content:space-between; align-items:center; } +.pipeline-card__head h4 { margin:0; font-size:14px; color:var(--ms-text, #f0f0f5); } +.pipeline-card__head button { padding:4px 10px; background:rgba(248,113,113,.15); color:#fca5a5; + border:1px solid rgba(248,113,113,.3); border-radius:6px; cursor:pointer; font-size:11px; } +.pipeline-progress { display:flex; gap:6px; margin:8px 0; } +.pipeline-dot { flex:1; text-align:center; padding:6px 0; border-radius:8px; + background:rgba(255,255,255,.05); font-size:11px; color:var(--ms-muted, #a0a0b0); } +.pipeline-dot.is-done { background:rgba(56,189,248,.2); color:#bae6fd; } +.pipeline-dot.is-current { box-shadow:0 0 8px rgba(56,189,248,.6); } +.pipeline-state { font-size:13px; color:var(--ms-text, #f0f0f5); } +.pipeline-review { font-size:12px; color:var(--ms-muted, #a0a0b0); } +.pipeline-review strong { color:#bae6fd; } +.pipeline-feedback { margin-top:8px; font-size:12px; color:var(--ms-muted, #a0a0b0); } +.pipeline-feedback summary { cursor:pointer; } +.pipeline-card a { color:#bae6fd; font-size:12px; } +.ms-empty { padding:32px; text-align:center; color:var(--ms-muted, #a0a0b0); grid-column:1/-1; } + +/* Modal — shared */ +.modal-overlay { position:fixed; inset:0; background:rgba(0,0,0,.6); + display:flex; align-items:center; justify-content:center; z-index:1000; } +.modal-body { background:#1a1a2e; padding:24px; border-radius:14px; min-width:320px; + border:1px solid var(--ms-line, #2a2a3a); } +.modal-body h3 { margin:0 0 12px; font-size:15px; color:var(--ms-text, #f0f0f5); } +.modal-body select { width:100%; padding:8px; background:rgba(255,255,255,.04); + border:1px solid var(--ms-line, #2a2a3a); border-radius:8px; color:var(--ms-text, #f0f0f5); font-size:13px; } +.modal-actions { display:flex; justify-content:flex-end; gap:8px; margin-top:16px; } +.modal-actions button { padding:6px 14px; background:rgba(255,255,255,.05); color:var(--ms-text, #f0f0f5); + border:1px solid var(--ms-line, #2a2a3a); border-radius:8px; cursor:pointer; font-size:13px; } +.modal-actions .button.primary { background:rgba(56,189,248,.2); color:#bae6fd; border-color:rgba(56,189,248,.4); } diff --git a/src/pages/music/components/PipelineCard.jsx b/src/pages/music/components/PipelineCard.jsx new file mode 100644 index 0000000..34461cb --- /dev/null +++ b/src/pages/music/components/PipelineCard.jsx @@ -0,0 +1,63 @@ +import { cancelPipeline, publishPipeline } from '../../../api'; + +const STEP_LABELS = ['커버','영상','썸네','메타','검토','발행']; + +function stepIndex(state) { + if (state.startsWith('cover')) return 0; + if (state.startsWith('video')) return 1; + if (state.startsWith('thumb')) return 2; + if (state.startsWith('meta')) return 3; + if (state.startsWith('ai_review') || state.startsWith('publish_pending')) return 4; + if (state.startsWith('publish')) return 5; + if (state === 'published') return 6; + return -1; +} + +export default function PipelineCard({ pipeline, onChanged }) { + const i = stepIndex(pipeline.state); + return ( +
진행 중인 파이프라인이 없습니다
} +