Files
sam-manage/resources/views/boards/create.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

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">
&larr; 목록으로
</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