183 lines
7.9 KiB
PHP
183 lines
7.9 KiB
PHP
|
|
@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.index') }}" class="text-gray-600 hover:text-gray-900">
|
||
|
|
← 목록으로
|
||
|
|
</a>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 폼 영역 -->
|
||
|
|
<div class="bg-white rounded-lg shadow-sm p-6">
|
||
|
|
<form id="boardForm" class="space-y-6">
|
||
|
|
@csrf
|
||
|
|
|
||
|
|
<!-- 기본 정보 -->
|
||
|
|
<div class="border-b border-gray-200 pb-6">
|
||
|
|
<h2 class="text-lg font-medium text-gray-900 mb-4">기본 정보</h2>
|
||
|
|
|
||
|
|
<div class="grid grid-cols-2 gap-6">
|
||
|
|
<!-- 게시판 코드 -->
|
||
|
|
<div>
|
||
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">
|
||
|
|
게시판 코드 <span class="text-red-500">*</span>
|
||
|
|
</label>
|
||
|
|
<input type="text" name="board_code"
|
||
|
|
placeholder="영문 소문자, 숫자, 하이픈만 사용"
|
||
|
|
pattern="[a-z0-9-]+"
|
||
|
|
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||
|
|
required>
|
||
|
|
<p class="mt-1 text-sm text-gray-500">URL에 사용됩니다 (예: notice, qna, faq)</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 게시판명 -->
|
||
|
|
<div>
|
||
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">
|
||
|
|
게시판명 <span class="text-red-500">*</span>
|
||
|
|
</label>
|
||
|
|
<input type="text" name="name"
|
||
|
|
placeholder="공지사항"
|
||
|
|
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||
|
|
required>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 게시판 유형 -->
|
||
|
|
<div>
|
||
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">게시판 유형</label>
|
||
|
|
<input type="text" name="board_type"
|
||
|
|
placeholder="notice, qna, faq, free 등"
|
||
|
|
list="boardTypeList"
|
||
|
|
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||
|
|
<datalist id="boardTypeList">
|
||
|
|
<option value="notice">공지사항</option>
|
||
|
|
<option value="qna">1:1 문의</option>
|
||
|
|
<option value="faq">FAQ</option>
|
||
|
|
<option value="free">자유게시판</option>
|
||
|
|
<option value="gallery">갤러리</option>
|
||
|
|
<option value="download">자료실</option>
|
||
|
|
</datalist>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 에디터 타입 -->
|
||
|
|
<div>
|
||
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">에디터 타입</label>
|
||
|
|
<select name="editor_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="wysiwyg">WYSIWYG (위지윅)</option>
|
||
|
|
<option value="markdown">Markdown</option>
|
||
|
|
<option value="text">텍스트</option>
|
||
|
|
</select>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 설명 -->
|
||
|
|
<div class="col-span-2">
|
||
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">설명</label>
|
||
|
|
<textarea name="description" rows="3"
|
||
|
|
placeholder="게시판에 대한 간단한 설명"
|
||
|
|
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"></textarea>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 파일 설정 -->
|
||
|
|
<div class="border-b border-gray-200 pb-6">
|
||
|
|
<h2 class="text-lg font-medium text-gray-900 mb-4">파일 첨부 설정</h2>
|
||
|
|
|
||
|
|
<div class="grid grid-cols-3 gap-6">
|
||
|
|
<!-- 파일 첨부 허용 -->
|
||
|
|
<div>
|
||
|
|
<label class="flex items-center">
|
||
|
|
<input type="checkbox" name="allow_files" value="1" checked
|
||
|
|
class="rounded border-gray-300 text-blue-600 focus:ring-blue-500">
|
||
|
|
<span class="ml-2 text-sm text-gray-700">파일 첨부 허용</span>
|
||
|
|
</label>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 최대 파일 수 -->
|
||
|
|
<div>
|
||
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">최대 파일 수</label>
|
||
|
|
<input type="number" name="max_file_count" value="5" min="0" max="100"
|
||
|
|
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>
|
||
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">최대 파일 크기 (KB)</label>
|
||
|
|
<input type="number" name="max_file_size" value="20480" min="0"
|
||
|
|
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||
|
|
<p class="mt-1 text-sm text-gray-500">20480 = 20MB</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 활성 상태 -->
|
||
|
|
<div>
|
||
|
|
<label class="flex items-center">
|
||
|
|
<input type="checkbox" name="is_active" value="1" checked
|
||
|
|
class="rounded border-gray-300 text-blue-600 focus:ring-blue-500">
|
||
|
|
<span class="ml-2 text-sm text-gray-700">활성화</span>
|
||
|
|
</label>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 에러 메시지 -->
|
||
|
|
<div id="errorMessage" class="hidden bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-lg"></div>
|
||
|
|
|
||
|
|
<!-- 버튼 -->
|
||
|
|
<div class="flex justify-end space-x-4">
|
||
|
|
<a href="{{ route('boards.index') }}"
|
||
|
|
class="px-6 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 transition">
|
||
|
|
취소
|
||
|
|
</a>
|
||
|
|
<button type="submit"
|
||
|
|
class="px-6 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition">
|
||
|
|
생성
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
</form>
|
||
|
|
</div>
|
||
|
|
@endsection
|
||
|
|
|
||
|
|
@push('scripts')
|
||
|
|
<script>
|
||
|
|
document.getElementById('boardForm').addEventListener('submit', async function(e) {
|
||
|
|
e.preventDefault();
|
||
|
|
|
||
|
|
const form = e.target;
|
||
|
|
const formData = new FormData(form);
|
||
|
|
const errorDiv = document.getElementById('errorMessage');
|
||
|
|
|
||
|
|
// 체크박스 처리
|
||
|
|
formData.set('allow_files', form.allow_files.checked ? '1' : '0');
|
||
|
|
formData.set('is_active', form.is_active.checked ? '1' : '0');
|
||
|
|
|
||
|
|
try {
|
||
|
|
const response = await fetch('/api/admin/boards', {
|
||
|
|
method: 'POST',
|
||
|
|
headers: {
|
||
|
|
'Content-Type': 'application/json',
|
||
|
|
'X-CSRF-TOKEN': '{{ csrf_token() }}',
|
||
|
|
'Accept': 'application/json'
|
||
|
|
},
|
||
|
|
body: JSON.stringify(Object.fromEntries(formData))
|
||
|
|
});
|
||
|
|
|
||
|
|
const data = await response.json();
|
||
|
|
|
||
|
|
if (response.ok && data.success) {
|
||
|
|
window.location.href = '{{ route('boards.index') }}';
|
||
|
|
} else {
|
||
|
|
errorDiv.textContent = data.message || '게시판 생성에 실패했습니다.';
|
||
|
|
errorDiv.classList.remove('hidden');
|
||
|
|
}
|
||
|
|
} catch (error) {
|
||
|
|
errorDiv.textContent = '서버 오류가 발생했습니다.';
|
||
|
|
errorDiv.classList.remove('hidden');
|
||
|
|
}
|
||
|
|
});
|
||
|
|
</script>
|
||
|
|
@endpush
|