Compare commits
2 Commits
f7641cd06b
...
e2caf9a0ba
| Author | SHA1 | Date | |
|---|---|---|---|
| e2caf9a0ba | |||
| e7418e7c3c |
@ -11,7 +11,7 @@
|
|||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<div>
|
<div>
|
||||||
<h1>칸반 보드</h1>
|
<h1>칸반 보드</h1>
|
||||||
<p class="sub">카드를 드래그해 단계를 옮기세요. 수집 → 검토 → 작업대상 → 완료.</p>
|
<p class="sub">카드를 드래그(모바일은 카드의 상태 드롭다운)해 단계를 옮기세요. 수집 → 검토 → 작업대상 → 완료.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button class="btn btn-secondary" onclick="openHelp()"><i data-lucide="help-circle" style="width:15px;"></i> 사용법</button>
|
<button class="btn btn-secondary" onclick="openHelp()"><i data-lucide="help-circle" style="width:15px;"></i> 사용법</button>
|
||||||
@ -65,6 +65,14 @@
|
|||||||
.kb-card:hover { border-color: var(--accent); }
|
.kb-card:hover { border-color: var(--accent); }
|
||||||
.kb-card.dragging { opacity:0.5; }
|
.kb-card.dragging { opacity:0.5; }
|
||||||
.kb-count { font-size:0.75rem; font-weight:600; background:var(--surface); border:1px solid var(--border); color:var(--text-2); padding:2px 9px; border-radius:999px; }
|
.kb-count { font-size:0.75rem; font-weight:600; background:var(--surface); border:1px solid var(--border); color:var(--text-2); padding:2px 9px; border-radius:999px; }
|
||||||
|
/* 모바일 터치용 상태 변경 드롭다운: 데스크톱에서는 숨기고 드래그 사용 */
|
||||||
|
.kb-status-sel { display:none; width:100%; margin-top:8px; padding:7px 8px; font-size:0.78rem; background:var(--surface-2); border:1px solid var(--border); border-radius:6px; color:var(--text); cursor:pointer; }
|
||||||
|
@media (hover: none), (max-width: 820px) {
|
||||||
|
.kb-status-sel { display:block; }
|
||||||
|
.kb-card { cursor:default; }
|
||||||
|
#board { grid-template-columns: repeat(5, minmax(260px, 80%)); -webkit-overflow-scrolling: touch; scroll-snap-type: x proximity; }
|
||||||
|
#board .kb-col { scroll-snap-align: start; }
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script th:inline="javascript">
|
<script th:inline="javascript">
|
||||||
@ -104,6 +112,8 @@
|
|||||||
v.viewsPerHour!=null ? '⚡ '+fmt(Math.round(v.viewsPerHour))+'/h' : '',
|
v.viewsPerHour!=null ? '⚡ '+fmt(Math.round(v.viewsPerHour))+'/h' : '',
|
||||||
db ? '⏱ '+db : ''
|
db ? '⏱ '+db : ''
|
||||||
].filter(Boolean).join(' · ');
|
].filter(Boolean).join(' · ');
|
||||||
|
const status = v.interestStatus || 'NEW';
|
||||||
|
const statusOpts = COLS.map(c => `<option value="${c.key}"${c.key===status?' selected':''}>${c.label}</option>`).join('');
|
||||||
return `<div class="kb-card" draggable="true" data-id="${v.id}">
|
return `<div class="kb-card" draggable="true" data-id="${v.id}">
|
||||||
<div style="display:flex; gap:8px;">
|
<div style="display:flex; gap:8px;">
|
||||||
<img src="${esc(v.thumbnailUrl)}" title="미리보기" data-vid="${v.videoId}" data-title="${esc(v.title)}"
|
<img src="${esc(v.thumbnailUrl)}" title="미리보기" data-vid="${v.videoId}" data-title="${esc(v.title)}"
|
||||||
@ -121,6 +131,10 @@
|
|||||||
<a href="/rework/${v.id}" title="재가공" class="text-muted hover:text-white"><i data-lucide="wand-2" style="width:14px;"></i></a>
|
<a href="/rework/${v.id}" title="재가공" class="text-muted hover:text-white"><i data-lucide="wand-2" style="width:14px;"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<select class="kb-status-sel" title="상태 변경(모바일)" onpointerdown="event.stopPropagation()"
|
||||||
|
onclick="event.stopPropagation()" onchange="changeStatus('${v.id}', this.value, this)">
|
||||||
|
${statusOpts}
|
||||||
|
</select>
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,6 +210,28 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 드롭다운(모바일 터치)으로 상태 변경 — 드래그와 동일한 API 호출
|
||||||
|
async function changeStatus(id, newStatus, selEl){
|
||||||
|
const card = document.querySelector('.kb-card[data-id="'+id+'"]');
|
||||||
|
const targetBody = document.querySelector('.kb-body[data-status="'+newStatus+'"]');
|
||||||
|
if(!card || !targetBody) return;
|
||||||
|
const fromBody = card.parentElement;
|
||||||
|
if(fromBody === targetBody) return;
|
||||||
|
targetBody.appendChild(card); // optimistic move
|
||||||
|
updateCounts();
|
||||||
|
try {
|
||||||
|
await api(API + '/' + id + '/status', {
|
||||||
|
method:'POST', headers:{'Content-Type':'application/json'},
|
||||||
|
body: JSON.stringify({ status: newStatus })
|
||||||
|
});
|
||||||
|
if(window.lucide) lucide.createIcons();
|
||||||
|
} catch(err){
|
||||||
|
alert('상태 변경 실패: ' + err.message);
|
||||||
|
if(fromBody){ fromBody.appendChild(card); if(selEl) selEl.value = fromBody.dataset.status; }
|
||||||
|
updateCounts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function openHelp(){ document.getElementById('helpModal').classList.add('open'); }
|
function openHelp(){ document.getElementById('helpModal').classList.add('open'); }
|
||||||
function closeHelp(){ document.getElementById('helpModal').classList.remove('open'); }
|
function closeHelp(){ document.getElementById('helpModal').classList.remove('open'); }
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user