상세페이지 UI 수정
Deploy EG-BIM QA Gateway / deploy (push) Successful in 32s

This commit is contained in:
root
2026-09-22 15:23:00 +09:00
parent f196791191
commit c6b430a197
5 changed files with 141 additions and 15 deletions
+91 -1
View File
@@ -46,6 +46,19 @@
localStorage.setItem(STORAGE_KEY, JSON.stringify(posts));
}
function removeStoredPost(id) {
const posts = readJson(STORAGE_KEY, []).filter(function (post) { return post.id !== id; });
localStorage.setItem(STORAGE_KEY, JSON.stringify(posts));
}
function isPostOwner(post, user) {
if (!post || !user) return false;
const postIds = [post.requesterId, post.requesterUuid].filter(Boolean);
const userIds = [user.requesterId, user.ssoSubject, user.userUuid].filter(Boolean);
if (postIds.length && userIds.length) return postIds.some(function (id) { return userIds.indexOf(id) > -1; });
return Boolean(post.author && [user.name, user.loginId, user.email].filter(Boolean).indexOf(post.author) > -1);
}
function normalizeStatus(value) {
if (value && typeof value === 'object') value = value.code || value.key || value.value || value.name || '';
const raw = String(value || '').trim();
@@ -365,7 +378,7 @@
if (!qs('#category').value || !title || !content) { errorBox.textContent = '구분, 제목, 내용을 모두 입력해주세요.'; errorBox.style.display = 'block'; return; }
const feedbackId = makeUuid();
const createdAt = new Date().toISOString();
const post = { id: feedbackId, feedbackId: feedbackId, category: qs('#category').value, company: currentUser.familyCompany || currentUser.company || '외부 사용자', department: currentUser.department || '-', author: currentUser.name || currentUser.loginId, title: title, date: createdAt.slice(0, 10), createdAt: createdAt, status: '접수', secret: qs('#secret').checked, content: content };
const post = { id: feedbackId, feedbackId: feedbackId, requesterId: currentUser.requesterId, requesterTenantId: currentUser.requesterTenantId, category: qs('#category').value, company: currentUser.familyCompany || currentUser.company || '외부 사용자', department: currentUser.department || '-', author: currentUser.name || currentUser.loginId, title: title, date: createdAt.slice(0, 10), createdAt: createdAt, status: '접수', secret: qs('#secret').checked, content: content };
const submitButton = qs('#submitButton');
submitButton.disabled = true;
submitButton.textContent = '등록 중...';
@@ -413,6 +426,83 @@
if (attachmentBox) attachmentBox.innerHTML = attachments.length ? attachments.map(function (attachment) {
return '<div class="attachment-item">📎 ' + escapeHtml(attachment.originalFileName || '첨부파일') + '</div>';
}).join('') : '<span class="help-text">첨부된 파일이 없습니다.</span>';
const editButton = qs('#editButton');
const deleteButton = qs('#deleteButton');
const editForm = qs('#editForm');
const editError = qs('#editError');
const ownerActions = function () {
const owner = isPostOwner(post, getAuthUser());
if (editButton) editButton.hidden = !owner;
if (deleteButton) deleteButton.hidden = !owner;
};
ownerActions();
if (authReady) authReady.then(ownerActions);
if (editButton && editForm) editButton.addEventListener('click', function () {
qs('#editCategory').value = post.category || '일반문의';
qs('#editTitle').value = post.title || '';
qs('#editContent').value = post.content || '';
qs('#editSecret').checked = Boolean(post.secret);
editError.hidden = true;
editError.style.display = 'none';
editForm.hidden = false;
editForm.scrollIntoView({ behavior: 'smooth', block: 'start' });
});
const editCancel = qs('#editCancel');
if (editCancel && editForm) editCancel.addEventListener('click', function () { editForm.hidden = true; });
if (editForm) editForm.addEventListener('submit', async function (event) {
event.preventDefault();
editError.hidden = true;
editError.style.display = 'none';
const title = qs('#editTitle').value.trim();
const content = qs('#editContent').value.trim();
const category = qs('#editCategory').value;
if (!title || !content || !category) {
editError.textContent = '구분, 제목, 내용을 모두 입력해주세요.';
editError.hidden = false;
editError.style.display = 'block';
return;
}
const saveButton = qs('button[type="submit"]', editForm);
saveButton.disabled = true;
saveButton.textContent = '저장 중...';
try {
await requestJson('/api/feedbacks/' + encodeURIComponent(post.id), {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title: title, contents: content, Category: CATEGORY_CODES[category], is_secret: qs('#editSecret').checked ? 'true' : 'false' })
});
post.category = category;
post.title = title;
post.content = content;
post.secret = qs('#editSecret').checked;
updateStoredPost(post);
qs('[data-detail-category]').textContent = post.category;
qs('[data-detail-title]').textContent = post.title;
qs('[data-detail-content]').textContent = post.content;
qs('[data-detail-secret]').hidden = !post.secret;
editForm.hidden = true;
showToast('문의가 수정되었습니다.');
} catch (error) {
editError.textContent = error.message || '문의 수정에 실패했습니다.';
editError.hidden = false;
editError.style.display = 'block';
} finally {
saveButton.disabled = false;
saveButton.textContent = '수정 저장';
}
});
if (deleteButton) deleteButton.addEventListener('click', async function () {
if (!window.confirm('이 문의를 삭제하시겠습니까?')) return;
deleteButton.disabled = true;
try {
await requestJson('/api/feedbacks/' + encodeURIComponent(post.id), { method: 'DELETE' });
removeStoredPost(post.id);
window.location.href = 'index.html';
} catch (error) {
deleteButton.disabled = false;
showToast(error.message || '문의 삭제에 실패했습니다.');
}
});
function safeMediaUrl(value) {
value = String(value || '');
return /^(https?:\/\/|\/|blob:)/i.test(value) ? value : '';