feat(mng): 고객센터 게시판 목록 페이지 추가
- /customer-center 라우트 신규 생성 - 활성화된 시스템 게시판만 표시 - 테이블 컬럼: ID, 유형, 코드, 게시판명, 게시글 수, 생성일 - 관리 기능(구분, 필드, 상태, 액션) 제외한 읽기 전용 뷰 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
26
app/Http/Controllers/Api/Admin/CustomerCenterController.php
Normal file
26
app/Http/Controllers/Api/Admin/CustomerCenterController.php
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api\Admin;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Boards\Board;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\View\View;
|
||||||
|
|
||||||
|
class CustomerCenterController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 고객센터 게시판 목록 (활성화된 시스템 게시판만 + 게시글 수)
|
||||||
|
*/
|
||||||
|
public function index(Request $request): View
|
||||||
|
{
|
||||||
|
$boards = Board::query()
|
||||||
|
->whereNull('tenant_id') // 시스템 게시판만
|
||||||
|
->where('is_active', true) // 활성화된 것만
|
||||||
|
->withCount('posts') // 게시글 수
|
||||||
|
->orderBy('created_at', 'desc')
|
||||||
|
->paginate(15);
|
||||||
|
|
||||||
|
return view('customer-center.partials.table', compact('boards'));
|
||||||
|
}
|
||||||
|
}
|
||||||
21
app/Http/Controllers/CustomerCenterController.php
Normal file
21
app/Http/Controllers/CustomerCenterController.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Services\BoardService;
|
||||||
|
use Illuminate\View\View;
|
||||||
|
|
||||||
|
class CustomerCenterController extends Controller
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private readonly BoardService $boardService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 고객센터 게시판 목록 (활성화된 시스템 게시판만)
|
||||||
|
*/
|
||||||
|
public function index(): View
|
||||||
|
{
|
||||||
|
return view('customer-center.index');
|
||||||
|
}
|
||||||
|
}
|
||||||
44
resources/views/customer-center/index.blade.php
Normal file
44
resources/views/customer-center/index.blade.php
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('title', '고객센터')
|
||||||
|
|
||||||
|
@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">고객센터</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 테이블 영역 -->
|
||||||
|
<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>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script>
|
||||||
|
// 테이블 로드 함수
|
||||||
|
function loadTable() {
|
||||||
|
fetch('/api/admin/customer-center', {
|
||||||
|
headers: {
|
||||||
|
'X-CSRF-TOKEN': '{{ csrf_token() }}',
|
||||||
|
'HX-Request': 'true'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => response.text())
|
||||||
|
.then(html => {
|
||||||
|
document.getElementById('board-table').innerHTML = html;
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 초기 로드
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
loadTable();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
71
resources/views/customer-center/partials/table.blade.php
Normal file
71
resources/views/customer-center/partials/table.blade.php
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<!-- 고객센터 게시판 테이블 -->
|
||||||
|
<div class="bg-white rounded-lg shadow-sm overflow-hidden">
|
||||||
|
<x-table-swipe>
|
||||||
|
<table class="min-w-full divide-y divide-gray-200">
|
||||||
|
<thead class="bg-gray-50">
|
||||||
|
<tr>
|
||||||
|
<th class="px-3 py-2 text-center text-sm font-semibold text-gray-700 uppercase tracking-wider whitespace-nowrap">ID</th>
|
||||||
|
<th class="px-3 py-2 text-center text-sm font-semibold text-gray-700 uppercase tracking-wider whitespace-nowrap">유형</th>
|
||||||
|
<th class="px-3 py-2 text-center text-sm font-semibold text-gray-700 uppercase tracking-wider whitespace-nowrap">코드</th>
|
||||||
|
<th class="px-3 py-2 text-center text-sm font-semibold text-gray-700 uppercase tracking-wider whitespace-nowrap">게시판명</th>
|
||||||
|
<th class="px-3 py-2 text-center text-sm font-semibold text-gray-700 uppercase tracking-wider whitespace-nowrap">게시글 수</th>
|
||||||
|
<th class="px-3 py-2 text-center text-sm font-semibold text-gray-700 uppercase tracking-wider whitespace-nowrap">생성일</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="bg-white divide-y divide-gray-200">
|
||||||
|
@forelse($boards as $board)
|
||||||
|
<tr class="hover:bg-gray-50 cursor-pointer" onclick="window.location='{{ route('boards.posts.index', $board->id) }}'">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
|
||||||
|
{{ $board->id }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
@if($board->board_type)
|
||||||
|
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full
|
||||||
|
@switch($board->board_type)
|
||||||
|
@case('notice') bg-purple-100 text-purple-800 @break
|
||||||
|
@case('qna') bg-blue-100 text-blue-800 @break
|
||||||
|
@case('faq') bg-green-100 text-green-800 @break
|
||||||
|
@case('free') bg-gray-100 text-gray-800 @break
|
||||||
|
@default bg-yellow-100 text-yellow-800
|
||||||
|
@endswitch
|
||||||
|
">
|
||||||
|
{{ $board->board_type }}
|
||||||
|
</span>
|
||||||
|
@else
|
||||||
|
<span class="text-gray-400">-</span>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm">
|
||||||
|
<span class="font-mono text-blue-600">{{ $board->board_code }}</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="text-sm font-medium text-gray-900">{{ $board->name }}</div>
|
||||||
|
@if($board->description)
|
||||||
|
<div class="text-sm text-gray-500 truncate max-w-xs">{{ $board->description }}</div>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 text-center">
|
||||||
|
<span class="px-2 py-1 bg-blue-50 text-blue-700 rounded-full">{{ $board->posts_count }}건</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||||
|
{{ $board->created_at->format('Y-m-d') }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@empty
|
||||||
|
<tr>
|
||||||
|
<td colspan="6" class="px-6 py-12 text-center text-gray-500">
|
||||||
|
등록된 게시판이 없습니다.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforelse
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</x-table-swipe>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 페이지네이션 -->
|
||||||
|
@if($boards->hasPages())
|
||||||
|
<div class="px-6 py-4 border-t border-gray-200">
|
||||||
|
{{ $boards->withQueryString()->links() }}
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Http\Controllers\Api\Admin\BoardController;
|
use App\Http\Controllers\Api\Admin\BoardController;
|
||||||
|
use App\Http\Controllers\Api\Admin\CustomerCenterController;
|
||||||
use App\Http\Controllers\Api\Admin\DailyLogController;
|
use App\Http\Controllers\Api\Admin\DailyLogController;
|
||||||
use App\Http\Controllers\Api\Admin\DepartmentController;
|
use App\Http\Controllers\Api\Admin\DepartmentController;
|
||||||
use App\Http\Controllers\Api\Admin\GlobalMenuController;
|
use App\Http\Controllers\Api\Admin\GlobalMenuController;
|
||||||
@@ -182,6 +183,9 @@
|
|||||||
Route::delete('/{id}', [PermissionController::class, 'destroy'])->name('destroy');
|
Route::delete('/{id}', [PermissionController::class, 'destroy'])->name('destroy');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 고객센터 API (활성화된 시스템 게시판 목록)
|
||||||
|
Route::get('/customer-center', [CustomerCenterController::class, 'index'])->name('customer-center.index');
|
||||||
|
|
||||||
// 시스템 게시판 관리 API
|
// 시스템 게시판 관리 API
|
||||||
Route::prefix('boards')->name('boards.')->group(function () {
|
Route::prefix('boards')->name('boards.')->group(function () {
|
||||||
// 고정 경로는 먼저 정의
|
// 고정 경로는 먼저 정의
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
use App\Http\Controllers\ArchivedRecordController;
|
use App\Http\Controllers\ArchivedRecordController;
|
||||||
use App\Http\Controllers\Auth\LoginController;
|
use App\Http\Controllers\Auth\LoginController;
|
||||||
use App\Http\Controllers\BoardController;
|
use App\Http\Controllers\BoardController;
|
||||||
|
use App\Http\Controllers\CustomerCenterController;
|
||||||
use App\Http\Controllers\DailyLogController;
|
use App\Http\Controllers\DailyLogController;
|
||||||
use App\Http\Controllers\DepartmentController;
|
use App\Http\Controllers\DepartmentController;
|
||||||
use App\Http\Controllers\DevTools\ApiExplorerController;
|
use App\Http\Controllers\DevTools\ApiExplorerController;
|
||||||
@@ -104,6 +105,9 @@
|
|||||||
Route::get('/{id}/edit', [PermissionController::class, 'edit'])->name('edit');
|
Route::get('/{id}/edit', [PermissionController::class, 'edit'])->name('edit');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 고객센터 (활성화된 시스템 게시판 목록)
|
||||||
|
Route::get('/customer-center', [CustomerCenterController::class, 'index'])->name('customer-center.index');
|
||||||
|
|
||||||
// 시스템 게시판 관리 (Blade 화면만)
|
// 시스템 게시판 관리 (Blade 화면만)
|
||||||
Route::prefix('boards')->name('boards.')->group(function () {
|
Route::prefix('boards')->name('boards.')->group(function () {
|
||||||
Route::get('/', [BoardController::class, 'index'])->name('index');
|
Route::get('/', [BoardController::class, 'index'])->name('index');
|
||||||
|
|||||||
Reference in New Issue
Block a user