sidakpelem/resources/views/admin/features/berita/edit-berita.blade.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