479 lines
21 KiB
PHP
479 lines
21 KiB
PHP
@extends('admin.layouts.app')
|
|
|
|
@section('title', 'Edit Berita')
|
|
|
|
@push('styles')
|
|
<link href="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote-bs4.min.css" rel="stylesheet">
|
|
<!-- Fallback CSS -->
|
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.18/summernote-bs4.min.css" rel="stylesheet">
|
|
<style>
|
|
.soft-card {
|
|
border: 0;
|
|
border-radius: 16px;
|
|
box-shadow: 0 10px 30px rgba(16, 24, 40, .06);
|
|
}
|
|
|
|
.form-label {
|
|
font-weight: 600;
|
|
color: #495057;
|
|
}
|
|
|
|
.required::after {
|
|
content: " *";
|
|
color: #dc3545;
|
|
}
|
|
|
|
.preview-image {
|
|
max-width: 200px;
|
|
max-height: 200px;
|
|
object-fit: cover;
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.current-image {
|
|
max-width: 150px;
|
|
max-height: 150px;
|
|
object-fit: cover;
|
|
border-radius: 8px;
|
|
border: 2px solid #e9ecef;
|
|
}
|
|
|
|
/* Fix Summernote dropdown issues */
|
|
.note-editor .note-dropdown-menu {
|
|
z-index: 9999 !important;
|
|
position: absolute !important;
|
|
display: block !important;
|
|
}
|
|
|
|
.note-editor .note-btn-group .note-dropdown-menu {
|
|
z-index: 9999 !important;
|
|
}
|
|
|
|
.note-editor .note-fontname .note-dropdown-menu,
|
|
.note-editor .note-fontsize .note-dropdown-menu,
|
|
.note-editor .note-color .note-dropdown-menu,
|
|
.note-editor .note-para .note-dropdown-menu,
|
|
.note-editor .note-height .note-dropdown-menu {
|
|
z-index: 9999 !important;
|
|
position: absolute !important;
|
|
display: block !important;
|
|
}
|
|
|
|
/* Ensure dropdowns are visible */
|
|
.note-editor .note-dropdown-menu.show {
|
|
display: block !important;
|
|
visibility: visible !important;
|
|
opacity: 1 !important;
|
|
}
|
|
|
|
/* Fix for Bootstrap 4 compatibility */
|
|
.note-editor .dropdown-menu {
|
|
z-index: 9999 !important;
|
|
}
|
|
|
|
/* Additional fixes for dropdown positioning */
|
|
.note-editor .note-btn-group {
|
|
position: relative !important;
|
|
}
|
|
|
|
.note-editor .note-dropdown-menu {
|
|
top: 100% !important;
|
|
left: 0 !important;
|
|
min-width: 100px !important;
|
|
}
|
|
|
|
/* Ensure color picker works */
|
|
.note-editor .note-color .note-dropdown-menu {
|
|
min-width: 200px !important;
|
|
}
|
|
|
|
/* Fix font size dropdown */
|
|
.note-editor .note-fontsize .note-dropdown-menu {
|
|
min-width: 80px !important;
|
|
}
|
|
|
|
/* Fix paragraph dropdown */
|
|
.note-editor .note-para .note-dropdown-menu {
|
|
min-width: 120px !important;
|
|
}
|
|
|
|
/* Fix height dropdown */
|
|
.note-editor .note-height .note-dropdown-menu {
|
|
min-width: 100px !important;
|
|
}
|
|
|
|
/* Ensure dropdowns are hidden by default */
|
|
.note-editor .note-dropdown-menu {
|
|
display: none !important;
|
|
}
|
|
|
|
/* Show dropdowns only when they have the 'show' class */
|
|
.note-editor .note-dropdown-menu.show {
|
|
display: block !important;
|
|
}
|
|
|
|
/* Prevent multiple dropdowns from showing */
|
|
.note-editor .note-dropdown-menu:not(.show) {
|
|
display: none !important;
|
|
visibility: hidden !important;
|
|
opacity: 0 !important;
|
|
}
|
|
|
|
/* Ensure all toolbar buttons are clickable */
|
|
.note-editor .note-btn {
|
|
cursor: pointer !important;
|
|
pointer-events: auto !important;
|
|
}
|
|
|
|
.note-editor .note-btn:hover {
|
|
background-color: #e9ecef !important;
|
|
}
|
|
|
|
.note-editor .note-btn.active {
|
|
background-color: #007bff !important;
|
|
color: white !important;
|
|
}
|
|
|
|
/* Fix link dialog */
|
|
.note-editor .note-link-dialog {
|
|
z-index: 9999 !important;
|
|
}
|
|
|
|
/* Fix fullscreen mode */
|
|
.note-editor.note-editing-area.note-frame.fullscreen {
|
|
z-index: 9999 !important;
|
|
}
|
|
</style>
|
|
@endpush
|
|
|
|
@section('content')
|
|
<div class="card soft-card">
|
|
<div class="card-body">
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<div>
|
|
<h4 class="mb-0">Edit Berita</h4>
|
|
<small class="text-success">Edit berita yang sudah ada</small>
|
|
</div>
|
|
<a href="{{ route('admin.berita.index') }}" class="btn btn-outline-secondary">
|
|
<i class="ti ti-arrow-left"></i> Kembali
|
|
</a>
|
|
</div>
|
|
|
|
<form action="{{ route('admin.berita.update', $news->id ?? 1) }}" method="POST" enctype="multipart/form-data">
|
|
@csrf
|
|
@method('PUT')
|
|
|
|
<div class="row">
|
|
<div class="col-lg-8">
|
|
<!-- Judul -->
|
|
<div class="mb-3">
|
|
<label for="title" class="form-label required">Judul Berita</label>
|
|
<input type="text"
|
|
class="form-control @error('title') is-invalid @enderror"
|
|
id="title"
|
|
name="title"
|
|
value="{{ old('title', $news->title ?? 'Judul Berita') }}"
|
|
placeholder="Masukkan judul berita"
|
|
required>
|
|
@error('title')
|
|
<div class="invalid-feedback">{{ $message }}</div>
|
|
@enderror
|
|
</div>
|
|
|
|
<!-- Slug -->
|
|
<div class="mb-3">
|
|
<label for="slug" class="form-label">Slug URL</label>
|
|
<input type="text"
|
|
class="form-control @error('slug') is-invalid @enderror"
|
|
id="slug"
|
|
name="slug"
|
|
value="{{ old('slug', $news->slug ?? 'slug-berita') }}"
|
|
placeholder="slug-berita-otomatis">
|
|
<small class="text-muted">Biarkan kosong untuk generate otomatis dari judul</small>
|
|
@error('slug')
|
|
<div class="invalid-feedback">{{ $message }}</div>
|
|
@enderror
|
|
</div>
|
|
|
|
<!-- Content -->
|
|
<div class="mb-3">
|
|
<label for="content" class="form-label required">Konten Berita</label>
|
|
<textarea class="form-control @error('content') is-invalid @enderror"
|
|
id="content"
|
|
name="content"
|
|
rows="15"
|
|
placeholder="Tulis konten berita disini...">{{ old('content', $news->content ?? 'Konten berita...') }}</textarea>
|
|
@error('content')
|
|
<div class="invalid-feedback">{{ $message }}</div>
|
|
@enderror
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-lg-4">
|
|
<!-- Kategori -->
|
|
<div class="mb-3">
|
|
<label for="category" class="form-label required">Kategori</label>
|
|
<select class="form-select @error('category') is-invalid @enderror"
|
|
id="category"
|
|
name="category"
|
|
required>
|
|
<option value="">Pilih kategori</option>
|
|
@php
|
|
$categories = ['Infrastruktur', 'Ekonomi', 'Kesehatan', 'Budaya', 'Pemerintahan', 'Pendidikan', 'Lingkungan', 'Teknologi', 'Umum'];
|
|
$currentCategory = old('category', $news->category ?? '');
|
|
@endphp
|
|
@foreach($categories as $category)
|
|
<option value="{{ $category }}" {{ $currentCategory == $category ? 'selected' : '' }}>
|
|
{{ $category }}
|
|
</option>
|
|
@endforeach
|
|
</select>
|
|
@error('category')
|
|
<div class="invalid-feedback">{{ $message }}</div>
|
|
@enderror
|
|
</div>
|
|
|
|
<!-- Status -->
|
|
<div class="mb-3">
|
|
<label for="status" class="form-label required">Status</label>
|
|
<select class="form-select @error('status') is-invalid @enderror"
|
|
id="status"
|
|
name="status"
|
|
required>
|
|
@php
|
|
$statuses = ['draft' => 'Draft', 'published' => 'Published', 'archived' => 'Archived'];
|
|
$currentStatus = old('status', $news->status ?? 'draft');
|
|
@endphp
|
|
@foreach($statuses as $value => $label)
|
|
<option value="{{ $value }}" {{ $currentStatus == $value ? 'selected' : '' }}>
|
|
{{ $label }}
|
|
</option>
|
|
@endforeach
|
|
</select>
|
|
@error('status')
|
|
<div class="invalid-feedback">{{ $message }}</div>
|
|
@enderror
|
|
</div>
|
|
|
|
<!-- Image -->
|
|
<div class="mb-3">
|
|
<label for="image" class="form-label">Gambar</label>
|
|
|
|
<!-- Current Image -->
|
|
@if(isset($news->image) && $news->image)
|
|
<div class="mb-2">
|
|
<label class="form-label">Gambar Saat Ini:</label>
|
|
<div>
|
|
<img src="{{ asset('storage/' . $news->image) }}"
|
|
alt="Current Image"
|
|
class="current-image"
|
|
onerror="this.style.display='none'">
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
<input type="file"
|
|
class="form-control @error('image') is-invalid @enderror"
|
|
id="image"
|
|
name="image"
|
|
accept="image/*"
|
|
onchange="previewImage(this)">
|
|
<small class="text-muted">Format: JPG, PNG, GIF. Maks: 2MB. Kosongkan jika tidak ingin mengubah gambar.</small>
|
|
@error('image')
|
|
<div class="invalid-feedback">{{ $message }}</div>
|
|
@enderror
|
|
|
|
<!-- Preview Image -->
|
|
<div id="imagePreview" class="mt-2" style="display: none;">
|
|
<label class="form-label">Preview Gambar Baru:</label>
|
|
<img id="preview" class="preview-image" src="" alt="Preview">
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Meta Information -->
|
|
<div class="mb-3">
|
|
<label class="form-label">Informasi Meta</label>
|
|
<div class="small text-muted">
|
|
<div>Dibuat: {{ isset($news->created_at) ? $news->created_at->format('d M Y H:i') : 'N/A' }}</div>
|
|
<div>Diupdate: {{ isset($news->updated_at) ? $news->updated_at->format('d M Y H:i') : 'N/A' }}</div>
|
|
@if(isset($news->id))
|
|
<div>ID: {{ $news->id }}</div>
|
|
@endif
|
|
@if(isset($news->views))
|
|
<div>Views: {{ $news->views }}</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Action Buttons -->
|
|
<div class="d-flex justify-content-end gap-2 mt-4">
|
|
<a href="{{ route('admin.berita.index') }}" class="btn btn-outline-secondary">
|
|
<i class="ti ti-x"></i> Batal
|
|
</a>
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="ti ti-device-floppy"></i> Update Berita
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
@endsection
|
|
|
|
@push('scripts')
|
|
<script src="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote-bs4.min.js"></script>
|
|
<!-- Fallback JS -->
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.18/summernote-bs4.min.js"></script>
|
|
<script>
|
|
$(document).ready(function() {
|
|
console.log('Document ready, initializing Summernote...');
|
|
|
|
// Check if Summernote is loaded
|
|
if (typeof $.fn.summernote === 'undefined') {
|
|
console.error('Summernote not loaded!');
|
|
return;
|
|
}
|
|
|
|
// Initialize Summernote
|
|
$('#content').summernote({
|
|
height: 400,
|
|
toolbar: [
|
|
['font', ['bold', 'underline', 'italic', 'strikethrough', 'clear']],
|
|
['fontname', ['fontname']],
|
|
['fontsize', ['fontsize']],
|
|
['color', ['color', 'backcolor']],
|
|
['para', ['ul', 'ol', 'paragraph']],
|
|
['height', ['height']],
|
|
['insert', ['link']],
|
|
['view', ['fullscreen', 'help']]
|
|
],
|
|
fontNames: [
|
|
'Arial', 'Arial Black', 'Comic Sans MS', 'Courier New', 'Helvetica',
|
|
'Impact', 'Tahoma', 'Times New Roman', 'Trebuchet MS', 'Verdana',
|
|
'Georgia', 'Palatino', 'Garamond', 'Bookman', 'Comic Sans MS',
|
|
'Trebuchet MS', 'Arial Black', 'Impact', 'Lucida Sans Unicode',
|
|
'Tahoma', 'Lucida Grande'
|
|
],
|
|
fontSizes: ['8', '9', '10', '11', '12', '14', '16', '18', '24', '36', '48', '64'],
|
|
colorNames: [
|
|
'Red', 'Orange', 'Yellow', 'Green', 'Blue', 'Purple', 'Pink',
|
|
'Brown', 'Black', 'White', 'Gray', 'Light Gray', 'Dark Gray',
|
|
'Cyan', 'Magenta', 'Lime', 'Navy', 'Teal', 'Maroon', 'Olive'
|
|
],
|
|
callbacks: {
|
|
onInit: function() {
|
|
console.log('Summernote initialized successfully!');
|
|
|
|
// Fix dropdown behavior
|
|
setTimeout(function() {
|
|
// Remove all existing click handlers
|
|
$('.note-fontname, .note-fontsize, .note-color, .note-para, .note-height').off('click');
|
|
|
|
// Add proper click handlers for all dropdowns
|
|
$('.note-fontname, .note-fontsize, .note-color, .note-para, .note-height').on('click', function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
var $currentDropdown = $(this).find('.note-dropdown-menu');
|
|
var isOpen = $currentDropdown.hasClass('show');
|
|
|
|
// Close all dropdowns first
|
|
$('.note-dropdown-menu').removeClass('show');
|
|
|
|
// Toggle current dropdown only if it wasn't open
|
|
if (!isOpen) {
|
|
$currentDropdown.addClass('show');
|
|
}
|
|
});
|
|
|
|
// Close dropdowns when clicking on dropdown items
|
|
$('.note-dropdown-menu a').on('click', function() {
|
|
$(this).closest('.note-dropdown-menu').removeClass('show');
|
|
});
|
|
|
|
// Close dropdowns when clicking outside
|
|
$(document).on('click', function(e) {
|
|
if (!$(e.target).closest('.note-btn-group').length) {
|
|
$('.note-dropdown-menu').removeClass('show');
|
|
}
|
|
});
|
|
|
|
// Close dropdowns when pressing Escape key
|
|
$(document).on('keydown', function(e) {
|
|
if (e.key === 'Escape') {
|
|
$('.note-dropdown-menu').removeClass('show');
|
|
}
|
|
});
|
|
|
|
// Ensure all buttons are clickable
|
|
$('.note-btn').on('click', function() {
|
|
console.log('Button clicked:', $(this).attr('data-original-title') || $(this).text());
|
|
});
|
|
|
|
// Test link functionality
|
|
$('.note-link-btn').on('click', function() {
|
|
console.log('Link button clicked');
|
|
});
|
|
|
|
// Debug dropdown buttons
|
|
console.log('Found dropdown buttons:');
|
|
$('.note-btn-group').each(function() {
|
|
var $btn = $(this).find('.note-btn');
|
|
var title = $btn.attr('data-original-title') || $btn.text();
|
|
var classes = $btn.attr('class');
|
|
console.log('Button:', title, 'Classes:', classes);
|
|
});
|
|
|
|
}, 500);
|
|
},
|
|
onFocus: function() {
|
|
console.log('Editor focused');
|
|
},
|
|
onChange: function(contents, $editable) {
|
|
console.log('Content changed');
|
|
},
|
|
onPaste: function(e) {
|
|
console.log('Content pasted');
|
|
}
|
|
}
|
|
});
|
|
|
|
// Auto generate slug from title
|
|
$('#title').on('keyup', function() {
|
|
let title = $(this).val();
|
|
let slug = title.toLowerCase()
|
|
.replace(/[^a-z0-9 -]/g, '')
|
|
.replace(/\s+/g, '-')
|
|
.replace(/-+/g, '-')
|
|
.trim('-');
|
|
$('#slug').val(slug);
|
|
});
|
|
|
|
// Test if editor is working
|
|
setTimeout(function() {
|
|
if ($('#content').next('.note-editor').length > 0) {
|
|
console.log('Summernote editor is properly initialized');
|
|
} else {
|
|
console.error('Summernote editor failed to initialize');
|
|
}
|
|
}, 1000);
|
|
});
|
|
|
|
// Image preview function
|
|
function previewImage(input) {
|
|
if (input.files && input.files[0]) {
|
|
var reader = new FileReader();
|
|
reader.onload = function(e) {
|
|
$('#preview').attr('src', e.target.result);
|
|
$('#imagePreview').show();
|
|
}
|
|
reader.readAsDataURL(input.files[0]);
|
|
} else {
|
|
$('#imagePreview').hide();
|
|
}
|
|
}
|
|
</script>
|
|
@endpush
|
|
|