feat(profile): 프로필에 '한줄 소개' 추가 — 본인만 인라인 편집
- users.bio 컬럼(멱등) + db.setBio / getUserProfile 조회 포함 - POST /profile/bio (본인만, fetch JSON / 폼 POST 폴백) - 프로필 히어로: 이름·사번 한 줄로 합치고 한줄 소개를 3줄째로 배치 - 본인은 연필 버튼으로 인라인 편집(저장/취소·Esc), 최대 80자 - word-break: keep-all 로 한글 단어 중간 잘림 방지 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,53 @@ import { $, toast } from "./util.js";
|
||||
|
||||
const OUT = 256; // 저장 이미지 한 변(px)
|
||||
|
||||
// 한줄 소개 편집 — 텍스트/편집버튼을 폼으로 토글, 저장은 fetch 로 즉시 반영.
|
||||
function initBio() {
|
||||
const row = $("#bioRow");
|
||||
const form = $("#bioForm");
|
||||
const text = $("#bioText");
|
||||
const editBtn = $("#bioEditBtn");
|
||||
const input = $("#bioInput");
|
||||
const cancel = $("#bioCancel");
|
||||
if (!row || !form || !text || !editBtn || !input) return; // 본인 프로필에서만 동작
|
||||
|
||||
function show(editing) {
|
||||
row.hidden = editing;
|
||||
form.hidden = !editing;
|
||||
if (editing) { input.focus(); input.select(); }
|
||||
}
|
||||
|
||||
editBtn.addEventListener("click", () => show(true));
|
||||
if (cancel) cancel.addEventListener("click", () => { input.value = text.classList.contains("is-empty") ? "" : text.textContent; show(false); });
|
||||
input.addEventListener("keydown", (e) => { if (e.key === "Escape") { e.preventDefault(); cancel.click(); } });
|
||||
|
||||
form.addEventListener("submit", async (e) => {
|
||||
e.preventDefault();
|
||||
const bio = input.value.trim().slice(0, 80);
|
||||
const saveBtn = $("#bioSave");
|
||||
if (saveBtn) { saveBtn.disabled = true; saveBtn.textContent = "저장 중…"; }
|
||||
try {
|
||||
const res = await fetch("/profile/bio", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "X-Requested-With": "fetch" },
|
||||
body: JSON.stringify({ bio }),
|
||||
});
|
||||
if (!res.ok) throw new Error("save failed");
|
||||
text.textContent = bio || "한줄 소개를 남겨보세요";
|
||||
text.classList.toggle("is-empty", !bio);
|
||||
show(false);
|
||||
toast("한줄 소개가 저장됐어요");
|
||||
} catch (err) {
|
||||
toast("저장에 실패했어요");
|
||||
} finally {
|
||||
if (saveBtn) { saveBtn.disabled = false; saveBtn.textContent = "저장"; }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function initProfile() {
|
||||
initBio();
|
||||
|
||||
const editBtn = $("#avatarEditBtn");
|
||||
const modal = $("#cropModal");
|
||||
if (!editBtn || !modal) return; // 본인 프로필이 아니면 크롭 UI 없음
|
||||
|
||||
Reference in New Issue
Block a user