## 슈퍼관리자 삭제 게시물 관리
- 삭제된 게시물 목록에 표시 (빨간색 배경, 취소선)
- 게시물 복원 기능 추가 (POST /{post}/restore)
- 게시물 영구삭제 기능 추가 (DELETE /{post}/force)
- 통계 카드에 삭제됨 카운트 추가
## 페이지 타이틀 회사명 표시
- /boards: "회사명 게시판 관리" 형식으로 표시
- /boards/{code}/posts: "회사명 게시판명" 형식으로 표시
- 회사명 파란색으로 구분 표시
## 버그 수정
- 통계 카드 CSS: Tailwind 동적 클래스 문제 해결
(grid-cols-{{ }} → 정적 클래스로 변경)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
163 lines
5.6 KiB
PHP
163 lines
5.6 KiB
PHP
@extends('layouts.app')
|
|
|
|
@section('title', ($currentTenant?->company_name ?? '') . ' 게시판 관리')
|
|
|
|
@section('content')
|
|
<!-- 페이지 헤더 -->
|
|
<div class="flex flex-col sm:flex-row sm:justify-between sm:items-center gap-4 mb-6">
|
|
<h1 class="text-2xl font-bold text-gray-800">
|
|
@if($currentTenant?->company_name)
|
|
<span class="text-blue-600">{{ $currentTenant->company_name }}</span>
|
|
@endif
|
|
게시판 관리
|
|
</h1>
|
|
<a href="{{ route('boards.create') }}" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition text-center w-full sm:w-auto">
|
|
+ 새 게시판
|
|
</a>
|
|
</div>
|
|
|
|
<!-- 필터 영역 -->
|
|
<x-filter-collapsible id="boardFilter">
|
|
<form id="filterForm" class="flex flex-wrap gap-2 sm:gap-4">
|
|
<!-- 검색 -->
|
|
<div class="flex-1 min-w-0 w-full sm:w-auto">
|
|
<input type="text"
|
|
name="search"
|
|
placeholder="게시판명, 코드로 검색..."
|
|
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
</div>
|
|
|
|
<!-- 게시판 유형 필터 -->
|
|
<div class="w-full sm:w-40">
|
|
<select name="board_type" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
<option value="">전체 유형</option>
|
|
<option value="notice">공지사항</option>
|
|
<option value="qna">1:1 문의</option>
|
|
<option value="faq">FAQ</option>
|
|
<option value="free">자유게시판</option>
|
|
@foreach($boardTypes as $type)
|
|
@if(!in_array($type, ['notice', 'qna', 'faq', 'free']))
|
|
<option value="{{ $type }}">{{ $type }}</option>
|
|
@endif
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
|
|
<!-- 활성 상태 필터 -->
|
|
<div class="w-full sm:w-32">
|
|
<select name="is_active" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
<option value="">전체</option>
|
|
<option value="1">활성</option>
|
|
<option value="0">비활성</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- 삭제된 항목 포함 -->
|
|
<div class="w-full sm:w-36">
|
|
<select name="trashed" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
<option value="">활성만</option>
|
|
<option value="with">삭제 포함</option>
|
|
<option value="only">삭제만</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- 검색 버튼 -->
|
|
<button type="submit" class="bg-gray-600 hover:bg-gray-700 text-white px-6 py-2 rounded-lg transition w-full sm:w-auto">
|
|
검색
|
|
</button>
|
|
</form>
|
|
</x-filter-collapsible>
|
|
|
|
<!-- 테이블 영역 -->
|
|
<div id="board-table" class="bg-white rounded-lg shadow-sm overflow-hidden">
|
|
<!-- 로딩 스피너 -->
|
|
<div class="flex justify-center items-center p-12">
|
|
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 인라인 스크립트 (HTMX 스왑 후에도 실행됨) -->
|
|
<script>
|
|
(function() {
|
|
const csrfToken = '{{ csrf_token() }}';
|
|
const boardTable = document.getElementById('board-table');
|
|
const filterForm = document.getElementById('filterForm');
|
|
|
|
// 테이블 로드 함수
|
|
function loadTable() {
|
|
const formData = new FormData(filterForm);
|
|
const params = new URLSearchParams(formData).toString();
|
|
|
|
fetch(`/api/admin/boards?${params}`, {
|
|
headers: {
|
|
'X-CSRF-TOKEN': csrfToken,
|
|
'HX-Request': 'true'
|
|
}
|
|
})
|
|
.then(response => response.text())
|
|
.then(html => {
|
|
boardTable.innerHTML = html;
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
});
|
|
}
|
|
|
|
// 폼 제출 이벤트
|
|
filterForm.addEventListener('submit', function(e) {
|
|
e.preventDefault();
|
|
loadTable();
|
|
});
|
|
|
|
// 삭제 확인
|
|
window.confirmDelete = function(id, name) {
|
|
showDeleteConfirm(name, () => {
|
|
fetch(`/api/admin/boards/${id}`, {
|
|
method: 'DELETE',
|
|
headers: {
|
|
'X-CSRF-TOKEN': csrfToken
|
|
}
|
|
}).then(() => loadTable());
|
|
});
|
|
};
|
|
|
|
// 복원 확인
|
|
window.confirmRestore = function(id, name) {
|
|
showConfirm(`"${name}" 게시판을 복원하시겠습니까?`, () => {
|
|
fetch(`/api/admin/boards/${id}/restore`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'X-CSRF-TOKEN': csrfToken
|
|
}
|
|
}).then(() => loadTable());
|
|
}, { title: '복원 확인', icon: 'question' });
|
|
};
|
|
|
|
// 영구삭제 확인
|
|
window.confirmForceDelete = function(id, name) {
|
|
showPermanentDeleteConfirm(name, () => {
|
|
fetch(`/api/admin/boards/${id}/force`, {
|
|
method: 'DELETE',
|
|
headers: {
|
|
'X-CSRF-TOKEN': csrfToken
|
|
}
|
|
}).then(() => loadTable());
|
|
});
|
|
};
|
|
|
|
// 활성/비활성 토글
|
|
window.toggleActive = function(id) {
|
|
fetch(`/api/admin/boards/${id}/toggle-active`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'X-CSRF-TOKEN': csrfToken
|
|
}
|
|
}).then(() => loadTable());
|
|
};
|
|
|
|
// 즉시 테이블 로드
|
|
loadTable();
|
|
})();
|
|
</script>
|
|
@endsection
|