Files
sam-manage/resources/views/documents/edit.blade.php
권혁성 7635373a45 feat:문서관리 Phase 1.3~2.1 구현 (시드데이터, 복제, 문서생성)
- Phase 1.3: EGI/SUS 수입검사 시드 데이터 생성 (IncomingInspectionTemplateSeeder)
- Phase 1.5: 양식 복제 기능 (duplicate API, 테이블 버튼, JS)
- Phase 2.1: 문서 생성 보완
  - 문서번호 카테고리별 prefix (IQC/PRD/SLS/PUR-YYMMDD-순번)
  - 결재라인 초기화 (template.approvalLines → document_approvals)
  - 기본필드 뷰 속성 수정 (field_type, Str::slug field_key)
  - store()에 DB 트랜잭션 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 04:32:35 +09:00

200 lines
8.8 KiB
PHP

@extends('layouts.app')
@section('title', $isCreate ? '새 문서 작성' : '문서 수정')
@section('content')
<div class="max-w-7xl mx-auto">
<!-- 헤더 -->
<div class="flex flex-col lg:flex-row lg:justify-between lg:items-center gap-4 mb-6">
<div>
<h1 class="text-2xl font-bold text-gray-800">{{ $isCreate ? '새 문서 작성' : '문서 수정' }}</h1>
<p class="text-sm text-gray-500 mt-1 hidden sm:block">
@if($document)
{{ $document->document_no }} - {{ $document->title }}
@else
템플릿을 선택하여 문서를 작성합니다.
@endif
</p>
</div>
<div class="flex items-center gap-2">
<a href="{{ route('documents.index') }}"
class="bg-gray-200 hover:bg-gray-300 text-gray-700 px-4 py-2 rounded-lg transition">
목록
</a>
</div>
</div>
{{-- 템플릿 선택 (생성 ) --}}
@if($isCreate && !$template)
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6 mb-6">
<h2 class="text-lg font-semibold text-gray-800 mb-4">템플릿 선택</h2>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
@forelse($templates as $tpl)
<a href="{{ route('documents.create', ['template_id' => $tpl->id]) }}"
class="block p-4 border border-gray-200 rounded-lg hover:border-blue-500 hover:bg-blue-50 transition-colors">
<h3 class="font-medium text-gray-900">{{ $tpl->name }}</h3>
<p class="text-sm text-gray-500 mt-1">{{ $tpl->category }}</p>
</a>
@empty
<p class="text-gray-500 col-span-3">사용 가능한 템플릿이 없습니다.</p>
@endforelse
</div>
</div>
@endif
{{-- 문서 --}}
@if($template)
<form id="documentForm" class="space-y-6">
@csrf
<input type="hidden" name="template_id" value="{{ $template->id }}">
{{-- 기본 정보 --}}
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
<h2 class="text-lg font-semibold text-gray-800 mb-4">기본 정보</h2>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">템플릿</label>
<input type="text" value="{{ $template->name }}" disabled
class="w-full rounded-lg border-gray-300 bg-gray-50 text-sm">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">
제목 <span class="text-red-500">*</span>
</label>
<input type="text" name="title" value="{{ $document->title ?? '' }}" required
class="w-full rounded-lg border-gray-300 text-sm focus:border-blue-500 focus:ring-blue-500"
placeholder="문서 제목을 입력하세요">
</div>
</div>
</div>
{{-- 기본 필드 --}}
@if($template->basicFields && $template->basicFields->count() > 0)
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
<h2 class="text-lg font-semibold text-gray-800 mb-4">{{ $template->title ?? '문서 정보' }}</h2>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
@foreach($template->basicFields as $field)
@php
$fieldKey = \Illuminate\Support\Str::slug($field->label, '_');
$savedValue = $document?->data->where('field_key', $fieldKey)->first()?->field_value ?? $field->default_value ?? '';
@endphp
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">
{{ $field->label }}
</label>
@if($field->field_type === 'textarea')
<textarea name="data[{{ $fieldKey }}]"
class="w-full rounded-lg border-gray-300 text-sm focus:border-blue-500 focus:ring-blue-500"
rows="3">{{ $savedValue }}</textarea>
@elseif($field->field_type === 'date')
<input type="date" name="data[{{ $fieldKey }}]"
value="{{ $savedValue }}"
class="w-full rounded-lg border-gray-300 text-sm focus:border-blue-500 focus:ring-blue-500">
@elseif($field->field_type === 'number')
<input type="number" name="data[{{ $fieldKey }}]"
value="{{ $savedValue }}"
class="w-full rounded-lg border-gray-300 text-sm focus:border-blue-500 focus:ring-blue-500">
@else
<input type="text" name="data[{{ $fieldKey }}]"
value="{{ $savedValue }}"
class="w-full rounded-lg border-gray-300 text-sm focus:border-blue-500 focus:ring-blue-500">
@endif
</div>
@endforeach
</div>
</div>
@endif
{{-- 섹션 (테이블 형태 - Phase 2.2에서 구현) --}}
@if($template->sections && $template->sections->count() > 0)
@foreach($template->sections as $section)
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
<h2 class="text-lg font-semibold text-gray-800 mb-4">{{ $section->title }}</h2>
@if($section->image_path)
<img src="{{ asset('storage/' . $section->image_path) }}" alt="{{ $section->title }}" class="max-w-full h-auto mb-4 rounded">
@endif
<p class="text-sm text-gray-400 italic">검사 데이터 테이블은 Phase 2.2에서 구현됩니다.</p>
</div>
@endforeach
@endif
{{-- 버튼 --}}
<div class="flex justify-end gap-3">
<a href="{{ route('documents.index') }}"
class="px-6 py-2 bg-gray-100 text-gray-700 text-sm font-medium rounded-lg hover:bg-gray-200 transition-colors">
취소
</a>
<button type="submit"
class="px-6 py-2 bg-blue-600 text-white text-sm font-medium rounded-lg hover:bg-blue-700 transition-colors">
{{ $isCreate ? '저장' : '수정' }}
</button>
</div>
</form>
@endif
</div>
@endsection
@push('scripts')
<script>
document.addEventListener('DOMContentLoaded', function() {
const form = document.getElementById('documentForm');
if (!form) return;
form.addEventListener('submit', function(e) {
e.preventDefault();
const formData = new FormData(form);
const data = {
template_id: formData.get('template_id'),
title: formData.get('title'),
data: []
};
// data 필드 수집
for (const [key, value] of formData.entries()) {
if (key.startsWith('data[') && key.endsWith(']')) {
const fieldKey = key.slice(5, -1);
data.data.push({
field_key: fieldKey,
field_value: value
});
}
}
const isCreate = {{ $isCreate ? 'true' : 'false' }};
const url = isCreate ? '/api/admin/documents' : '/api/admin/documents/{{ $document?->id }}';
const method = isCreate ? 'POST' : 'PATCH';
fetch(url, {
method: method,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(result => {
if (result.success) {
showToast(isCreate ? '문서가 저장되었습니다.' : '문서가 수정되었습니다.', 'success');
if (isCreate && result.data?.id) {
window.location.href = '/documents/' + result.data.id + '/edit';
} else {
window.location.href = '/documents';
}
} else {
showToast(result.message || '오류가 발생했습니다.', 'error');
}
})
.catch(error => {
console.error('Error:', error);
showToast('오류가 발생했습니다.', 'error');
});
});
});
</script>
@endpush