feat: 문의사항 상세에서 글(본문) 수정 기능

- 의견 내용 패널에 '수정' 토글 → 본문 편집·저장(계정 스코프·2000자 제한)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
taekyoungc
2026-07-13 12:26:58 +09:00
parent 65582c3439
commit 9365848f9d
3 changed files with 60 additions and 2 deletions

View File

@@ -258,6 +258,7 @@ $routes->group('admin', ['filter' => 'adminAuth'], static function ($routes): vo
$routes->get('feedback/file/(:num)', 'Admin\Feedback::file/$1'); $routes->get('feedback/file/(:num)', 'Admin\Feedback::file/$1');
$routes->get('feedback/(:num)', 'Admin\Feedback::show/$1'); $routes->get('feedback/(:num)', 'Admin\Feedback::show/$1');
$routes->post('feedback/(:num)/status', 'Admin\Feedback::updateStatus/$1'); $routes->post('feedback/(:num)/status', 'Admin\Feedback::updateStatus/$1');
$routes->post('feedback/(:num)/content', 'Admin\Feedback::updateContent/$1');
$routes->get('/', 'Admin\Dashboard::index'); $routes->get('/', 'Admin\Dashboard::index');
$routes->get('users', 'Admin\User::index'); $routes->get('users', 'Admin\User::index');
$routes->get('users/create', 'Admin\User::create'); $routes->get('users/create', 'Admin\User::create');

View File

@@ -142,6 +142,30 @@ class Feedback extends BaseController
return redirect()->to(site_url('admin/feedback/' . $id))->with('success', '처리 상태를 저장했습니다.'); return redirect()->to(site_url('admin/feedback/' . $id))->with('success', '처리 상태를 저장했습니다.');
} }
/** 문의 글(본문) 수정 */
public function updateContent(int $id): ResponseInterface
{
$model = model(FeedbackModel::class);
$row = $model->find($id);
$scope = $this->scopeLgIdx();
if ($row === null || ($scope !== null && (int) $row->fb_lg_idx !== $scope)) {
return redirect()->to(site_url('admin/feedback'))->with('error', '의견을 찾을 수 없습니다.');
}
$content = trim((string) $this->request->getPost('fb_content'));
if ($content === '') {
return redirect()->to(site_url('admin/feedback/' . $id))->with('error', '내용을 입력해 주세요.');
}
$model->update($id, ['fb_content' => mb_substr($content, 0, 2000)]);
$returnTo = (string) $this->request->getPost('return_to');
if ($returnTo === 'all') {
return redirect()->to(site_url('admin/feedback/all') . '#fb-' . $id)->with('success', '문의 내용을 수정했습니다.');
}
return redirect()->to(site_url('admin/feedback/' . $id))->with('success', '문의 내용을 수정했습니다.');
}
/** 스크린샷 이미지 서빙 (관리자만, writable 보호 유지) */ /** 스크린샷 이미지 서빙 (관리자만, writable 보호 유지) */
public function image(int $id): ResponseInterface public function image(int $id): ResponseInterface
{ {

View File

@@ -20,9 +20,24 @@ use App\Models\FeedbackModel;
<div class="grid grid-cols-1 lg:grid-cols-2 gap-3 mt-2"> <div class="grid grid-cols-1 lg:grid-cols-2 gap-3 mt-2">
<section class="border border-gray-300 rounded-lg overflow-hidden"> <section class="border border-gray-300 rounded-lg overflow-hidden">
<div class="px-3 py-2 border-b bg-gray-50 text-sm font-semibold text-gray-700">의견 내용</div> <div class="px-3 py-2 border-b bg-gray-50 text-sm font-semibold text-gray-700 flex items-center justify-between">
<span>의견 내용</span>
<button type="button" id="fb-content-edit-btn" class="text-xs font-medium text-blue-600 hover:underline">수정</button>
</div>
<div class="p-3 space-y-2 text-sm"> <div class="p-3 space-y-2 text-sm">
<!-- 보기 모드 -->
<div id="fb-content-view">
<p class="whitespace-pre-wrap text-gray-800"><?= esc((string) $row->fb_content) ?></p> <p class="whitespace-pre-wrap text-gray-800"><?= esc((string) $row->fb_content) ?></p>
</div>
<!-- 수정 모드 -->
<form id="fb-content-edit" action="<?= site_url('admin/feedback/' . (int) $row->fb_idx . '/content') ?>" method="post" class="hidden">
<?= csrf_field() ?>
<textarea name="fb_content" rows="6" maxlength="2000" class="w-full border border-gray-300 rounded px-2 py-1.5 text-sm"><?= esc((string) $row->fb_content) ?></textarea>
<div class="flex gap-2 mt-2">
<button type="submit" class="bg-btn-search text-white px-4 py-1.5 rounded-sm text-sm">수정 저장</button>
<button type="button" id="fb-content-cancel" class="bg-gray-200 text-gray-700 px-4 py-1.5 rounded-sm text-sm hover:bg-gray-300">취소</button>
</div>
</form>
<hr class="my-2"/> <hr class="my-2"/>
<?php <?php
// 화면 URL — embed 파라미터를 떼고 전체 화면 절대 URL로 변환(클릭 시 해당 화면으로 바로 이동). // 화면 URL — embed 파라미터를 떼고 전체 화면 절대 URL로 변환(클릭 시 해당 화면으로 바로 이동).
@@ -91,3 +106,21 @@ use App\Models\FeedbackModel;
</section> </section>
<?php endif; ?> <?php endif; ?>
</div><!-- /.fb-selectable --> </div><!-- /.fb-selectable -->
<script>
(function () {
var btn = document.getElementById('fb-content-edit-btn');
var view = document.getElementById('fb-content-view');
var edit = document.getElementById('fb-content-edit');
var cancel = document.getElementById('fb-content-cancel');
if (!btn || !view || !edit) return;
var show = function (editing) {
view.classList.toggle('hidden', editing);
edit.classList.toggle('hidden', !editing);
btn.classList.toggle('hidden', editing);
if (editing) { var ta = edit.querySelector('textarea'); if (ta) ta.focus(); }
};
btn.addEventListener('click', function () { show(true); });
if (cancel) cancel.addEventListener('click', function () { show(false); });
})();
</script>