(function () {
'use strict';
var YS = window.YS || {};
var csrfToken = YS.csrfToken || '';
// ── Helpers ──
function $(sel) { return document.querySelector(sel); }
function $$(sel) { return document.querySelectorAll(sel); }
function escapeHTML(s) {
var d = document.createElement('div');
d.textContent = s || '';
return d.innerHTML;
}
function escapeAttr(s) {
if (!s) return '';
return s.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(//g, '>');
}
async function fetchJSON(url) {
var r = await fetch(url);
var data = await r.json();
if (!data.success) throw new Error(data.error || '요청 실패');
return data;
}
async function postForm(url, params) {
params.csrf_token = csrfToken;
var body = new URLSearchParams(params);
var r = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: body,
});
var data = await r.json();
if (!data.success) throw new Error(data.error || '요청 실패');
return data;
}
function showToast(msg, type) {
var toast = document.querySelector('.community-toast');
if (!toast) {
toast = document.createElement('div');
toast.className = 'community-toast';
toast.style.cssText = 'position:fixed;bottom:24px;left:50%;transform:translateX(-50%);padding:10px 24px;border-radius:8px;color:#fff;font-size:14px;z-index:9999;transition:opacity 0.3s;pointer-events:none;';
document.body.appendChild(toast);
}
toast.textContent = msg;
toast.style.background = type === 'error' ? '#e74c3c' : '#00b894';
toast.style.opacity = '1';
clearTimeout(toast._timer);
toast._timer = setTimeout(function () { toast.style.opacity = '0'; }, 2500);
}
function renderLevelBadge(level, label, cls) {
if (!level) return '';
return 'Lv.' + level + ' ' + escapeHTML(label || '') + '';
}
function renderPagination(container, pg, onPageClick) {
if (!pg || pg.total_pages <= 1) { container.innerHTML = ''; return; }
var html = '';
var start = Math.max(1, pg.page - 2);
var end = Math.min(pg.total_pages, pg.page + 2);
if (pg.page > 1) {
html += '';
}
for (var i = start; i <= end; i++) {
html += '';
}
if (pg.page < pg.total_pages) {
html += '';
}
container.innerHTML = html;
container.onclick = function (e) {
var btn = e.target.closest('[data-page]');
if (btn) onPageClick(parseInt(btn.dataset.page));
};
}
// ── Page Router ──
var page = YS.communityPage || '';
if (page === 'board') initBoard();
if (page === 'post') initPostDetail();
if (page === 'write') initWriteForm();
// ================================================================
// Board Page
// ================================================================
function initBoard() {
var state = { page: 1, keyword: '', storeId: YS.filterStoreId || 0, regionId: 0, industryId: 0 };
var boardType = YS.boardType;
var boardId = YS.boardId;
var isReview = boardType === 'review';
var isAnonymous = boardType === 'anonymous';
// ── Review Board Filters ──
var _saveReviewFilterTimer = null;
if (isReview) {
initReviewFilters();
}
function initReviewFilters() {
var regions = YS.reviewRegions || [];
var industries = YS.reviewIndustries || [];
var regionSelect = document.getElementById('reviewFilterRegion');
var subRegionSelect = document.getElementById('reviewFilterSubRegion');
var industrySelect = document.getElementById('reviewFilterIndustry');
if (!regionSelect) return;
// Populate parent regions
regions.forEach(function (r) {
var opt = document.createElement('option');
opt.value = r.region_id;
opt.textContent = r.region_name;
regionSelect.appendChild(opt);
});
// Populate industries
industries.forEach(function (ind) {
var opt = document.createElement('option');
opt.value = ind.industry_id;
opt.textContent = ind.industry_name;
industrySelect.appendChild(opt);
});
// Restore saved filter
var initRegionId = YS.reviewInitRegionId || 0;
var initIndustryId = YS.reviewInitIndustryId || 0;
if (initRegionId > 0) {
restoreReviewRegion(initRegionId, regions, regionSelect, subRegionSelect);
}
if (initIndustryId > 0) {
industrySelect.value = initIndustryId;
state.industryId = initIndustryId;
}
// Region change
regionSelect.addEventListener('change', function () {
var parentId = parseInt(regionSelect.value, 10);
updateReviewSubRegion(parentId, regions, subRegionSelect);
state.regionId = parentId;
state.page = 1;
loadPosts();
saveReviewFilterToServer();
});
// Sub-region change
subRegionSelect.addEventListener('change', function () {
var subId = parseInt(subRegionSelect.value, 10);
if (subId > 0) {
state.regionId = subId;
} else {
state.regionId = parseInt(regionSelect.value, 10);
}
state.page = 1;
loadPosts();
saveReviewFilterToServer();
});
// Industry change
industrySelect.addEventListener('change', function () {
state.industryId = parseInt(industrySelect.value, 10);
state.page = 1;
loadPosts();
saveReviewFilterToServer();
});
}
function restoreReviewRegion(regionId, regions, regionSelect, subRegionSelect) {
// Check if it's a parent region
var parentRegion = regions.find(function (r) {
return parseInt(r.region_id, 10) === regionId;
});
if (parentRegion) {
regionSelect.value = regionId;
updateReviewSubRegion(regionId, regions, subRegionSelect);
state.regionId = regionId;
} else {
// It's a child region: find its parent
for (var i = 0; i < regions.length; i++) {
var p = regions[i];
if (p.children) {
var child = p.children.find(function (c) {
return parseInt(c.region_id, 10) === regionId;
});
if (child) {
var parentId = parseInt(p.region_id, 10);
regionSelect.value = parentId;
updateReviewSubRegion(parentId, regions, subRegionSelect);
subRegionSelect.value = regionId;
state.regionId = regionId;
break;
}
}
}
}
}
function updateReviewSubRegion(parentRegionId, regions, subRegionSelect) {
subRegionSelect.innerHTML = '';
if (parentRegionId === 0) {
subRegionSelect.disabled = true;
return;
}
var parent = regions.find(function (r) {
return parseInt(r.region_id, 10) === parentRegionId;
});
if (parent && parent.children && parent.children.length > 0) {
parent.children.forEach(function (child) {
var opt = document.createElement('option');
opt.value = child.region_id;
opt.textContent = child.region_name;
subRegionSelect.appendChild(opt);
});
subRegionSelect.disabled = false;
} else {
subRegionSelect.disabled = true;
}
}
function saveReviewFilterToServer() {
if (!YS.isLoggedIn) return;
clearTimeout(_saveReviewFilterTimer);
_saveReviewFilterTimer = setTimeout(function () {
var body = new URLSearchParams({
region_id: state.regionId,
industry_id: state.industryId,
csrf_token: csrfToken,
});
fetch('/api/save_review_filter.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: body,
}).catch(function () { /* silent */ });
}, 1000);
}
// Search UI
var searchInput = document.getElementById('boardSearchInput');
var searchBtn = document.getElementById('boardSearchBtn');
var clearBtn = document.getElementById('clearStoreFilter');
if (searchBtn) {
searchBtn.addEventListener('click', function () {
state.keyword = searchInput ? searchInput.value.trim() : '';
state.page = 1;
loadPosts();
});
}
if (searchInput) {
searchInput.addEventListener('keydown', function (e) {
if (e.key === 'Enter') {
state.keyword = searchInput.value.trim();
state.page = 1;
loadPosts();
}
});
}
if (clearBtn) {
clearBtn.addEventListener('click', function () {
state.storeId = 0;
var filterEl = document.getElementById('boardStoreFilter');
if (filterEl) filterEl.style.display = 'none';
state.page = 1;
loadPosts();
});
}
loadPosts();
// Row click → navigate to post (single listener, persists across re-renders)
$('#postList').addEventListener('click', function (e) {
var row = e.target.closest('tr[data-href]');
if (!row) return;
if (e.target.closest('a')) return;
location.href = row.dataset.href;
});
async function loadPosts() {
try {
var params = new URLSearchParams({ board_id: boardId, page: state.page });
if (isReview && state.storeId) params.set('store_id', state.storeId);
if (isReview && state.regionId) params.set('region_id', state.regionId);
if (isReview && state.industryId) params.set('industry_id', state.industryId);
if (state.keyword) params.set('keyword', state.keyword);
var data = await fetchJSON('/api/community/posts.php?' + params);
var posts = data.data.posts;
var pg = data.data.pagination;
$('#loading').style.display = 'none';
if (!posts.length && state.page === 1) {
var hasFilter = (state.keyword || (isReview && (state.storeId || state.regionId || state.industryId)));
var emptyEl = $('#emptyState');
var emptyMsg = emptyEl.querySelector('p');
var emptyBtn = emptyEl.querySelector('a');
if (hasFilter) {
emptyMsg.textContent = '검색 결과가 없습니다.';
if (emptyBtn) emptyBtn.style.display = 'none';
} else {
emptyMsg.textContent = '아직 게시글이 없습니다.';
if (emptyBtn) emptyBtn.style.display = '';
}
emptyEl.style.display = '';
$('#content').style.display = 'none';
return;
}
$('#emptyState').style.display = 'none';
$('#content').style.display = '';
if (boardType === 'photo') {
renderPhotoGrid(posts);
} else {
renderNormalList(posts, pg);
}
renderPagination($('#pagination'), pg, function (p) {
state.page = p;
loadPosts();
window.scrollTo({ top: 0, behavior: 'smooth' });
});
} catch (e) {
$('#loading').innerHTML = '
' + escapeHTML(e.message) + '
';
}
}
function renderNormalList(posts, pg) {
var startNum = pg.total - (pg.page - 1) * pg.per_page;
var html = '' +
'' +
'| 번호 | ' +
'제목 | ' +
'작성자 | ' +
'조회 | ' +
'좋아요 | ' +
'날짜 | ' +
'
';
posts.forEach(function (p, i) {
var num = startNum - i;
var postUrl = '/community/post.php?id=' + p.post_id;
var titleHtml = '';
// Review board: add [region-store] prefix and therapist name
if (isReview && p.store_name && !p.is_blinded) {
var prefix = '[' + escapeHTML(p.region_name || '') + '-' + escapeHTML(p.store_name) + '] ';
titleHtml += '' + prefix + '';
if (p.therapist_name) {
titleHtml += '' + escapeHTML(p.therapist_name) + ' ';
}
}
titleHtml += p.is_blinded
? '' + escapeHTML(p.title) + ''
: '' + escapeHTML(p.title) + '';
if (p.comment_count > 0) {
titleHtml += '';
}
var authorHtml = isAnonymous
? escapeHTML(p.author_name)
: renderLevelBadge(p.author_level, p.author_level_label, p.author_level_class) + ' ' + escapeHTML(p.author_name);
var rowAttr = p.is_blinded ? '' : ' data-href="' + postUrl + '"';
html += '' +
'| ' + num + ' | ' +
'' + titleHtml + ' | ' +
'' + authorHtml + ' | ' +
'' + p.view_count + ' | ' +
'' + p.like_count + ' | ' +
'' + escapeHTML((p.created_at || '').substring(5, 10)) + ' | ' +
'
';
});
html += '
';
$('#postList').innerHTML = html;
}
function renderPhotoGrid(posts) {
var html = '';
$('#postList').innerHTML = html;
}
}
// ================================================================
// Post Detail Page
// ================================================================
function initPostDetail() {
var postId = YS.postId;
var postData = null;
var boardData = null;
loadPost();
// Record view
fetch('/api/community/view.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'post_id=' + postId + '&csrf_token=' + encodeURIComponent(csrfToken),
}).catch(function () { });
async function loadPost() {
try {
var data = await fetchJSON('/api/community/post_detail.php?id=' + postId);
postData = data.data.post;
boardData = data.data.board;
$('#loading').style.display = 'none';
$('#content').style.display = '';
// Update mobile back link
var backLink = document.getElementById('mobileBackLink');
if (backLink && boardData) {
backLink.href = '/community/board.php?slug=' + encodeURIComponent(boardData.board_slug);
backLink.innerHTML = ' ' + escapeHTML(boardData.board_name);
}
renderPost(data.data);
renderActions(data.data);
renderNav(data.data);
loadComments();
// Update page title
document.title = escapeHTML(postData.title) + ' - 커뮤니티';
} catch (e) {
$('#loading').style.display = 'none';
$('#errorMsg').textContent = e.message;
$('#errorState').style.display = '';
}
}
function renderPost(d) {
var p = d.post;
var b = d.board;
var isAnonBoard = b.board_type === 'anonymous';
var authorHtml = isAnonBoard
? '' + escapeHTML(p.author_name) + ''
: renderLevelBadge(p.author_level, p.author_level_label, p.author_level_class) +
' ' + escapeHTML(p.author_name) + '';
if (!isAnonBoard && p.author_is_specialist) {
authorHtml += ' 인증';
}
// Store link for review board
var storeLinkHtml = '';
var storeBarHtml = '';
if (p.store_id && p.store_name) {
storeLinkHtml = '' +
'
[' +
escapeHTML(p.region_name || '') + '-' + escapeHTML(p.store_name) + ']';
if (p.therapist_name) {
storeLinkHtml += '
담당: ' + escapeHTML(p.therapist_name) + '';
}
storeLinkHtml += '
';
// Store action buttons (rendered inside content area top)
var storeActionsHtml = '';
// Attendance (always show if store_id exists)
storeActionsHtml += '' +
'📅' +
'출근부';
// Phone
if (p.phone_number) {
storeActionsHtml += '' +
'📞' +
'전화';
}
// Kakao
if (p.messenger_kakao) {
storeActionsHtml += '' +
'💬' +
'카카오';
}
// Telegram
if (p.messenger_telegram) {
storeActionsHtml += '' +
'✈' +
'텔레그램';
}
// WhatsApp
if (p.messenger_whatsapp) {
storeActionsHtml += '' +
'💬' +
'왓츠앱';
}
storeBarHtml = '' + storeActionsHtml + '
';
}
var html = '' +
'' + storeBarHtml + p.content + '
';
$('#postDetail').innerHTML = html;
}
function renderActions(d) {
var p = d.post;
var html = '';
if (boardData.allow_likes) {
html += '';
}
if (YS.isLoggedIn || YS.isOwner) {
html += '';
}
html += '';
if (p.is_mine) {
html += '✎ 수정';
html += '';
} else if (YS.isAdmin) {
html += '';
}
html += '📝 목록';
$('#postActions').innerHTML = html;
// Like toggle
var likeBtn = $('#likeBtn');
if (likeBtn) {
likeBtn.addEventListener('click', async function () {
if (!YS.isLoggedIn && !YS.isOwner) { showToast('로그인이 필요합니다.', 'error'); return; }
try {
var data = await postForm('/api/community/like.php', { target_type: 'post', target_id: postId });
var liked = data.data.liked;
likeBtn.className = 'post-actions__btn' + (liked ? ' post-actions__btn--liked' : '');
likeBtn.innerHTML = (liked ? '❤' : '♡') + ' ' + data.data.like_count + '';
} catch (e) { showToast(e.message, 'error'); }
});
}
// Report
var reportBtn = document.querySelector('.js-report-post');
if (reportBtn) {
reportBtn.addEventListener('click', function () { openReportModal('post', postId); });
}
// Delete
var deleteBtn = document.querySelector('.js-delete-post');
if (deleteBtn) {
deleteBtn.addEventListener('click', async function () {
if (!confirm('게시글을 삭제하시겠습니까?')) return;
try {
await postForm('/api/community/posts.php', { action: 'delete', post_id: postId });
showToast('삭제되었습니다.', 'success');
setTimeout(function () {
location.href = '/community/board.php?slug=' + boardData.board_slug;
}, 500);
} catch (e) { showToast(e.message, 'error'); }
});
}
}
function renderNav(d) {
var html = '';
if (d.prev_post) {
html += '' +
'« 이전글' +
escapeHTML(d.prev_post.title) + '';
} else {
html += '';
}
if (d.next_post) {
html += '' +
'다음글 »' +
escapeHTML(d.next_post.title) + '';
}
$('#postNav').innerHTML = html;
}
// ── Comments ──
async function loadComments() {
try {
var data = await fetchJSON('/api/community/comments.php?post_id=' + postId);
var comments = data.data.comments;
$('#commentCount').textContent = data.data.total;
renderCommentForm();
renderComments(comments);
} catch (e) { /* ignore */ }
}
function renderCommentForm() {
var formEl = $('#commentForm');
if (!YS.isLoggedIn && !YS.isOwner) {
formEl.innerHTML = '';
return;
}
formEl.innerHTML = '';
$('#commentSubmitBtn').addEventListener('click', async function () {
var content = $('#commentTextarea').value.trim();
if (!content) { showToast('댓글을 입력해주세요.', 'error'); return; }
this.disabled = true;
try {
await postForm('/api/community/comments.php', { post_id: postId, content: content });
$('#commentTextarea').value = '';
loadComments();
showToast('댓글이 작성되었습니다.', 'success');
} catch (e) { showToast(e.message, 'error'); }
this.disabled = false;
});
}
function renderComments(comments) {
// Build nested structure
var topLevel = [];
var replies = {};
comments.forEach(function (c) {
if (c.parent_comment_id) {
if (!replies[c.parent_comment_id]) replies[c.parent_comment_id] = [];
replies[c.parent_comment_id].push(c);
} else {
topLevel.push(c);
}
});
var html = '';
topLevel.forEach(function (c) {
html += renderCommentItem(c, false);
if (replies[c.comment_id]) {
replies[c.comment_id].forEach(function (r) {
html += renderCommentItem(r, true);
});
}
});
$('#commentList').innerHTML = html || '아직 댓글이 없습니다.
';
}
function renderCommentItem(c, isReply) {
var cls = 'comment-item' + (isReply ? ' comment-item--reply' : '') + (c.is_blinded ? ' comment-item--blinded' : '');
var isAnonBoard = boardData && boardData.board_type === 'anonymous';
var authorHtml = isAnonBoard
? ''
: renderLevelBadge(c.author_level, c.author_level_label, c.author_level_class) +
' ';
if (!isAnonBoard && c.author_is_specialist) authorHtml += ' 인증';
var actionsHtml = '';
if (!c.is_blinded) {
if (boardData && boardData.allow_likes) {
actionsHtml += '';
}
if (!isReply && (YS.isLoggedIn || YS.isOwner)) {
actionsHtml += '';
}
if (YS.isLoggedIn || YS.isOwner) {
actionsHtml += '';
}
if (c.is_mine || YS.isAdmin) {
actionsHtml += '';
}
}
return '' +
'' +
'' +
'' +
'' +
'
';
}
// Event delegation for comments
document.addEventListener('click', function (e) {
// Like comment
var likeBtn2 = e.target.closest('.js-like-comment');
if (likeBtn2) {
if (!YS.isLoggedIn && !YS.isOwner) { showToast('로그인이 필요합니다.', 'error'); return; }
var cid = likeBtn2.dataset.id;
postForm('/api/community/like.php', { target_type: 'comment', target_id: cid })
.then(function () { loadComments(); })
.catch(function (err) { showToast(err.message, 'error'); });
}
// Reply toggle
var replyBtn = e.target.closest('.js-reply-toggle');
if (replyBtn) {
var parentId = replyBtn.dataset.id;
var container = $('#replyForm_' + parentId);
if (container.innerHTML) { container.innerHTML = ''; return; }
container.innerHTML = '';
}
// Reply cancel
var cancelBtn = e.target.closest('.js-reply-cancel');
if (cancelBtn) {
var pid = cancelBtn.dataset.id;
$('#replyForm_' + pid).innerHTML = '';
}
// Reply submit
var submitBtn = e.target.closest('.js-reply-submit');
if (submitBtn) {
var pid2 = submitBtn.dataset.id;
var textarea = $('#replyForm_' + pid2 + ' textarea');
var content2 = textarea.value.trim();
if (!content2) { showToast('답글을 입력해주세요.', 'error'); return; }
submitBtn.disabled = true;
postForm('/api/community/comments.php', { post_id: postId, content: content2, parent_comment_id: pid2 })
.then(function () { loadComments(); showToast('답글이 작성되었습니다.', 'success'); })
.catch(function (err) { showToast(err.message, 'error'); submitBtn.disabled = false; });
}
// Delete comment
var delBtn = e.target.closest('.js-delete-comment');
if (delBtn) {
if (!confirm('댓글을 삭제하시겠습니까?')) return;
var dcid = delBtn.dataset.id;
postForm('/api/community/comments.php', { action: 'delete', comment_id: dcid })
.then(function () { loadComments(); showToast('삭제되었습니다.', 'success'); })
.catch(function (err) { showToast(err.message, 'error'); });
}
// Report comment
var reportComBtn = e.target.closest('.js-report-comment');
if (reportComBtn) {
openReportModal('comment', reportComBtn.dataset.id);
}
});
// ── Report Modal ──
function openReportModal(type, id) {
$('#reportTargetType').value = type;
$('#reportTargetId').value = id;
$('#reportDetail').value = '';
var radios = document.querySelectorAll('[name="reportReason"]');
radios.forEach(function (r) { r.checked = r.value === 'other'; });
$('#reportModal').classList.add('modal-overlay--active');
}
if ($('#reportClose')) {
$('#reportClose').addEventListener('click', function () { $('#reportModal').classList.remove('modal-overlay--active'); });
}
if ($('#reportCancel')) {
$('#reportCancel').addEventListener('click', function () { $('#reportModal').classList.remove('modal-overlay--active'); });
}
if ($('#reportModal')) {
$('#reportModal').addEventListener('click', function (e) {
if (e.target === this) this.classList.remove('modal-overlay--active');
});
}
if ($('#reportSubmit')) {
$('#reportSubmit').addEventListener('click', async function () {
var reason = document.querySelector('[name="reportReason"]:checked');
if (!reason) { showToast('신고 사유를 선택해주세요.', 'error'); return; }
this.disabled = true;
try {
await postForm('/api/community/report.php', {
target_type: $('#reportTargetType').value,
target_id: $('#reportTargetId').value,
reason: reason.value,
detail_text: $('#reportDetail').value,
});
showToast('신고가 접수되었습니다.', 'success');
$('#reportModal').classList.remove('modal-overlay--active');
} catch (e2) { showToast(e2.message, 'error'); }
this.disabled = false;
});
}
}
// ================================================================
// Write / Edit Form
// ================================================================
function initWriteForm() {
var boardId = YS.boardId;
var editMode = YS.editMode;
var postIdEdit = YS.postId;
var boardType = YS.boardType;
var boardSlug = YS.boardSlug;
// Init Summernote
if (typeof $ === 'function' && typeof jQuery !== 'undefined') {
jQuery('#postEditor').summernote({
height: 400,
lang: 'ko-KR',
placeholder: '내용을 입력하세요...',
toolbar: [
['style', ['style']],
['font', ['bold', 'italic', 'underline', 'strikethrough']],
['color', ['color']],
['para', ['ul', 'ol', 'paragraph']],
['table', ['table']],
['insert', ['link', 'picture']],
['view', ['fullscreen', 'codeview']],
],
callbacks: {
onImageUpload: function (files) {
uploadImage(files[0], function (url) {
jQuery('#postEditor').summernote('insertImage', url);
});
},
},
});
}
// Thumbnail upload (photo boards)
var thumbnailFileEl = document.getElementById('thumbnailFile');
if (thumbnailFileEl) {
thumbnailFileEl.addEventListener('change', function () {
if (this.files[0]) {
uploadImage(this.files[0], function (url) {
document.getElementById('thumbnailUrl').value = url;
document.getElementById('thumbnailPreview').innerHTML = '
';
}, 'thumbnail');
}
});
}
function uploadImage(file, callback, type) {
var fd = new FormData();
fd.append('file', file);
fd.append('csrf_token', csrfToken);
if (type) fd.append('type', type);
fetch('/api/community/upload_image.php', { method: 'POST', body: fd })
.then(function (r) { return r.json(); })
.then(function (data) {
if (data.success) callback(data.url);
else showToast(data.error || '업로드 실패', 'error');
})
.catch(function () { showToast('업로드 실패', 'error'); });
}
// Store selector (review board)
if (boardType === 'review') {
var storeSearchEl = document.getElementById('storeSearch');
var storeIdInput = document.getElementById('storeIdInput');
var storeSelectedEl = document.getElementById('storeSelected');
var storeResultsEl = document.getElementById('storeResults');
var searchTimer = null;
function selectStore(id, name, region) {
storeIdInput.value = id;
storeSearchEl.style.display = 'none';
storeResultsEl.style.display = 'none';
storeSelectedEl.innerHTML = '' + escapeHTML('[' + region + '-' + name + ']') + '' +
'';
storeSelectedEl.style.display = '';
storeSelectedEl.querySelector('.store-selector__clear').addEventListener('click', function () {
storeIdInput.value = '';
storeSelectedEl.style.display = 'none';
storeSearchEl.style.display = '';
storeSearchEl.value = '';
storeSearchEl.focus();
});
}
// Pre-fill store
if (YS.prefillStoreId) {
selectStore(YS.prefillStoreId, YS.prefillStoreName || '', YS.prefillStoreRegion || '');
}
// Auto-focus therapist name field if requested via URL param
if (YS.focusField === 'therapist') {
var therapistEl = document.getElementById('therapistName');
if (therapistEl) {
setTimeout(function () { therapistEl.focus(); }, 300);
}
}
if (storeSearchEl) {
storeSearchEl.addEventListener('input', function () {
clearTimeout(searchTimer);
var kw = this.value.trim();
if (kw.length < 1) { storeResultsEl.style.display = 'none'; return; }
searchTimer = setTimeout(function () {
fetch('/api/community/search_stores.php?keyword=' + encodeURIComponent(kw))
.then(function (r) { return r.json(); })
.then(function (data) {
if (!data.success || !data.data.stores.length) {
storeResultsEl.innerHTML = '검색 결과가 없습니다.
';
storeResultsEl.style.display = '';
return;
}
storeResultsEl.innerHTML = data.data.stores.map(function (s) {
return '' +
escapeHTML('[' + s.region_name + '] ' + s.store_name) + '
';
}).join('');
storeResultsEl.style.display = '';
})
.catch(function () { storeResultsEl.style.display = 'none'; });
}, 300);
});
storeResultsEl.addEventListener('click', function (e) {
var item = e.target.closest('.store-selector__item[data-id]');
if (!item) return;
selectStore(item.dataset.id, item.dataset.name, item.dataset.region);
});
// Hide results on outside click
document.addEventListener('click', function (e) {
if (!storeResultsEl.contains(e.target) && e.target !== storeSearchEl) {
storeResultsEl.style.display = 'none';
}
});
}
}
// Form submit
var form = document.getElementById('writeForm');
if (form) {
form.addEventListener('submit', async function (e) {
e.preventDefault();
var title = document.getElementById('postTitle').value.trim();
var content = jQuery ? jQuery('#postEditor').summernote('code') : '';
var thumbnailUrl = document.getElementById('thumbnailUrl') ? document.getElementById('thumbnailUrl').value : '';
if (!title) { showError('제목을 입력해주세요.'); return; }
if (!content || content === '
') { showError('내용을 입력해주세요.'); return; }
// Review board: store_id required, therapist_name optional
var storeIdVal = null;
var therapistNameVal = '';
if (boardType === 'review') {
var sid = document.getElementById('storeIdInput');
storeIdVal = sid ? sid.value : '';
if (!storeIdVal) { showError('매장을 선택해주세요.'); return; }
var tnEl = document.getElementById('therapistName');
therapistNameVal = tnEl ? tnEl.value.trim() : '';
}
var submitBtn = document.getElementById('submitBtn');
submitBtn.disabled = true;
submitBtn.textContent = '처리 중...';
try {
var params = { title: title, content: content };
if (thumbnailUrl) params.thumbnail_url = thumbnailUrl;
if (storeIdVal) params.store_id = storeIdVal;
if (boardType === 'review') params.therapist_name = therapistNameVal;
if (editMode) {
params.action = 'update';
params.post_id = postIdEdit;
await postForm('/api/community/posts.php', params);
showToast('수정되었습니다.', 'success');
setTimeout(function () { location.href = '/community/post.php?id=' + postIdEdit; }, 500);
} else {
params.board_id = boardId;
var data = await postForm('/api/community/posts.php', params);
showToast('작성되었습니다.', 'success');
setTimeout(function () { location.href = '/community/post.php?id=' + data.data.post_id; }, 500);
}
} catch (err) {
showError(err.message);
submitBtn.disabled = false;
submitBtn.textContent = editMode ? '수정' : '작성';
}
});
}
function showError(msg) {
var el = document.getElementById('writeError');
el.textContent = msg;
el.style.display = '';
setTimeout(function () { el.style.display = 'none'; }, 3000);
}
}
})();
댓글을 작성하려면 로그인하세요.