181 lines
8.6 KiB
PHP
181 lines
8.6 KiB
PHP
@extends('layouts.admin')
|
|
|
|
@section('title', 'Upload Dokumen')
|
|
|
|
@section('breadcrumb')
|
|
<li class="breadcrumb-item"><a href="{{ route('admin.documents.index') }}">Dokumen</a></li>
|
|
<li class="breadcrumb-item active">Upload Baru</li>
|
|
@endsection
|
|
|
|
@section('content')
|
|
<div class="row justify-content-center">
|
|
<div class="col-lg-8">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-header bg-white border-bottom">
|
|
<h5 class="mb-0 fw-bold"><i class="bi bi-upload me-2"></i>Upload Dokumen PDF</h5>
|
|
</div>
|
|
<div class="card-body p-4">
|
|
<form method="POST" action="{{ route('admin.documents.store') }}" enctype="multipart/form-data">
|
|
@csrf
|
|
|
|
<div class="row g-3">
|
|
<div class="col-12">
|
|
<label class="form-label fw-semibold">Kategori <span class="text-danger">*</span></label>
|
|
<select name="category_id" class="form-select @error('category_id') is-invalid @enderror" required>
|
|
<option value="">— Pilih Kategori —</option>
|
|
@foreach($categories as $cat)
|
|
<option value="{{ $cat->id }}" {{ old('category_id') == $cat->id ? 'selected' : '' }}>
|
|
{{ $cat->name }}
|
|
</option>
|
|
@endforeach
|
|
</select>
|
|
@error('category_id')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
|
</div>
|
|
|
|
<div class="col-12">
|
|
<label class="form-label fw-semibold">Tajuk Dokumen <span class="text-danger">*</span></label>
|
|
<input type="text" name="title" class="form-control @error('title') is-invalid @enderror"
|
|
value="{{ old('title') }}" placeholder="Contoh: Garis Panduan Pelesenan Perniagaan 2024" required>
|
|
@error('title')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
|
</div>
|
|
|
|
<div class="col-12">
|
|
<label class="form-label fw-semibold">Fail PDF <span class="text-danger">*</span></label>
|
|
<input type="file" name="file" id="fileInput"
|
|
class="form-control @error('file') is-invalid @enderror"
|
|
accept=".pdf" required>
|
|
<div class="form-text">
|
|
Hanya fail PDF dibenarkan. Saiz maksimum:
|
|
{{ round(config('knowledgebase.upload.max_file_size', 20480) / 1024) }}MB
|
|
</div>
|
|
@error('file')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
|
<div id="filePreview" class="mt-2 d-none">
|
|
<div class="alert alert-info py-2 mb-0 small">
|
|
<i class="bi bi-file-pdf me-1"></i>
|
|
<span id="fileName"></span> —
|
|
<span id="fileSize"></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-12">
|
|
<label class="form-label fw-semibold">Deskripsi</label>
|
|
<textarea name="description" class="form-control" rows="2"
|
|
placeholder="Deskripsi ringkas dokumen ini...">{{ old('description') }}</textarea>
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<label class="form-label fw-semibold">Tarikh Kuat Kuasa</label>
|
|
<input type="date" name="effective_date" class="form-control @error('effective_date') is-invalid @enderror"
|
|
value="{{ old('effective_date') }}">
|
|
@error('effective_date')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<label class="form-label fw-semibold">Tarikh Luput</label>
|
|
<input type="date" name="expiry_date" class="form-control @error('expiry_date') is-invalid @enderror"
|
|
value="{{ old('expiry_date') }}">
|
|
@error('expiry_date')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<label class="form-label fw-semibold">Bahasa</label>
|
|
<select name="language" class="form-select">
|
|
<option value="ms" {{ old('language', 'ms') == 'ms' ? 'selected' : '' }}>Bahasa Melayu</option>
|
|
<option value="en" {{ old('language') == 'en' ? 'selected' : '' }}>English</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<label class="form-label fw-semibold">Tag</label>
|
|
<input type="text" id="tagsInput" class="form-control"
|
|
placeholder="Taip dan tekan Enter..."
|
|
value="{{ old('tags') ? implode(', ', old('tags')) : '' }}">
|
|
<div id="tagsContainer" class="mt-1"></div>
|
|
<input type="hidden" name="tags" id="tagsHidden">
|
|
<div class="form-text">Tekan Enter atau koma untuk tambah tag.</div>
|
|
</div>
|
|
|
|
<div class="col-12">
|
|
<label class="form-label fw-semibold">Nota Upload</label>
|
|
<input type="text" name="change_notes" class="form-control"
|
|
value="{{ old('change_notes', 'Versi pertama.') }}"
|
|
placeholder="Nota ringkas tentang upload ini...">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="d-flex gap-2 mt-4 pt-3 border-top">
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="bi bi-upload me-1"></i>Upload & Proses
|
|
</button>
|
|
<a href="{{ route('admin.documents.index') }}" class="btn btn-outline-secondary">
|
|
Batal
|
|
</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="alert alert-light border mt-3 small">
|
|
<i class="bi bi-info-circle me-2 text-info"></i>
|
|
Dokumen akan diproses secara <strong>background</strong> selepas upload. Proses extraction, chunking dan embedding mungkin mengambil masa beberapa minit bergantung pada saiz fail.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endsection
|
|
|
|
@push('scripts')
|
|
<script>
|
|
// Preview fail yang dipilih
|
|
$('#fileInput').on('change', function() {
|
|
const file = this.files[0];
|
|
if (file) {
|
|
const size = file.size < 1048576
|
|
? (file.size / 1024).toFixed(1) + ' KB'
|
|
: (file.size / 1048576).toFixed(1) + ' MB';
|
|
$('#fileName').text(file.name);
|
|
$('#fileSize').text(size);
|
|
$('#filePreview').removeClass('d-none');
|
|
}
|
|
});
|
|
|
|
// Tag input
|
|
let tags = [];
|
|
|
|
function renderTags() {
|
|
const container = $('#tagsContainer');
|
|
container.empty();
|
|
tags.forEach((tag, i) => {
|
|
container.append(
|
|
`<span class="badge bg-secondary me-1 mb-1">${tag}
|
|
<i class="bi bi-x-circle ms-1" style="cursor:pointer" data-i="${i}"></i></span>`
|
|
);
|
|
});
|
|
$('#tagsHidden').val(tags.map((t, i) => `tags[${i}]=${t}`).join('&'));
|
|
// Rebuild hidden inputs properly
|
|
$('[name^="tags["]').remove();
|
|
tags.forEach((tag, i) => {
|
|
$('form').append(`<input type="hidden" name="tags[${i}]" value="${tag}">`);
|
|
});
|
|
}
|
|
|
|
$('#tagsInput').on('keydown', function(e) {
|
|
if (e.key === 'Enter' || e.key === ',') {
|
|
e.preventDefault();
|
|
const val = $(this).val().trim().replace(/,$/, '');
|
|
if (val && !tags.includes(val)) {
|
|
tags.push(val);
|
|
renderTags();
|
|
}
|
|
$(this).val('');
|
|
}
|
|
});
|
|
|
|
$(document).on('click', '.bi-x-circle', function() {
|
|
const i = $(this).data('i');
|
|
tags.splice(i, 1);
|
|
renderTags();
|
|
});
|
|
</script>
|
|
@endpush
|