public/js/{util,ui,reactions,modals,comments,feed,main}.js 로 분리하고
dashboard/project 에서 <script type="module" src="/public/js/main.js"> 로 로드.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
64 lines
2.7 KiB
JavaScript
64 lines
2.7 KiB
JavaScript
// 피드 검색·정렬·즐겨찾기 필터 + 내 프로젝트 필터 (모두 클라이언트 처리).
|
|
import { $, $$ } from "./util.js";
|
|
|
|
function applyFeed() {
|
|
const grid = $("#feedGrid"); if (!grid) return;
|
|
const q = (($("#feedSearch") && $("#feedSearch").value) || "").trim().toLowerCase();
|
|
const starOnly = $("#feedStarFilter") && $("#feedStarFilter").classList.contains("on");
|
|
let visible = 0;
|
|
$$(".fcard", grid).forEach((c) => {
|
|
const hit = !q || (c.getAttribute("data-search") || "").indexOf(q) >= 0;
|
|
const st = !starOnly || c.getAttribute("data-starred") === "true";
|
|
const show = hit && st;
|
|
c.style.display = show ? "" : "none";
|
|
if (show) visible++;
|
|
});
|
|
const empty = $("#feedEmpty");
|
|
if (empty) {
|
|
empty.hidden = visible !== 0;
|
|
empty.textContent = starOnly && visible === 0
|
|
? "아직 즐겨찾기한 프로젝트가 없어요 · 카드의 ⭐ 버튼으로 추가하세요"
|
|
: "“" + (($("#feedSearch") && $("#feedSearch").value) || "") + "” 와 일치하는 프로젝트가 없습니다.";
|
|
}
|
|
}
|
|
|
|
function sortFeed(mode) {
|
|
const grid = $("#feedGrid"); if (!grid) return;
|
|
const cards = $$(".fcard", grid);
|
|
cards.sort((a, b) => {
|
|
if (mode === "popular") {
|
|
return (+b.getAttribute("data-pop") || 0) - (+a.getAttribute("data-pop") || 0)
|
|
|| (b.getAttribute("data-created") || "").localeCompare(a.getAttribute("data-created") || "");
|
|
}
|
|
return (b.getAttribute("data-created") || "").localeCompare(a.getAttribute("data-created") || "");
|
|
});
|
|
cards.forEach((c) => grid.appendChild(c));
|
|
}
|
|
|
|
export function initFeed() {
|
|
const search = $("#feedSearch");
|
|
if (search) search.addEventListener("input", applyFeed);
|
|
const sl = $("#sortLatest"), sp = $("#sortPopular");
|
|
if (sl) sl.addEventListener("click", () => { sl.classList.add("on"); if (sp) sp.classList.remove("on"); sortFeed("latest"); });
|
|
if (sp) sp.addEventListener("click", () => { sp.classList.add("on"); if (sl) sl.classList.remove("on"); sortFeed("popular"); });
|
|
const sf = $("#feedStarFilter");
|
|
if (sf) sf.addEventListener("click", () => { sf.classList.toggle("on"); applyFeed(); });
|
|
}
|
|
|
|
export function initMyFilter() {
|
|
const tabs = $$("[data-myfilter]");
|
|
if (!tabs.length) return;
|
|
tabs.forEach((tab) => {
|
|
tab.addEventListener("click", () => {
|
|
const f = tab.getAttribute("data-myfilter"); // all | public | private
|
|
tabs.forEach((t) => t.classList.toggle("on", t === tab));
|
|
$$("#myProjGrid .pcard").forEach((c) => {
|
|
const vis = c.getAttribute("data-vis");
|
|
c.style.display = (f === "all" || vis === f) ? "" : "none";
|
|
});
|
|
const add = $("#addCard");
|
|
if (add) add.style.display = f === "all" ? "" : "none";
|
|
});
|
|
});
|
|
}
|