Files
sam-manage/resources/views/boards/index.blade.php
hskwon 58009e675d feat: [boards] MNG 게시판 관리 시스템 구현
- Models: Board, BoardSetting (커스텀 필드)
- Service: BoardService (CRUD, 필드 관리)
- Controllers: BoardController (Blade), Api/Admin/BoardController (API)
- Views: index, create, edit, table partial
- 커스텀 필드 다중 추가 모달 (한 줄 레이아웃, + 버튼 추가)
2025-11-28 08:50:47 +09:00

148 lines
5.4 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@extends('layouts.app')
@section('title', '시스템 게시판 관리')
@section('content')
<!-- 페이지 헤더 -->
<div class="flex justify-between items-center mb-6">
<h1 class="text-2xl font-bold text-gray-800">📋 시스템 게시판 관리</h1>
<a href="{{ route('boards.create') }}" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition">
+ 게시판
</a>
</div>
<!-- 필터 영역 -->
<div class="bg-white rounded-lg shadow-sm p-4 mb-6">
<form id="filterForm" class="flex gap-4 flex-wrap">
<!-- 검색 -->
<div class="flex-1 min-w-[200px]">
<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-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-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-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">
검색
</button>
</form>
</div>
<!-- 테이블 영역 (HTMX로 로드) -->
<div id="board-table"
hx-get="/api/admin/boards"
hx-trigger="load, filterSubmit from:body"
hx-include="#filterForm"
hx-headers='{"X-CSRF-TOKEN": "{{ csrf_token() }}"}'
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>
@endsection
@push('scripts')
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
<script>
// 폼 제출 시 HTMX 이벤트 트리거
document.getElementById('filterForm').addEventListener('submit', function(e) {
e.preventDefault();
htmx.trigger('#board-table', 'filterSubmit');
});
// 삭제 확인
window.confirmDelete = function(id, name) {
if (confirm(`"${name}" 게시판을 삭제하시겠습니까?`)) {
htmx.ajax('DELETE', `/api/admin/boards/${id}`, {
target: '#board-table',
swap: 'none',
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
}
}).then(() => {
htmx.trigger('#board-table', 'filterSubmit');
});
}
};
// 복원 확인
window.confirmRestore = function(id, name) {
if (confirm(`"${name}" 게시판을 복원하시겠습니까?`)) {
htmx.ajax('POST', `/api/admin/boards/${id}/restore`, {
target: '#board-table',
swap: 'none',
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
}
}).then(() => {
htmx.trigger('#board-table', 'filterSubmit');
});
}
};
// 영구삭제 확인
window.confirmForceDelete = function(id, name) {
if (confirm(`"${name}" 게시판을 영구 삭제하시겠습니까?\n\n⚠ 이 작업은 되돌릴 수 없습니다!`)) {
htmx.ajax('DELETE', `/api/admin/boards/${id}/force`, {
target: '#board-table',
swap: 'none',
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
}
}).then(() => {
htmx.trigger('#board-table', 'filterSubmit');
});
}
};
// 활성/비활성 토글
window.toggleActive = function(id) {
htmx.ajax('POST', `/api/admin/boards/${id}/toggle-active`, {
target: '#board-table',
swap: 'none',
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
}
}).then(() => {
htmx.trigger('#board-table', 'filterSubmit');
});
};
</script>
@endpush