feat(projects): 상세 모달에서 공개/비공개 전환 + '비공개로' 버튼 스타일 개선

투명 텍스트라 버튼처럼 안 보이던 .toggle-share-btn 을 테두리·패딩 있는
버튼 모양으로 변경. 프로젝트 상세 모달(소유자)에 '비공개로 전환/공개로
전환' 버튼을 추가하고, 전환 라우트가 return_to 를 존중하도록 해 모달에서
전환하면 모달이 다시 열린 상태로 돌아온다.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-02 14:15:34 +09:00
parent 761b1a1936
commit 4a3e5636c8
3 changed files with 15 additions and 4 deletions

View File

@@ -71,8 +71,11 @@
} }
.vis-badge.public { color: var(--success-fg); background: var(--success-bg); border: 1px solid var(--success-bd); } .vis-badge.public { color: var(--success-fg); background: var(--success-bg); border: 1px solid var(--success-bd); }
.vis-badge.private { color: var(--fg2); background: var(--panel); border: 1px solid var(--border); } .vis-badge.private { color: var(--fg2); background: var(--panel); border: 1px solid var(--border); }
.toggle-share-btn { background: transparent; border: 0; padding: 0; cursor: pointer; font-family: inherit; font-size: 11.5px; font-weight: 600; color: var(--fg3); white-space: nowrap; } .toggle-share-btn {
.toggle-share-btn:hover { color: var(--fg); } display: inline-flex; align-items: center; gap: 5px; background: var(--btn-bg); border: 1px solid var(--btn-bd); border-radius: 7px; padding: 4px 10px;
cursor: pointer; font-family: inherit; font-size: 11.5px; font-weight: 600; color: var(--fg2); white-space: nowrap; transition: background .14s ease, color .14s ease, border-color .14s ease;
}
.toggle-share-btn:hover { background: var(--btn-hover); color: var(--fg); border-color: var(--border); }
.private-note { font-size: 11.5px; color: var(--fg3); } .private-note { font-size: 11.5px; color: var(--fg3); }
.share-mini-btn { .share-mini-btn {
display: inline-flex; align-items: center; gap: 5px; background: var(--success); display: inline-flex; align-items: center; gap: 5px; background: var(--success);

View File

@@ -155,7 +155,10 @@ app.post("/projects/:id/visibility", requireAuth, async (req, res) => {
const isPublic = req.body.is_public === "1"; const isPublic = req.body.is_public === "1";
await db.setVisibility({ id: req.params.id, sabun: req.session.user.sabun, isPublic }); await db.setVisibility({ id: req.params.id, sabun: req.session.user.sabun, isPublic });
const msg = isPublic ? "공개로 전환됐습니다 · 피드에 표시됩니다" : "비공개로 전환됐습니다"; const msg = isPublic ? "공개로 전환됐습니다 · 피드에 표시됩니다" : "비공개로 전환됐습니다";
res.redirect("/?toast=" + encodeURIComponent(msg)); // 모달에서 전환하면 return_to(=/?open=<id>) 로 돌아가 모달을 다시 연다. 카드에서는 "/".
const back = safeBack(req.body.return_to, "/");
const sep = back.includes("?") ? "&" : "?";
res.redirect(back + sep + "toast=" + encodeURIComponent(msg));
}); });
// --- 프로젝트 삭제 (본인) --- // --- 프로젝트 삭제 (본인) ---

View File

@@ -55,7 +55,12 @@
<a class="modal-action ghost" href="<%= p.repo_url %>" target="_blank" rel="noopener"><%- icon("code", { size: 14 }) %>저장소</a> <a class="modal-action ghost" href="<%= p.repo_url %>" target="_blank" rel="noopener"><%- icon("code", { size: 14 }) %>저장소</a>
<% } %> <% } %>
<% if (p.owner_sabun === me) { %> <% if (p.owner_sabun === me) { %>
<form method="post" action="/projects/<%= p.id %>/delete" style="margin-left:auto"> <form method="post" action="/projects/<%= p.id %>/visibility" style="margin-left:auto">
<input type="hidden" name="is_public" value="<%= p.is_public ? "0" : "1" %>" />
<input type="hidden" name="return_to" value="<%= returnTo %>" />
<button type="submit" class="modal-action"><%- icon(p.is_public ? "lock" : "globe", { size: 14 }) %><%= p.is_public ? "비공개로 전환" : "공개로 전환" %></button>
</form>
<form method="post" action="/projects/<%= p.id %>/delete">
<input type="hidden" name="return_to" value="/" /> <input type="hidden" name="return_to" value="/" />
<button type="submit" class="comment-link comment-del" data-confirm="이 프로젝트를 삭제할까요? 댓글·반응도 함께 삭제됩니다." style="font-size:12.5px"><%- icon("trash", { size: 13 }) %>프로젝트 삭제</button> <button type="submit" class="comment-link comment-del" data-confirm="이 프로젝트를 삭제할까요? 댓글·반응도 함께 삭제됩니다." style="font-size:12.5px"><%- icon("trash", { size: 13 }) %>프로젝트 삭제</button>
</form> </form>