user-artikel final done
This commit is contained in:
parent
b979707a4a
commit
54e82c61a7
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\InformasiBudidaya;
|
||||
use App\Models\BudidayaSub;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
|
|
@ -25,12 +26,15 @@ public function store(Request $request)
|
|||
$validated = $request->validate([
|
||||
'judul' => 'required|string|max:200',
|
||||
'deskripsi_singkat' => 'nullable|string',
|
||||
'konten' => 'required|string',
|
||||
'konten' => 'nullable|string',
|
||||
'gambar_utama' => 'nullable|image|max:2048',
|
||||
'galeri_gambar.*' => 'nullable|image|max:2048',
|
||||
'file_pdf' => 'nullable|mimes:pdf|max:5120',
|
||||
'tags' => 'nullable|string',
|
||||
'is_published' => 'boolean',
|
||||
'sub_judul.*' => 'nullable|string|max:200',
|
||||
'sub_konten.*' => 'nullable|string',
|
||||
'sub_gambar.*' => 'nullable|image|max:2048',
|
||||
]);
|
||||
|
||||
$validated['slug'] = Str::slug($request->judul);
|
||||
|
|
@ -45,16 +49,14 @@ public function store(Request $request)
|
|||
$validated['file_pdf'] = $request->file('file_pdf')->store('budidaya/pdf', 'public');
|
||||
}
|
||||
|
||||
// Handle galeri gambar
|
||||
if ($request->hasFile('galeri_gambar')) {
|
||||
$galeri = [];
|
||||
foreach ($request->file('galeri_gambar') as $foto) {
|
||||
$galeri[] = $foto->store('budidaya/galeri', 'public');
|
||||
}
|
||||
$validated['galeri_gambar'] = $galeri; // otomatis di-cast ke JSON oleh model
|
||||
$validated['galeri_gambar'] = $galeri;
|
||||
}
|
||||
|
||||
// Handle tags
|
||||
$tagsDecoded = json_decode($request->tags, true);
|
||||
$validated['tags'] = (!empty($tagsDecoded)) ? $tagsDecoded : null;
|
||||
|
||||
|
|
@ -62,7 +64,28 @@ public function store(Request $request)
|
|||
$validated['published_at'] = now();
|
||||
}
|
||||
|
||||
InformasiBudidaya::create($validated);
|
||||
$artikel = InformasiBudidaya::create($validated);
|
||||
|
||||
// Handle sub-bab
|
||||
if ($request->has('sub_judul')) {
|
||||
foreach ($request->sub_judul as $index => $judul) {
|
||||
if (!empty($judul)) {
|
||||
$subData = [
|
||||
'id_artikel' => $artikel->id,
|
||||
'judul_sub' => $judul,
|
||||
'konten' => $request->sub_konten[$index] ?? null,
|
||||
'urutan' => $index + 1,
|
||||
];
|
||||
|
||||
if ($request->hasFile("sub_gambar.$index")) {
|
||||
$path = $request->file("sub_gambar.$index")->store('budidaya/sub', 'public');
|
||||
$subData['gambar'] = $path;
|
||||
}
|
||||
|
||||
BudidayaSub::create($subData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return redirect()->route('admin.artikel-budidaya.index')
|
||||
->with('success', 'Artikel budidaya berhasil ditambahkan!');
|
||||
|
|
@ -70,6 +93,7 @@ public function store(Request $request)
|
|||
|
||||
public function edit(InformasiBudidaya $artikelBudidaya)
|
||||
{
|
||||
$artikelBudidaya->load('subBab');
|
||||
return view('admin.artikel-budidaya.edit', compact('artikelBudidaya'));
|
||||
}
|
||||
|
||||
|
|
@ -78,12 +102,15 @@ public function update(Request $request, InformasiBudidaya $artikelBudidaya)
|
|||
$validated = $request->validate([
|
||||
'judul' => 'required|string|max:200',
|
||||
'deskripsi_singkat' => 'nullable|string',
|
||||
'konten' => 'required|string',
|
||||
'konten' => 'nullable|string',
|
||||
'gambar_utama' => 'nullable|image|max:2048',
|
||||
'galeri_gambar.*' => 'nullable|image|max:2048',
|
||||
'file_pdf' => 'nullable|mimes:pdf|max:5120',
|
||||
'tags' => 'nullable|string',
|
||||
'is_published' => 'boolean',
|
||||
'sub_judul.*' => 'nullable|string|max:200',
|
||||
'sub_konten.*' => 'nullable|string',
|
||||
'sub_gambar.*' => 'nullable|image|max:2048',
|
||||
]);
|
||||
|
||||
$validated['slug'] = Str::slug($request->judul);
|
||||
|
|
@ -97,7 +124,6 @@ public function update(Request $request, InformasiBudidaya $artikelBudidaya)
|
|||
$validated['file_pdf'] = $request->file('file_pdf')->store('budidaya/pdf', 'public');
|
||||
}
|
||||
|
||||
// Handle galeri gambar
|
||||
if ($request->hasFile('galeri_gambar')) {
|
||||
$galeri = [];
|
||||
foreach ($request->file('galeri_gambar') as $foto) {
|
||||
|
|
@ -106,7 +132,6 @@ public function update(Request $request, InformasiBudidaya $artikelBudidaya)
|
|||
$validated['galeri_gambar'] = $galeri;
|
||||
}
|
||||
|
||||
// Handle tags
|
||||
$tagsDecoded = json_decode($request->tags, true);
|
||||
$validated['tags'] = (!empty($tagsDecoded)) ? $tagsDecoded : null;
|
||||
|
||||
|
|
@ -116,6 +141,29 @@ public function update(Request $request, InformasiBudidaya $artikelBudidaya)
|
|||
|
||||
$artikelBudidaya->update($validated);
|
||||
|
||||
// Hapus sub-bab lama & simpan yang baru
|
||||
$artikelBudidaya->subBab()->delete();
|
||||
|
||||
if ($request->has('sub_judul')) {
|
||||
foreach ($request->sub_judul as $index => $judul) {
|
||||
if (!empty($judul)) {
|
||||
$subData = [
|
||||
'id_artikel' => $artikelBudidaya->id,
|
||||
'judul_sub' => $judul,
|
||||
'konten' => $request->sub_konten[$index] ?? null,
|
||||
'urutan' => $index + 1,
|
||||
];
|
||||
|
||||
if ($request->hasFile("sub_gambar.$index")) {
|
||||
$path = $request->file("sub_gambar.$index")->store('budidaya/sub', 'public');
|
||||
$subData['gambar'] = $path;
|
||||
}
|
||||
|
||||
BudidayaSub::create($subData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return redirect()->route('admin.artikel-budidaya.index')
|
||||
->with('success', 'Artikel budidaya berhasil diupdate!');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class BudidayaSub extends Model
|
||||
{
|
||||
protected $table = 'budidaya_sub';
|
||||
|
||||
protected $fillable = [
|
||||
'id_artikel',
|
||||
'judul_sub',
|
||||
'konten',
|
||||
'gambar',
|
||||
'urutan',
|
||||
];
|
||||
|
||||
public function artikel()
|
||||
{
|
||||
return $this->belongsTo(InformasiBudidaya::class, 'id_artikel', 'id');
|
||||
}
|
||||
}
|
||||
|
|
@ -41,4 +41,9 @@ public function scopePublished($query)
|
|||
{
|
||||
return $query->where('is_published', true);
|
||||
}
|
||||
|
||||
public function subBab()
|
||||
{
|
||||
return $this->hasMany(BudidayaSub::class, 'id_artikel', 'id')->orderBy('urutan');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('budidaya_sub', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('id_artikel')->constrained('informasi_budidaya')->onDelete('cascade');
|
||||
$table->string('judul_sub');
|
||||
$table->longText('konten')->nullable();
|
||||
$table->string('gambar')->nullable();
|
||||
$table->integer('urutan')->default(0);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('budidaya_sub');
|
||||
}
|
||||
};
|
||||
|
|
@ -12,10 +12,10 @@
|
|||
<div class="space-y-6">
|
||||
<!-- Judul -->
|
||||
<div>
|
||||
<label class="block text-sm font-bold text-gray-700 mb-2">Judul <span class="text-red-500">*</span></label>
|
||||
<label class="block text-sm font-bold text-gray-700 mb-2">Judul Bab <span class="text-red-500">*</span></label>
|
||||
<input type="text" name="judul" value="{{ old('judul') }}"
|
||||
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-green-500 focus:border-transparent @error('judul') border-red-500 @enderror"
|
||||
placeholder="Masukkan judul artikel...">
|
||||
placeholder="Contoh: Persiapan Lahan, Penanaman, dll...">
|
||||
@error('judul') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
|
||||
</div>
|
||||
|
||||
|
|
@ -24,22 +24,13 @@ class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:rin
|
|||
<label class="block text-sm font-bold text-gray-700 mb-2">Deskripsi Singkat</label>
|
||||
<textarea name="deskripsi_singkat" rows="3"
|
||||
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-green-500 focus:border-transparent"
|
||||
placeholder="Ringkasan singkat artikel...">{{ old('deskripsi_singkat') }}</textarea>
|
||||
</div>
|
||||
|
||||
<!-- Konten -->
|
||||
<div>
|
||||
<label class="block text-sm font-bold text-gray-700 mb-2">Konten <span class="text-red-500">*</span></label>
|
||||
<textarea name="konten" rows="10"
|
||||
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-green-500 focus:border-transparent @error('konten') border-red-500 @enderror"
|
||||
placeholder="Tulis konten artikel di sini...">{{ old('konten') }}</textarea>
|
||||
@error('konten') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
|
||||
placeholder="Ringkasan singkat tentang bab ini...">{{ old('deskripsi_singkat') }}</textarea>
|
||||
</div>
|
||||
|
||||
<!-- Gambar Utama & PDF -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<label class="block text-sm font-bold text-gray-700 mb-2">Gambar Utama</label>
|
||||
<label class="block text-sm font-bold text-gray-700 mb-2">Gambar Cover</label>
|
||||
<input type="file" name="gambar_utama" accept="image/*"
|
||||
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-green-500">
|
||||
<p class="text-xs text-gray-400 mt-1">Format: JPG, PNG. Maks 2MB</p>
|
||||
|
|
@ -55,8 +46,7 @@ class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:rin
|
|||
<!-- Tags -->
|
||||
<div>
|
||||
<label class="block text-sm font-bold text-gray-700 mb-2">Tags</label>
|
||||
<div id="tags-container" class="w-full px-4 py-3 border border-gray-300 rounded-xl flex flex-wrap gap-2 min-h-[50px]">
|
||||
</div>
|
||||
<div id="tags-container" class="w-full px-4 py-3 border border-gray-300 rounded-xl flex flex-wrap gap-2 min-h-[50px]"></div>
|
||||
<input type="text" id="tags-input"
|
||||
class="w-full mt-2 px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-green-500"
|
||||
placeholder="Ketik tag lalu tekan Enter...">
|
||||
|
|
@ -64,12 +54,26 @@ class="w-full mt-2 px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focu
|
|||
<input type="hidden" name="tags" id="tags-hidden" value="[]">
|
||||
</div>
|
||||
|
||||
<!-- Galeri Gambar -->
|
||||
<!-- Sub-bab -->
|
||||
<div>
|
||||
<label class="block text-sm font-bold text-gray-700 mb-2">Galeri Gambar</label>
|
||||
<input type="file" name="galeri_gambar[]" accept="image/*" multiple
|
||||
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-green-500">
|
||||
<p class="text-xs text-gray-400 mt-1">Bisa pilih beberapa foto sekaligus. Format: JPG, PNG. Maks 2MB per foto</p>
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div>
|
||||
<label class="block text-sm font-bold text-gray-700">Sub-bab</label>
|
||||
<p class="text-xs text-gray-400 mt-1">Tambahkan sub-bab untuk artikel ini</p>
|
||||
</div>
|
||||
<button type="button" onclick="tambahSub()"
|
||||
class="flex items-center gap-2 px-4 py-2 bg-green-500 text-white text-sm font-bold rounded-xl hover:bg-green-600 transition">
|
||||
+ Tambah Sub-bab
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="sub-container" class="space-y-4">
|
||||
<!-- Sub-bab items akan ditambahkan di sini -->
|
||||
</div>
|
||||
|
||||
<div id="empty-sub" class="text-center py-8 bg-gray-50 rounded-xl border-2 border-dashed border-gray-200">
|
||||
<p class="text-gray-400 text-sm">Belum ada sub-bab. Klik tombol di atas untuk menambahkan.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Status Publish -->
|
||||
|
|
@ -96,6 +100,53 @@ class="w-5 h-5 text-green-600 rounded focus:ring-green-500">
|
|||
|
||||
@push('scripts')
|
||||
<script>
|
||||
let subCount = 0;
|
||||
|
||||
function tambahSub() {
|
||||
const container = document.getElementById('sub-container');
|
||||
const empty = document.getElementById('empty-sub');
|
||||
empty.classList.add('hidden');
|
||||
|
||||
const index = subCount++;
|
||||
const div = document.createElement('div');
|
||||
div.className = 'sub-item bg-gray-50 border border-gray-200 rounded-xl p-5 space-y-4';
|
||||
div.id = `sub-${index}`;
|
||||
div.innerHTML = `
|
||||
<div class="flex items-center justify-between">
|
||||
<h4 class="font-bold text-gray-700 text-sm">Sub-bab ${index + 1}</h4>
|
||||
<button type="button" onclick="hapusSub(${index})" class="text-red-400 hover:text-red-600 text-sm font-semibold">Hapus</button>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">Judul Sub-bab <span class="text-red-500">*</span></label>
|
||||
<input type="text" name="sub_judul[]"
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-green-500"
|
||||
placeholder="Contoh: Pemilihan Lahan">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">Konten</label>
|
||||
<textarea name="sub_konten[]" rows="5"
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-green-500"
|
||||
placeholder="Tulis isi sub-bab di sini..."></textarea>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">Gambar (opsional)</label>
|
||||
<input type="file" name="sub_gambar[${index}]" accept="image/*"
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg text-sm">
|
||||
<p class="text-xs text-gray-400 mt-1">Format: JPG, PNG. Maks 2MB</p>
|
||||
</div>
|
||||
`;
|
||||
container.appendChild(div);
|
||||
}
|
||||
|
||||
function hapusSub(index) {
|
||||
const el = document.getElementById(`sub-${index}`);
|
||||
if (el) el.remove();
|
||||
if (document.querySelectorAll('.sub-item').length === 0) {
|
||||
document.getElementById('empty-sub').classList.remove('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
// Tags
|
||||
const tagsInput = document.getElementById('tags-input');
|
||||
const tagsContainer = document.getElementById('tags-container');
|
||||
const tagsHidden = document.getElementById('tags-hidden');
|
||||
|
|
@ -130,5 +181,4 @@ function removeTag(index) {
|
|||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@endpush
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
<div class="space-y-6">
|
||||
<!-- Judul -->
|
||||
<div>
|
||||
<label class="block text-sm font-bold text-gray-700 mb-2">Judul <span class="text-red-500">*</span></label>
|
||||
<label class="block text-sm font-bold text-gray-700 mb-2">Judul Bab <span class="text-red-500">*</span></label>
|
||||
<input type="text" name="judul" value="{{ old('judul', $artikelBudidaya->judul) }}"
|
||||
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-green-500 focus:border-transparent @error('judul') border-red-500 @enderror">
|
||||
@error('judul') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
|
||||
|
|
@ -26,24 +26,16 @@ class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:rin
|
|||
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-green-500 focus:border-transparent">{{ old('deskripsi_singkat', $artikelBudidaya->deskripsi_singkat) }}</textarea>
|
||||
</div>
|
||||
|
||||
<!-- Konten -->
|
||||
<div>
|
||||
<label class="block text-sm font-bold text-gray-700 mb-2">Konten <span class="text-red-500">*</span></label>
|
||||
<textarea name="konten" rows="10"
|
||||
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-green-500 focus:border-transparent @error('konten') border-red-500 @enderror">{{ old('konten', $artikelBudidaya->konten) }}</textarea>
|
||||
@error('konten') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
|
||||
</div>
|
||||
|
||||
<!-- Gambar Utama -->
|
||||
<!-- Gambar Utama & PDF -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<label class="block text-sm font-bold text-gray-700 mb-2">Gambar Utama</label>
|
||||
<label class="block text-sm font-bold text-gray-700 mb-2">Gambar Cover</label>
|
||||
@if($artikelBudidaya->gambar_utama)
|
||||
<img src="{{ Storage::url($artikelBudidaya->gambar_utama) }}" class="w-32 h-24 object-cover rounded-lg mb-2">
|
||||
@endif
|
||||
<input type="file" name="gambar_utama" accept="image/*"
|
||||
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-green-500">
|
||||
<p class="text-xs text-gray-400 mt-1">Kosongkan jika tidak ingin mengubah gambar</p>
|
||||
<p class="text-xs text-gray-400 mt-1">Kosongkan jika tidak ingin mengubah</p>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-bold text-gray-700 mb-2">File PDF</label>
|
||||
|
|
@ -52,36 +44,74 @@ class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:rin
|
|||
@endif
|
||||
<input type="file" name="file_pdf" accept=".pdf"
|
||||
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-green-500">
|
||||
<p class="text-xs text-gray-400 mt-1">Kosongkan jika tidak ingin mengubah PDF</p>
|
||||
<p class="text-xs text-gray-400 mt-1">Kosongkan jika tidak ingin mengubah</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tags -->
|
||||
<div>
|
||||
<label class="block text-sm font-bold text-gray-700 mb-2">Tags</label>
|
||||
<div id="tags-container" class="w-full px-4 py-3 border border-gray-300 rounded-xl flex flex-wrap gap-2 min-h-[50px]">
|
||||
</div>
|
||||
<div id="tags-container" class="w-full px-4 py-3 border border-gray-300 rounded-xl flex flex-wrap gap-2 min-h-[50px]"></div>
|
||||
<input type="text" id="tags-input"
|
||||
class="w-full mt-2 px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-green-500"
|
||||
placeholder="Ketik tag lalu tekan Enter...">
|
||||
<p class="text-xs text-gray-400 mt-1">Tekan Enter atau koma untuk menambah tag</p>
|
||||
<input type="hidden" name="tags" id="tags-hidden" value="[]">
|
||||
</div>
|
||||
|
||||
<!-- Galeri Gambar -->
|
||||
<!-- Sub-bab -->
|
||||
<div>
|
||||
<label class="block text-sm font-bold text-gray-700 mb-2">Galeri Gambar</label>
|
||||
@if($artikelBudidaya->galeri_gambar)
|
||||
<div class="flex flex-wrap gap-2 mb-3">
|
||||
@foreach($artikelBudidaya->galeri_gambar as $foto)
|
||||
<img src="{{ Storage::url($foto) }}" class="w-24 h-20 object-cover rounded-lg">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div>
|
||||
<label class="block text-sm font-bold text-gray-700">Sub-bab</label>
|
||||
<p class="text-xs text-gray-400 mt-1">Edit atau tambah sub-bab</p>
|
||||
</div>
|
||||
<button type="button" onclick="tambahSub()"
|
||||
class="flex items-center gap-2 px-4 py-2 bg-green-500 text-white text-sm font-bold rounded-xl hover:bg-green-600 transition">
|
||||
+ Tambah Sub-bab
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="sub-container" class="space-y-4">
|
||||
@foreach($artikelBudidaya->subBab as $i => $sub)
|
||||
<div class="sub-item bg-gray-50 border border-gray-200 rounded-xl p-5 space-y-4" id="sub-existing-{{ $i }}">
|
||||
<div class="flex items-center justify-between">
|
||||
<h4 class="font-bold text-gray-700 text-sm">Sub-bab {{ $i + 1 }}</h4>
|
||||
<button type="button" onclick="hapusSubExisting('sub-existing-{{ $i }}')" class="text-red-400 hover:text-red-600 text-sm font-semibold">Hapus</button>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">Judul Sub-bab <span class="text-red-500">*</span></label>
|
||||
<input type="text" name="sub_judul[]" value="{{ $sub->judul_sub }}"
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-green-500">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">Konten</label>
|
||||
<textarea name="sub_konten[]" rows="5"
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-green-500">{{ $sub->konten }}</textarea>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">Gambar</label>
|
||||
@if($sub->gambar)
|
||||
<img src="{{ Storage::url($sub->gambar) }}" class="w-24 h-16 object-cover rounded-lg mb-2">
|
||||
@endif
|
||||
<input type="file" name="sub_gambar[{{ $i }}]" accept="image/*"
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg text-sm">
|
||||
<p class="text-xs text-gray-400 mt-1">Kosongkan jika tidak ingin mengubah</p>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
<input type="file" name="galeri_gambar[]" accept="image/*" multiple
|
||||
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-green-500">
|
||||
<p class="text-xs text-gray-400 mt-1">Upload foto baru akan menggantikan galeri yang lama</p>
|
||||
|
||||
@if($artikelBudidaya->subBab->isEmpty())
|
||||
<div id="empty-sub" class="text-center py-8 bg-gray-50 rounded-xl border-2 border-dashed border-gray-200">
|
||||
<p class="text-gray-400 text-sm">Belum ada sub-bab. Klik tombol di atas untuk menambahkan.</p>
|
||||
</div>
|
||||
@else
|
||||
<div id="empty-sub" class="hidden text-center py-8 bg-gray-50 rounded-xl border-2 border-dashed border-gray-200">
|
||||
<p class="text-gray-400 text-sm">Belum ada sub-bab. Klik tombol di atas untuk menambahkan.</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- Status Publish -->
|
||||
<div class="flex items-center space-x-3">
|
||||
<input type="checkbox" name="is_published" value="1" id="is_published" {{ old('is_published', $artikelBudidaya->is_published) ? 'checked' : '' }}
|
||||
|
|
@ -106,11 +136,55 @@ class="w-5 h-5 text-green-600 rounded focus:ring-green-500">
|
|||
|
||||
@push('scripts')
|
||||
<script>
|
||||
let subCount = {{ $artikelBudidaya->subBab->count() }};
|
||||
|
||||
function tambahSub() {
|
||||
const container = document.getElementById('sub-container');
|
||||
const empty = document.getElementById('empty-sub');
|
||||
empty.classList.add('hidden');
|
||||
|
||||
const index = subCount++;
|
||||
const div = document.createElement('div');
|
||||
div.className = 'sub-item bg-gray-50 border border-gray-200 rounded-xl p-5 space-y-4';
|
||||
div.id = `sub-new-${index}`;
|
||||
div.innerHTML = `
|
||||
<div class="flex items-center justify-between">
|
||||
<h4 class="font-bold text-gray-700 text-sm">Sub-bab Baru</h4>
|
||||
<button type="button" onclick="hapusSubExisting('sub-new-${index}')" class="text-red-400 hover:text-red-600 text-sm font-semibold">Hapus</button>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">Judul Sub-bab <span class="text-red-500">*</span></label>
|
||||
<input type="text" name="sub_judul[]"
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-green-500"
|
||||
placeholder="Contoh: Pemilihan Lahan">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">Konten</label>
|
||||
<textarea name="sub_konten[]" rows="5"
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-green-500"
|
||||
placeholder="Tulis isi sub-bab di sini..."></textarea>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">Gambar (opsional)</label>
|
||||
<input type="file" name="sub_gambar[${index}]" accept="image/*"
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg text-sm">
|
||||
</div>
|
||||
`;
|
||||
container.appendChild(div);
|
||||
}
|
||||
|
||||
function hapusSubExisting(id) {
|
||||
const el = document.getElementById(id);
|
||||
if (el) el.remove();
|
||||
if (document.querySelectorAll('.sub-item').length === 0) {
|
||||
document.getElementById('empty-sub').classList.remove('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
// Tags
|
||||
const tagsInput = document.getElementById('tags-input');
|
||||
const tagsContainer = document.getElementById('tags-container');
|
||||
const tagsHidden = document.getElementById('tags-hidden');
|
||||
|
||||
// Load tags yang sudah ada
|
||||
let tags = {!! json_encode($artikelBudidaya->tags ?? []) !!};
|
||||
|
||||
function renderTags() {
|
||||
|
|
@ -142,7 +216,6 @@ function removeTag(index) {
|
|||
}
|
||||
});
|
||||
|
||||
// Render tags awal
|
||||
renderTags();
|
||||
</script>
|
||||
@endpush
|
||||
|
|
@ -1,89 +1,427 @@
|
|||
@extends('layouts.user-app')
|
||||
|
||||
@section('page-title', '🌱 Artikel Budidaya')
|
||||
@section('page-title', 'Artikel Budidaya')
|
||||
@section('page-subtitle', 'Informasi seputar budidaya tanaman kopi')
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Lora:ital,wght@0,400;0,600;0,700;1,400&family=DM+Sans:wght@300;400;500;600&display=swap');
|
||||
|
||||
.budidaya-page {
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
}
|
||||
|
||||
/* ── Search Bar ── */
|
||||
.search-wrap {
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 4px 20px rgba(34,80,34,.08);
|
||||
padding: 20px 24px;
|
||||
margin-bottom: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.search-inner {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
left: 14px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: #9eb89e;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
width: 100%;
|
||||
padding: 12px 16px 12px 44px;
|
||||
border: 1.5px solid #e0ece0;
|
||||
border-radius: 12px;
|
||||
font-size: 13.5px;
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
color: #1a2e1a;
|
||||
background: #f7fbf7;
|
||||
transition: border-color .2s, box-shadow .2s;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.search-input:focus {
|
||||
border-color: #4caf50;
|
||||
box-shadow: 0 0 0 3px rgba(76,175,80,.12);
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.search-input::placeholder { color: #9eb89e; }
|
||||
|
||||
.search-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 8px 16px;
|
||||
background: linear-gradient(135deg, #e8f5e9, #c8e6c9);
|
||||
border: 1.5px solid #a5d6a7;
|
||||
border-radius: 100px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #2e7d32;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* ── Grid ── */
|
||||
.artikel-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(1, 1fr);
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.artikel-grid { grid-template-columns: repeat(2, 1fr); }
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.artikel-grid { grid-template-columns: repeat(3, 1fr); }
|
||||
}
|
||||
|
||||
/* ── Card ── */
|
||||
.artikel-card {
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 4px 20px rgba(34,80,34,.07);
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-decoration: none;
|
||||
transition: transform .25s ease, box-shadow .25s ease;
|
||||
border: 1.5px solid #f0f7f0;
|
||||
}
|
||||
|
||||
.artikel-card:hover {
|
||||
transform: translateY(-6px);
|
||||
box-shadow: 0 16px 40px rgba(34,80,34,.14);
|
||||
border-color: #c8e6c9;
|
||||
}
|
||||
|
||||
/* Image */
|
||||
.card-img-wrap {
|
||||
height: 200px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
background: linear-gradient(135deg, #a8d5a2, #2e7d32);
|
||||
}
|
||||
|
||||
.card-img-wrap img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
transition: transform .45s ease;
|
||||
}
|
||||
|
||||
.artikel-card:hover .card-img-wrap img {
|
||||
transform: scale(1.07);
|
||||
}
|
||||
|
||||
.card-img-overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(to top, rgba(15,40,15,.45) 0%, transparent 55%);
|
||||
}
|
||||
|
||||
.card-placeholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.card-placeholder span {
|
||||
font-size: 4rem;
|
||||
filter: drop-shadow(0 4px 8px rgba(0,0,0,.15));
|
||||
}
|
||||
|
||||
/* Body */
|
||||
.card-body {
|
||||
padding: 20px 22px 22px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Tags */
|
||||
.card-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.card-tag {
|
||||
padding: 3px 10px;
|
||||
background: #e8f5e9;
|
||||
color: #2e7d32;
|
||||
border: 1px solid #c8e6c9;
|
||||
border-radius: 100px;
|
||||
font-size: 10.5px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .4px;
|
||||
}
|
||||
|
||||
/* Title */
|
||||
.card-title {
|
||||
font-family: 'Lora', serif;
|
||||
font-weight: 700;
|
||||
font-size: 1rem;
|
||||
color: #1a2e1a;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 10px;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
transition: color .2s;
|
||||
}
|
||||
|
||||
.artikel-card:hover .card-title {
|
||||
color: #2e7d32;
|
||||
}
|
||||
|
||||
/* Excerpt */
|
||||
.card-excerpt {
|
||||
font-size: 12.5px;
|
||||
color: #6a826a;
|
||||
line-height: 1.75;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
flex: 1;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
.card-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-top: 14px;
|
||||
border-top: 1px solid #f0f7f0;
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.card-date {
|
||||
font-size: 11.5px;
|
||||
color: #9eb89e;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.card-cta {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
color: #2e7d32;
|
||||
padding: 6px 14px;
|
||||
background: #e8f5e9;
|
||||
border-radius: 100px;
|
||||
transition: background .2s, color .2s;
|
||||
}
|
||||
|
||||
.artikel-card:hover .card-cta {
|
||||
background: #2e7d32;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* ── Empty State ── */
|
||||
.empty-state {
|
||||
background: #fff;
|
||||
border-radius: 24px;
|
||||
box-shadow: 0 4px 24px rgba(34,80,34,.08);
|
||||
padding: 80px 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.empty-state .empty-icon {
|
||||
font-size: 4rem;
|
||||
display: block;
|
||||
margin-bottom: 16px;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
.empty-state h3 {
|
||||
font-family: 'Lora', serif;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 700;
|
||||
color: #1a2e1a;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.empty-state p {
|
||||
font-size: 13px;
|
||||
color: #9eb89e;
|
||||
}
|
||||
|
||||
/* ── Pagination ── */
|
||||
.pagination-wrap {
|
||||
margin-top: 36px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* ── No result (search) ── */
|
||||
.no-result-msg {
|
||||
display: none;
|
||||
text-align: center;
|
||||
padding: 48px 24px;
|
||||
color: #9eb89e;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.no-result-msg .nr-icon {
|
||||
font-size: 3rem;
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
opacity: .5;
|
||||
}
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
|
||||
<!-- Search & Filter -->
|
||||
<div class="bg-white rounded-2xl shadow-lg p-6 mb-6">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="flex-1 relative">
|
||||
<span class="absolute left-4 top-3 text-gray-400">🔍</span>
|
||||
<input type="text" id="search-artikel" placeholder="Cari artikel budidaya..."
|
||||
class="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-xl text-sm focus:ring-2 focus:ring-green-500 focus:border-transparent">
|
||||
<div class="budidaya-page">
|
||||
|
||||
{{-- ── Search Bar ── --}}
|
||||
<div class="search-wrap">
|
||||
<div class="search-inner">
|
||||
<span class="search-icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001q.044.06.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1 1 0 0 0-.115-.099zm-5.242 1.656a5.5 5.5 0 1 1 0-11 5.5 5.5 0 0 1 0 11"/>
|
||||
</svg>
|
||||
</span>
|
||||
<input
|
||||
type="text"
|
||||
id="search-artikel"
|
||||
class="search-input"
|
||||
placeholder="Cari artikel budidaya...">
|
||||
</div>
|
||||
<div class="search-badge">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M8 16s6-5.686 6-10A6 6 0 0 0 2 6c0 4.314 6 10 6 10m0-7a3 3 0 1 1 0-6 3 3 0 0 1 0 6"/>
|
||||
</svg>
|
||||
{{ $artikels->total() }} Artikel
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Grid Artikel -->
|
||||
{{-- ── Grid Artikel ── --}}
|
||||
@if($artikels->count() > 0)
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6" id="artikel-grid">
|
||||
|
||||
<div class="artikel-grid" id="artikel-grid">
|
||||
@foreach($artikels as $artikel)
|
||||
<a href="{{ route('user.artikel.budidaya.detail', $artikel->slug) }}"
|
||||
class="artikel-card bg-white rounded-2xl shadow-lg overflow-hidden hover:shadow-xl transition-all hover:-translate-y-1 group">
|
||||
<!-- Gambar -->
|
||||
<div class="h-48 bg-gradient-to-br from-green-400 to-green-600 overflow-hidden relative">
|
||||
<a href="{{ route('user.artikel.budidaya.detail', $artikel->slug) }}" class="artikel-card">
|
||||
|
||||
{{-- Gambar --}}
|
||||
<div class="card-img-wrap">
|
||||
@if($artikel->gambar_utama)
|
||||
<img src="{{ Storage::url($artikel->gambar_utama) }}"
|
||||
class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
|
||||
alt="{{ $artikel->judul }}">
|
||||
<img src="{{ Storage::url($artikel->gambar_utama) }}" alt="{{ $artikel->judul }}">
|
||||
<div class="card-img-overlay"></div>
|
||||
@else
|
||||
<div class="w-full h-full flex items-center justify-center">
|
||||
<span class="text-6xl">🌱</span>
|
||||
<div class="card-placeholder">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" fill="rgba(255,255,255,0.6)" viewBox="0 0 16 16">
|
||||
<path d="M8 16s6-5.686 6-10A6 6 0 0 0 2 6c0 4.314 6 10 6 10m0-7a3 3 0 1 1 0-6 3 3 0 0 1 0 6"/>
|
||||
</svg>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- Konten -->
|
||||
<div class="p-5">
|
||||
<!-- Tags -->
|
||||
{{-- Body --}}
|
||||
<div class="card-body">
|
||||
|
||||
{{-- Tags --}}
|
||||
@if($artikel->tags)
|
||||
<div class="flex flex-wrap gap-1 mb-3">
|
||||
<div class="card-tags">
|
||||
@foreach(array_slice($artikel->tags, 0, 2) as $tag)
|
||||
<span class="px-2 py-0.5 bg-green-100 text-green-700 text-xs font-semibold rounded-full">{{ $tag }}</span>
|
||||
<span class="card-tag">{{ $tag }}</span>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<h3 class="font-bold text-gray-800 mb-2 group-hover:text-green-600 transition-colors line-clamp-2">
|
||||
{{ $artikel->judul }}
|
||||
</h3>
|
||||
{{-- Judul --}}
|
||||
<h3 class="card-title">{{ $artikel->judul }}</h3>
|
||||
|
||||
{{-- Excerpt --}}
|
||||
@if($artikel->deskripsi_singkat)
|
||||
<p class="text-xs text-gray-500 leading-relaxed line-clamp-3 mb-4">{{ $artikel->deskripsi_singkat }}</p>
|
||||
<p class="card-excerpt">{{ $artikel->deskripsi_singkat }}</p>
|
||||
@endif
|
||||
|
||||
<div class="flex items-center justify-between pt-3 border-t border-gray-100">
|
||||
<span class="text-xs text-gray-400">{{ $artikel->published_at?->format('d M Y') ?? '-' }}</span>
|
||||
<span class="text-xs font-semibold text-green-600 group-hover:underline">Baca Selengkapnya →</span>
|
||||
{{-- Footer --}}
|
||||
<div class="card-footer">
|
||||
<span class="card-date">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4z"/>
|
||||
</svg>
|
||||
{{ $artikel->published_at?->format('d M Y') ?? '-' }}
|
||||
</span>
|
||||
<span class="card-cta">Baca →</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<!-- Pagination -->
|
||||
<div class="mt-8">{{ $artikels->links() }}</div>
|
||||
{{-- No result pesan --}}
|
||||
<div id="no-result" class="no-result-msg">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="#9eb89e" viewBox="0 0 16 16" style="margin:0 auto 10px;display:block;opacity:.5">
|
||||
<path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001q.044.06.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1 1 0 0 0-.115-.099zm-5.242 1.656a5.5 5.5 0 1 1 0-11 5.5 5.5 0 0 1 0 11"/>
|
||||
</svg>
|
||||
Artikel tidak ditemukan
|
||||
</div>
|
||||
|
||||
{{-- Pagination --}}
|
||||
<div class="pagination-wrap">
|
||||
{{ $artikels->links() }}
|
||||
</div>
|
||||
|
||||
@else
|
||||
<div class="bg-white rounded-2xl shadow-lg p-16 text-center text-gray-400">
|
||||
<span class="text-6xl block mb-4">🌱</span>
|
||||
<p class="text-xl font-semibold mb-2">Belum ada artikel budidaya</p>
|
||||
<p class="text-sm">Artikel akan segera tersedia</p>
|
||||
<div class="empty-state">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="56" height="56" fill="#9eb89e" viewBox="0 0 16 16" style="margin:0 auto 16px;display:block;opacity:.5">
|
||||
<path d="M8 16s6-5.686 6-10A6 6 0 0 0 2 6c0 4.314 6 10 6 10m0-7a3 3 0 1 1 0-6 3 3 0 0 1 0 6"/>
|
||||
</svg>
|
||||
<h3>Belum ada artikel budidaya</h3>
|
||||
<p>Artikel akan segera tersedia</p>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
document.getElementById('search-artikel').addEventListener('input', function () {
|
||||
const keyword = this.value.toLowerCase();
|
||||
document.querySelectorAll('.artikel-card').forEach(card => {
|
||||
const judul = card.querySelector('h3').textContent.toLowerCase();
|
||||
card.style.display = judul.includes(keyword) ? '' : 'none';
|
||||
const cards = document.querySelectorAll('.artikel-card');
|
||||
let visible = 0;
|
||||
|
||||
cards.forEach(card => {
|
||||
const judul = card.querySelector('.card-title').textContent.toLowerCase();
|
||||
const show = judul.includes(keyword);
|
||||
card.style.display = show ? '' : 'none';
|
||||
if (show) visible++;
|
||||
});
|
||||
|
||||
const noResult = document.getElementById('no-result');
|
||||
if (noResult) noResult.style.display = visible === 0 ? 'block' : 'none';
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
|
@ -1,111 +1,617 @@
|
|||
@extends('layouts.user-app')
|
||||
|
||||
@section('page-title', '🌱 Artikel Budidaya')
|
||||
@section('page-subtitle', '{{ $artikel->judul }}')
|
||||
@section('page-title', 'Artikel Budidaya')
|
||||
@section('page-subtitle', $artikel->judul)
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Lora:ital,wght@0,400;0,600;0,700;1,400&family=DM+Sans:wght@300;400;500;600&display=swap');
|
||||
|
||||
.budidaya-wrap {
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
}
|
||||
|
||||
/* ── Hero Card ── */
|
||||
.hero-card {
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
box-shadow: 0 4px 24px rgba(34,80,34,.08);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.hero-img-wrap {
|
||||
position: relative;
|
||||
height: 320px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hero-img-wrap img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
transition: transform .6s ease;
|
||||
}
|
||||
|
||||
.hero-card:hover .hero-img-wrap img {
|
||||
transform: scale(1.03);
|
||||
}
|
||||
|
||||
.hero-img-overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(to top, rgba(15,40,15,.55) 0%, transparent 55%);
|
||||
}
|
||||
|
||||
.hero-placeholder {
|
||||
width: 100%;
|
||||
height: 280px;
|
||||
background: linear-gradient(135deg, #a8d5a2 0%, #3a8f4a 60%, #1d5c2a 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.hero-placeholder span {
|
||||
font-size: 5rem;
|
||||
filter: drop-shadow(0 4px 12px rgba(0,0,0,.2));
|
||||
}
|
||||
|
||||
/* ── Tag Pills ── */
|
||||
.tag-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 4px 14px;
|
||||
background: #e8f5e9;
|
||||
color: #2e7d32;
|
||||
border: 1.5px solid #a5d6a7;
|
||||
border-radius: 100px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
letter-spacing: .4px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/* ── Article Title ── */
|
||||
.article-title {
|
||||
font-family: 'Lora', serif;
|
||||
font-size: 1.65rem;
|
||||
font-weight: 700;
|
||||
color: #1a2e1a;
|
||||
line-height: 1.35;
|
||||
letter-spacing: -.3px;
|
||||
}
|
||||
|
||||
.article-meta span {
|
||||
font-size: 12px;
|
||||
color: #8a9e8a;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.article-excerpt {
|
||||
background: linear-gradient(135deg, #f1f8f1 0%, #e8f5e9 100%);
|
||||
border-left: 4px solid #4caf50;
|
||||
border-radius: 0 12px 12px 0;
|
||||
padding: 16px 20px;
|
||||
color: #3d5c3d;
|
||||
font-style: italic;
|
||||
font-size: 13.5px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
/* ── Accordion Section ── */
|
||||
.section-card {
|
||||
background: #fff;
|
||||
border-radius: 24px;
|
||||
box-shadow: 0 4px 24px rgba(34,80,34,.08);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
padding: 22px 28px;
|
||||
border-bottom: 1px solid #f0f5f0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.section-header-icon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
background: #e8f5e9;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 16px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.section-header h3 {
|
||||
font-family: 'Lora', serif;
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
color: #1a2e1a;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Accordion Item */
|
||||
.accordion-item {
|
||||
border-bottom: 1px solid #f3f7f3;
|
||||
transition: background .2s;
|
||||
}
|
||||
|
||||
.accordion-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.accordion-trigger {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 18px 28px;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
gap: 14px;
|
||||
transition: background .2s;
|
||||
}
|
||||
|
||||
.accordion-trigger:hover {
|
||||
background: #f7fbf7;
|
||||
}
|
||||
|
||||
.accordion-trigger:hover .acc-num {
|
||||
background: #2e7d32;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.acc-num {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
background: #e8f5e9;
|
||||
color: #2e7d32;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
transition: background .2s, color .2s;
|
||||
}
|
||||
|
||||
.acc-title {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
color: #1a2e1a;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.acc-arrow {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
color: #8a9e8a;
|
||||
flex-shrink: 0;
|
||||
transition: transform .3s ease;
|
||||
}
|
||||
|
||||
.accordion-body {
|
||||
padding: 0 28px 24px 74px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.accordion-body.open {
|
||||
display: block;
|
||||
animation: fadeSlideIn .25s ease;
|
||||
}
|
||||
|
||||
@keyframes fadeSlideIn {
|
||||
from { opacity: 0; transform: translateY(-6px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
.accordion-body img {
|
||||
width: 100%;
|
||||
max-height: 260px;
|
||||
object-fit: cover;
|
||||
border-radius: 14px;
|
||||
margin-bottom: 14px;
|
||||
box-shadow: 0 4px 16px rgba(0,0,0,.08);
|
||||
}
|
||||
|
||||
.accordion-body .konten-text {
|
||||
font-size: 13.5px;
|
||||
color: #4a5e4a;
|
||||
line-height: 1.8;
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.acc-empty {
|
||||
font-size: 13px;
|
||||
color: #9e9e9e;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* ── Empty State ── */
|
||||
.empty-state {
|
||||
background: #fff;
|
||||
border-radius: 24px;
|
||||
box-shadow: 0 4px 24px rgba(34,80,34,.08);
|
||||
padding: 64px 24px;
|
||||
text-align: center;
|
||||
color: #9e9e9e;
|
||||
}
|
||||
|
||||
.empty-state .empty-icon {
|
||||
font-size: 3.5rem;
|
||||
display: block;
|
||||
margin-bottom: 12px;
|
||||
opacity: .6;
|
||||
}
|
||||
|
||||
.empty-state p {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ── Sidebar ── */
|
||||
.sidebar-card {
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 4px 24px rgba(34,80,34,.08);
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.sidebar-card h3 {
|
||||
font-family: 'Lora', serif;
|
||||
font-size: .95rem;
|
||||
font-weight: 600;
|
||||
color: #1a2e1a;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.sidebar-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 9px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 15px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* TOC */
|
||||
.toc-btn {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 8px 10px;
|
||||
border-radius: 10px;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
transition: background .2s;
|
||||
}
|
||||
|
||||
.toc-btn:hover {
|
||||
background: #f1f8f1;
|
||||
}
|
||||
|
||||
.toc-num {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border-radius: 50%;
|
||||
background: #e8f5e9;
|
||||
color: #2e7d32;
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
transition: background .2s, color .2s;
|
||||
}
|
||||
|
||||
.toc-btn:hover .toc-num {
|
||||
background: #4caf50;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.toc-label {
|
||||
font-size: 12.5px;
|
||||
color: #4a5e4a;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.toc-btn:hover .toc-label {
|
||||
color: #2e7d32;
|
||||
}
|
||||
|
||||
/* Info rows */
|
||||
.info-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #f3f7f3;
|
||||
font-size: 12.5px;
|
||||
}
|
||||
|
||||
.info-row:last-of-type {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.info-row .lbl { color: #8a9e8a; }
|
||||
.info-row .val { font-weight: 600; color: #1a2e1a; }
|
||||
.info-row .val.green { color: #2e7d32; }
|
||||
.info-row .val.blue { color: #1565c0; }
|
||||
|
||||
/* PDF Button */
|
||||
.btn-pdf {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
padding: 12px 20px;
|
||||
background: linear-gradient(135deg, #e53935, #b71c1c);
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
border-radius: 12px;
|
||||
text-decoration: none;
|
||||
margin-top: 14px;
|
||||
transition: opacity .2s, transform .15s;
|
||||
box-shadow: 0 4px 12px rgba(183,28,28,.25);
|
||||
}
|
||||
|
||||
.btn-pdf:hover {
|
||||
opacity: .9;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
/* Nav Buttons */
|
||||
.btn-nav {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
padding: 12px 20px;
|
||||
border: 2px solid #e0ece0;
|
||||
color: #3d5c3d;
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
border-radius: 12px;
|
||||
text-decoration: none;
|
||||
transition: background .2s, border-color .2s, transform .15s;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.btn-nav:hover {
|
||||
background: #f1f8f1;
|
||||
border-color: #a5d6a7;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
/* Sticky sidebar on desktop */
|
||||
@media (min-width: 1024px) {
|
||||
.sidebar-sticky {
|
||||
position: sticky;
|
||||
top: 24px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
<div class="budidaya-wrap grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
|
||||
<!-- Konten Utama -->
|
||||
{{-- ══════════════════════════════════
|
||||
KONTEN UTAMA
|
||||
══════════════════════════════════ --}}
|
||||
<div class="lg:col-span-2 space-y-6">
|
||||
<div class="bg-white rounded-2xl shadow-lg overflow-hidden">
|
||||
<!-- Gambar -->
|
||||
|
||||
{{-- Header Artikel --}}
|
||||
<div class="hero-card">
|
||||
|
||||
{{-- Gambar --}}
|
||||
@if($artikel->gambar_utama)
|
||||
<img src="{{ Storage::url($artikel->gambar_utama) }}" class="w-full h-64 object-cover" alt="{{ $artikel->judul }}">
|
||||
<div class="hero-img-wrap">
|
||||
<img src="{{ Storage::url($artikel->gambar_utama) }}" alt="{{ $artikel->judul }}">
|
||||
<div class="hero-img-overlay"></div>
|
||||
</div>
|
||||
@else
|
||||
<div class="w-full h-48 bg-gradient-to-br from-green-400 to-green-600 flex items-center justify-center">
|
||||
<span class="text-7xl">🌱</span>
|
||||
<div class="hero-placeholder">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80" fill="rgba(255,255,255,0.7)" viewBox="0 0 16 16">
|
||||
<path d="M8 16s6-5.686 6-10A6 6 0 0 0 2 6c0 4.314 6 10 6 10m0-7a3 3 0 1 1 0-6 3 3 0 0 1 0 6"/>
|
||||
</svg>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="p-8">
|
||||
<!-- Tags -->
|
||||
{{-- Tags --}}
|
||||
@if($artikel->tags)
|
||||
<div class="flex flex-wrap gap-2 mb-4">
|
||||
@foreach($artikel->tags as $tag)
|
||||
<span class="px-3 py-1 bg-green-100 text-green-700 text-xs font-bold rounded-full">{{ $tag }}</span>
|
||||
<span class="tag-pill">{{ $tag }}</span>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<h1 class="text-2xl font-bold text-gray-800 mb-2">{{ $artikel->judul }}</h1>
|
||||
{{-- Judul --}}
|
||||
<h1 class="article-title mb-3">{{ $artikel->judul }}</h1>
|
||||
|
||||
<div class="flex items-center gap-4 text-xs text-gray-400 mb-6 pb-6 border-b border-gray-100">
|
||||
<span>📅 {{ $artikel->published_at?->format('d M Y') ?? '-' }}</span>
|
||||
@if($artikel->author)
|
||||
<span>✍️ {{ $artikel->author->nama }}</span>
|
||||
@endif
|
||||
{{-- Meta --}}
|
||||
<div class="article-meta flex items-center gap-5 mb-5">
|
||||
<span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4z"/>
|
||||
</svg>
|
||||
{{ $artikel->published_at?->format('d M Y') ?? '-' }}
|
||||
</span>
|
||||
<span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M1 2.828c.885-.37 2.154-.769 3.388-.893 1.33-.134 2.458.063 3.112.752v9.746c-.935-.53-2.12-.603-3.213-.493-1.18.12-2.37.461-3.287.811zm7.5-.141c.654-.689 1.782-.886 3.112-.752 1.234.124 2.503.523 3.388.893v9.923c-.918-.35-2.107-.692-3.287-.81-1.094-.111-2.278-.039-3.213.492zM8 1.783C7.015.936 5.587.81 4.287.94c-1.514.153-3.042.672-3.994 1.105A.5.5 0 0 0 0 2.5v11a.5.5 0 0 0 .707.455c.882-.4 2.303-.881 3.68-1.02 1.409-.142 2.59.087 3.223.877a.5.5 0 0 0 .78 0c.633-.79 1.814-1.019 3.222-.877 1.378.139 2.8.62 3.681 1.02A.5.5 0 0 0 16 13.5v-11a.5.5 0 0 0-.293-.455c-.952-.433-2.48-.952-3.994-1.105C10.413.809 8.985.936 8 1.783"/>
|
||||
</svg>
|
||||
{{ $artikel->subBab->count() }} sub-bab
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{{-- Deskripsi --}}
|
||||
@if($artikel->deskripsi_singkat)
|
||||
<p class="text-gray-600 leading-relaxed mb-6 bg-green-50 rounded-xl p-4 italic border-l-4 border-green-400">
|
||||
{{ $artikel->deskripsi_singkat }}
|
||||
</p>
|
||||
<p class="article-excerpt">{{ $artikel->deskripsi_singkat }}</p>
|
||||
@endif
|
||||
|
||||
<div class="prose max-w-none text-gray-700 leading-relaxed text-sm">
|
||||
{!! nl2br(e($artikel->konten)) !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Galeri -->
|
||||
@if($artikel->galeri_gambar && count($artikel->galeri_gambar) > 0)
|
||||
<div class="bg-white rounded-2xl shadow-lg p-6">
|
||||
<h3 class="font-bold text-gray-800 mb-4 flex items-center">
|
||||
<span class="w-8 h-8 bg-green-100 rounded-lg flex items-center justify-center mr-2 text-sm">🖼️</span>
|
||||
Galeri Foto
|
||||
</h3>
|
||||
<div class="grid grid-cols-2 md:grid-cols-3 gap-3">
|
||||
@foreach($artikel->galeri_gambar as $foto)
|
||||
<img src="{{ Storage::url($foto) }}" class="w-full h-32 object-cover rounded-xl hover:opacity-90 transition cursor-pointer" alt="Galeri">
|
||||
{{-- Sub-bab Accordion --}}
|
||||
@if($artikel->subBab->count() > 0)
|
||||
<div class="section-card">
|
||||
|
||||
<div class="section-header">
|
||||
<div class="section-header-icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#2e7d32" viewBox="0 0 16 16">
|
||||
<path d="M5 10.5a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5m0-2a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5m0-2a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5m0-2a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5"/>
|
||||
<path d="M3 0h10a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2m0 1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3>Isi Artikel</h3>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@foreach($artikel->subBab as $index => $sub)
|
||||
<div class="accordion-item">
|
||||
|
||||
{{-- Trigger --}}
|
||||
<button type="button" onclick="toggleAccordion({{ $index }})" class="accordion-trigger">
|
||||
<span class="acc-num">{{ $index + 1 }}</span>
|
||||
<span class="acc-title">{{ $sub->judul_sub }}</span>
|
||||
<svg id="arrow-{{ $index }}" class="acc-arrow" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
{{-- Body --}}
|
||||
<div id="accordion-{{ $index }}" class="accordion-body">
|
||||
@if($sub->gambar)
|
||||
<img src="{{ Storage::url($sub->gambar) }}" alt="{{ $sub->judul_sub }}">
|
||||
@endif
|
||||
@if($sub->konten)
|
||||
<div class="konten-text">{{ $sub->konten }}</div>
|
||||
@else
|
||||
<p class="acc-empty">Konten belum tersedia.</p>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<div class="empty-state">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="#9e9e9e" viewBox="0 0 16 16" style="margin:0 auto 12px;display:block;opacity:.6">
|
||||
<path d="M0 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v.217l7 4.2 7-4.2V4a1 1 0 0 0-1-1zm13 2.383-4.708 2.825L15 11.105zm-.034 6.876-5.64-3.471L8 9.583l-1.326-.795-5.64 3.47A1 1 0 0 0 2 13h12a1 1 0 0 0 .966-.741M1 11.105l4.708-2.897L1 5.383z"/>
|
||||
</svg>
|
||||
<p>Belum ada sub-bab</p>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Sidebar -->
|
||||
<div class="space-y-6">
|
||||
<!-- Info Artikel -->
|
||||
<div class="bg-white rounded-2xl shadow-lg p-6">
|
||||
<h3 class="font-bold text-gray-800 mb-4 flex items-center">
|
||||
<span class="w-8 h-8 bg-blue-100 rounded-lg flex items-center justify-center mr-2 text-sm">ℹ️</span>
|
||||
{{-- ══════════════════════════════════
|
||||
SIDEBAR
|
||||
══════════════════════════════════ --}}
|
||||
<div class="space-y-5 sidebar-sticky">
|
||||
|
||||
{{-- Info Artikel --}}
|
||||
<div class="sidebar-card">
|
||||
<h3>
|
||||
<span class="sidebar-icon" style="background:#e3f2fd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" fill="#1565c0" viewBox="0 0 16 16">
|
||||
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/>
|
||||
<path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0"/>
|
||||
</svg>
|
||||
</span>
|
||||
Info Artikel
|
||||
</h3>
|
||||
<div class="space-y-3">
|
||||
<div class="flex justify-between py-2 border-b border-gray-100">
|
||||
<span class="text-xs text-gray-500">Kategori</span>
|
||||
<span class="text-xs font-bold text-green-600">Budidaya</span>
|
||||
|
||||
<div class="info-row">
|
||||
<span class="lbl">Kategori</span>
|
||||
<span class="val green">Budidaya</span>
|
||||
</div>
|
||||
<div class="flex justify-between py-2 border-b border-gray-100">
|
||||
<span class="text-xs text-gray-500">Tanggal</span>
|
||||
<span class="text-xs font-semibold text-gray-800">{{ $artikel->published_at?->format('d M Y') ?? '-' }}</span>
|
||||
</div>
|
||||
@if($artikel->file_pdf)
|
||||
<div class="pt-2">
|
||||
<a href="{{ Storage::url($artikel->file_pdf) }}" target="_blank"
|
||||
class="w-full flex items-center justify-center gap-2 px-4 py-3 bg-red-500 text-white font-bold rounded-xl hover:bg-red-600 transition text-sm">
|
||||
📄 Download PDF
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
<div class="info-row">
|
||||
<span class="lbl">Tanggal</span>
|
||||
<span class="val">{{ $artikel->published_at?->format('d M Y') ?? '-' }}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="lbl">Sub-bab</span>
|
||||
<span class="val blue">{{ $artikel->subBab->count() }} sub-bab</span>
|
||||
</div>
|
||||
|
||||
<!-- Tombol Aksi -->
|
||||
<div class="bg-white rounded-2xl shadow-lg p-6 space-y-3">
|
||||
<a href="{{ route('user.artikel.budidaya') }}"
|
||||
class="w-full flex items-center justify-center gap-2 px-4 py-3 border-2 border-gray-200 text-gray-700 font-semibold rounded-xl hover:bg-gray-50 transition text-sm">
|
||||
← Kembali ke Daftar
|
||||
@if($artikel->file_pdf)
|
||||
<a href="{{ Storage::url($artikel->file_pdf) }}" target="_blank" class="btn-pdf">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M14 14V4.5L9.5 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2M9.5 3A1.5 1.5 0 0 0 11 4.5h2V14a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.5z"/>
|
||||
<path d="M4.603 14.087a.8.8 0 0 1-.438-.42c-.195-.388-.13-.776.08-1.102.198-.307.526-.568.897-.787a7.7 7.7 0 0 1 1.482-.645 20 20 0 0 0 1.062-2.227 7.3 7.3 0 0 1-.43-1.295c-.086-.4-.119-.796-.046-1.136.075-.354.274-.672.65-.823.192-.077.4-.12.602-.077a.7.7 0 0 1 .477.365c.088.164.12.356.127.538.007.188-.012.396-.047.614-.084.51-.27 1.134-.52 1.794a11 11 0 0 0 .98 1.686 5.8 5.8 0 0 1 1.334.05c.364.066.734.195.96.465.12.144.193.32.2.518.007.192-.047.382-.138.563a1.04 1.04 0 0 1-.354.416.86.86 0 0 1-.51.138c-.331-.014-.654-.196-.933-.417a5.7 5.7 0 0 1-.911-.95 11.7 11.7 0 0 0-1.997.406 11.3 11.3 0 0 1-1.02 1.51c-.292.35-.609.656-.927.787a.8.8 0 0 1-.58.029"/>
|
||||
</svg>
|
||||
Download PDF
|
||||
</a>
|
||||
<a href="{{ route('user.dashboard') }}"
|
||||
class="w-full flex items-center justify-center gap-2 px-4 py-3 border-2 border-gray-200 text-gray-700 font-semibold rounded-xl hover:bg-gray-50 transition text-sm">
|
||||
🏠 Dashboard
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Navigasi --}}
|
||||
<div class="sidebar-card space-y-3">
|
||||
<a href="{{ route('user.artikel.budidaya') }}" class="btn-nav">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8"/>
|
||||
</svg>
|
||||
Kembali ke Daftar
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
function toggleAccordion(index) {
|
||||
const content = document.getElementById(`accordion-${index}`);
|
||||
const arrow = document.getElementById(`arrow-${index}`);
|
||||
|
||||
if (content.classList.contains('open')) {
|
||||
content.classList.remove('open');
|
||||
arrow.style.transform = 'rotate(0deg)';
|
||||
} else {
|
||||
content.classList.add('open');
|
||||
arrow.style.transform = 'rotate(180deg)';
|
||||
}
|
||||
}
|
||||
|
||||
function bukaAccordion(index) {
|
||||
const content = document.getElementById(`accordion-${index}`);
|
||||
const arrow = document.getElementById(`arrow-${index}`);
|
||||
|
||||
content.classList.add('open');
|
||||
arrow.style.transform = 'rotate(180deg)';
|
||||
|
||||
// Scroll ke accordion
|
||||
content.closest('.accordion-item').scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
}
|
||||
</script>
|
||||
@endpush
|
||||
|
|
@ -1,142 +1,550 @@
|
|||
@extends('layouts.user-app')
|
||||
|
||||
@section('page-title', '🦠 Artikel Hama & Penyakit')
|
||||
@section('page-subtitle', '{{ $artikel->judul }}')
|
||||
@section('page-title', 'Artikel Hama & Penyakit')
|
||||
@section('page-subtitle', $artikel->judul)
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Lora:ital,wght@0,400;0,600;0,700;1,400&family=DM+Sans:wght@300;400;500;600&display=swap');
|
||||
|
||||
.detail-hp { font-family: 'DM Sans', sans-serif; }
|
||||
|
||||
/* ── Hero Card ── */
|
||||
.hero-card {
|
||||
background: #fff;
|
||||
border-radius: 24px;
|
||||
box-shadow: 0 4px 24px rgba(0,0,0,.08);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hero-img-wrap {
|
||||
position: relative;
|
||||
height: 320px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hero-img-wrap img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
transition: transform .6s ease;
|
||||
}
|
||||
|
||||
.hero-card:hover .hero-img-wrap img { transform: scale(1.03); }
|
||||
|
||||
.hero-img-overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(to top, rgba(20,5,0,.5) 0%, transparent 55%);
|
||||
}
|
||||
|
||||
.hero-placeholder {
|
||||
width: 100%;
|
||||
height: 280px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.hero-placeholder span {
|
||||
font-size: 5rem;
|
||||
filter: drop-shadow(0 4px 12px rgba(0,0,0,.2));
|
||||
}
|
||||
|
||||
/* ── Badges & Tags ── */
|
||||
.jenis-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
padding: 5px 14px;
|
||||
border-radius: 100px;
|
||||
font-size: 11.5px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .4px;
|
||||
}
|
||||
|
||||
.badge-hama { background: #fff7ed; color: #c2410c; border: 1.5px solid #fdba74; }
|
||||
.badge-penyakit { background: #fef2f2; color: #b91c1c; border: 1.5px solid #fca5a5; }
|
||||
|
||||
.tag-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 4px 12px;
|
||||
border-radius: 100px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
background: #f3f4f6;
|
||||
color: #374151;
|
||||
border: 1.5px solid #e5e7eb;
|
||||
}
|
||||
|
||||
/* ── Article Title ── */
|
||||
.article-title {
|
||||
font-family: 'Lora', serif;
|
||||
font-size: 1.65rem;
|
||||
font-weight: 700;
|
||||
color: #1a0a00;
|
||||
line-height: 1.35;
|
||||
letter-spacing: -.3px;
|
||||
}
|
||||
|
||||
.article-meta span {
|
||||
font-size: 12px;
|
||||
color: #9ca3af;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
/* Excerpt */
|
||||
.article-excerpt {
|
||||
border-radius: 0 12px 12px 0;
|
||||
padding: 16px 20px;
|
||||
font-style: italic;
|
||||
font-size: 13.5px;
|
||||
line-height: 1.75;
|
||||
border-left: 4px solid;
|
||||
}
|
||||
|
||||
.excerpt-hama { background: linear-gradient(135deg,#fff7ed,#ffedd5); border-color: #f97316; color: #7c2d12; }
|
||||
.excerpt-penyakit { background: linear-gradient(135deg,#fef2f2,#fee2e2); border-color: #ef4444; color: #7f1d1d; }
|
||||
|
||||
/* Main content */
|
||||
.konten-text {
|
||||
font-size: 14px;
|
||||
color: #374151;
|
||||
line-height: 1.85;
|
||||
}
|
||||
|
||||
/* ── Info Teknis Grid ── */
|
||||
.teknis-section {
|
||||
border-top: 1px solid #f3f4f6;
|
||||
padding-top: 28px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.teknis-title {
|
||||
font-family: 'Lora', serif;
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
color: #1a0a00;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.teknis-icon {
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 16px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.teknis-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) { .teknis-grid { grid-template-columns: repeat(2,1fr); } }
|
||||
|
||||
.teknis-card {
|
||||
border-radius: 14px;
|
||||
padding: 16px 18px;
|
||||
border: 1.5px solid;
|
||||
}
|
||||
|
||||
.teknis-card h4 {
|
||||
font-weight: 700;
|
||||
font-size: 12.5px;
|
||||
margin-bottom: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.teknis-card p {
|
||||
font-size: 12.5px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.tc-yellow { background: #fefce8; border-color: #fde68a; }
|
||||
.tc-yellow h4 { color: #92400e; }
|
||||
.tc-yellow p { color: #78350f; }
|
||||
|
||||
.tc-blue { background: #eff6ff; border-color: #bfdbfe; }
|
||||
.tc-blue h4 { color: #1e40af; }
|
||||
.tc-blue p { color: #1e3a8a; }
|
||||
|
||||
.tc-green { background: #f0fdf4; border-color: #bbf7d0; }
|
||||
.tc-green h4 { color: #15803d; }
|
||||
.tc-green p { color: #14532d; }
|
||||
|
||||
.tc-red { background: #fef2f2; border-color: #fecaca; }
|
||||
.tc-red h4 { color: #b91c1c; }
|
||||
.tc-red p { color: #7f1d1d; }
|
||||
|
||||
/* ── Galeri ── */
|
||||
.galeri-card {
|
||||
background: #fff;
|
||||
border-radius: 24px;
|
||||
box-shadow: 0 4px 24px rgba(0,0,0,.07);
|
||||
padding: 24px 28px;
|
||||
}
|
||||
|
||||
.galeri-title {
|
||||
font-family: 'Lora', serif;
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
color: #1a0a00;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.galeri-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) { .galeri-grid { grid-template-columns: repeat(3, 1fr); } }
|
||||
|
||||
.galeri-grid img {
|
||||
width: 100%;
|
||||
height: 130px;
|
||||
object-fit: cover;
|
||||
border-radius: 12px;
|
||||
transition: transform .3s ease, opacity .2s;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,.07);
|
||||
}
|
||||
|
||||
.galeri-grid img:hover { transform: scale(1.03); opacity: .9; }
|
||||
|
||||
/* ── Section Card (generic) ── */
|
||||
.section-card {
|
||||
background: #fff;
|
||||
border-radius: 24px;
|
||||
box-shadow: 0 4px 24px rgba(0,0,0,.07);
|
||||
padding: 24px 28px;
|
||||
}
|
||||
|
||||
/* ── Sidebar ── */
|
||||
.sidebar-card {
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,.07);
|
||||
padding: 22px;
|
||||
}
|
||||
|
||||
.sidebar-card h3 {
|
||||
font-family: 'Lora', serif;
|
||||
font-size: .95rem;
|
||||
font-weight: 600;
|
||||
color: #1a0a00;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.sidebar-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 9px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 15px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #f3f4f6;
|
||||
font-size: 12.5px;
|
||||
}
|
||||
|
||||
.info-row:last-of-type { border-bottom: none; }
|
||||
.info-row .lbl { color: #9ca3af; }
|
||||
.info-row .val { font-weight: 600; color: #111827; }
|
||||
.val-hama { color: #c2410c !important; }
|
||||
.val-penyakit { color: #b91c1c !important; }
|
||||
|
||||
.btn-pdf {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
padding: 12px 20px;
|
||||
background: linear-gradient(135deg,#e53935,#b71c1c);
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
border-radius: 12px;
|
||||
text-decoration: none;
|
||||
margin-top: 14px;
|
||||
transition: opacity .2s, transform .15s;
|
||||
box-shadow: 0 4px 12px rgba(183,28,28,.25);
|
||||
}
|
||||
|
||||
.btn-pdf:hover { opacity: .9; transform: translateY(-1px); }
|
||||
|
||||
.btn-nav {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
padding: 12px 20px;
|
||||
border: 2px solid #e5e7eb;
|
||||
color: #374151;
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
border-radius: 12px;
|
||||
text-decoration: none;
|
||||
background: #fff;
|
||||
transition: background .2s, border-color .2s, transform .15s;
|
||||
}
|
||||
|
||||
.btn-nav:hover {
|
||||
background: #f9fafb;
|
||||
border-color: #d1d5db;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) { .sidebar-sticky { position: sticky; top: 24px; } }
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
<div class="detail-hp grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
|
||||
<!-- Konten Utama -->
|
||||
{{-- ══════════════════════════════
|
||||
KONTEN UTAMA
|
||||
══════════════════════════════ --}}
|
||||
<div class="lg:col-span-2 space-y-6">
|
||||
<div class="bg-white rounded-2xl shadow-lg overflow-hidden">
|
||||
|
||||
{{-- Hero --}}
|
||||
<div class="hero-card">
|
||||
|
||||
@if($artikel->gambar_utama)
|
||||
<img src="{{ Storage::url($artikel->gambar_utama) }}" class="w-full h-64 object-cover" alt="{{ $artikel->judul }}">
|
||||
<div class="hero-img-wrap">
|
||||
<img src="{{ Storage::url($artikel->gambar_utama) }}" alt="{{ $artikel->judul }}">
|
||||
<div class="hero-img-overlay"></div>
|
||||
</div>
|
||||
@else
|
||||
<div class="w-full h-48 flex items-center justify-center {{ $artikel->jenis === 'Hama' ? 'bg-gradient-to-br from-orange-400 to-orange-600' : 'bg-gradient-to-br from-red-400 to-red-600' }}">
|
||||
<span class="text-7xl">{{ $artikel->jenis === 'Hama' ? '🐛' : '🦠' }}</span>
|
||||
<div class="hero-placeholder {{ $artikel->jenis === 'Hama' ? 'bg-gradient-to-br from-orange-300 to-orange-600' : 'bg-gradient-to-br from-red-300 to-red-700' }}">
|
||||
@if($artikel->jenis === 'Hama')
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80" fill="rgba(255,255,255,0.7)" viewBox="0 0 16 16">
|
||||
<path d="M8 3.5a.5.5 0 0 0-1 0V9a.5.5 0 0 0 .252.434l3.5 2a.5.5 0 0 0 .496-.868L8 8.71z"/>
|
||||
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m7-8A7 7 0 1 1 1 8a7 7 0 0 1 14 0"/>
|
||||
</svg>
|
||||
@else
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80" fill="rgba(255,255,255,0.7)" viewBox="0 0 16 16">
|
||||
<path d="M6.5 2a.5.5 0 0 0 0 1h3a.5.5 0 0 0 0-1zM11 7.5a4.002 4.002 0 0 1-3.512 3.96A1 1 0 0 1 7 12.5V14h1a.5.5 0 0 1 0 1H6a.5.5 0 0 1 0-1h.5V12.5a1 1 0 0 1-.988-.04A4.002 4.002 0 0 1 5 7.5H1.5a.5.5 0 0 1 0-1H5a4 4 0 0 1 6 0h3.5a.5.5 0 0 1 0 1z"/>
|
||||
</svg>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="p-8">
|
||||
|
||||
{{-- Badge jenis + tags --}}
|
||||
<div class="flex flex-wrap gap-2 mb-4">
|
||||
<span class="px-3 py-1 text-xs font-bold rounded-full {{ $artikel->jenis === 'Hama' ? 'bg-orange-100 text-orange-700' : 'bg-red-100 text-red-700' }}">
|
||||
{{ $artikel->jenis === 'Hama' ? '🐛' : '🦠' }} {{ $artikel->jenis }}
|
||||
<span class="jenis-badge {{ $artikel->jenis === 'Hama' ? 'badge-hama' : 'badge-penyakit' }}">
|
||||
@if($artikel->jenis === 'Hama')
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M8 3.5a.5.5 0 0 0-1 0V9a.5.5 0 0 0 .252.434l3.5 2a.5.5 0 0 0 .496-.868L8 8.71z"/>
|
||||
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m7-8A7 7 0 1 1 1 8a7 7 0 0 1 14 0"/>
|
||||
</svg>
|
||||
@else
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M6.5 2a.5.5 0 0 0 0 1h3a.5.5 0 0 0 0-1zM11 7.5a4.002 4.002 0 0 1-3.512 3.96A1 1 0 0 1 7 12.5V14h1a.5.5 0 0 1 0 1H6a.5.5 0 0 1 0-1h.5V12.5a1 1 0 0 1-.988-.04A4.002 4.002 0 0 1 5 7.5H1.5a.5.5 0 0 1 0-1H5a4 4 0 0 1 6 0h3.5a.5.5 0 0 1 0 1z"/>
|
||||
</svg>
|
||||
@endif
|
||||
{{ $artikel->jenis }}
|
||||
</span>
|
||||
@if($artikel->tags)
|
||||
@foreach($artikel->tags as $tag)
|
||||
<span class="px-3 py-1 bg-gray-100 text-gray-600 text-xs font-semibold rounded-full">{{ $tag }}</span>
|
||||
<span class="tag-pill">{{ $tag }}</span>
|
||||
@endforeach
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<h1 class="text-2xl font-bold text-gray-800 mb-2">{{ $artikel->judul }}</h1>
|
||||
<div class="flex items-center gap-4 text-xs text-gray-400 mb-6 pb-6 border-b border-gray-100">
|
||||
<span>📅 {{ $artikel->published_at?->format('d M Y') ?? '-' }}</span>
|
||||
{{-- Judul --}}
|
||||
<h1 class="article-title mb-3">{{ $artikel->judul }}</h1>
|
||||
|
||||
{{-- Meta --}}
|
||||
<div class="flex items-center gap-5 mb-6 pb-6 border-b border-gray-100">
|
||||
<span class="article-meta">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4z"/>
|
||||
</svg>
|
||||
{{ $artikel->published_at?->format('d M Y') ?? '-' }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{{-- Excerpt --}}
|
||||
@if($artikel->deskripsi_singkat)
|
||||
<p class="text-gray-600 leading-relaxed mb-6 bg-gray-50 rounded-xl p-4 italic border-l-4 {{ $artikel->jenis === 'Hama' ? 'border-orange-400' : 'border-red-400' }}">
|
||||
<p class="article-excerpt mb-6 {{ $artikel->jenis === 'Hama' ? 'excerpt-hama' : 'excerpt-penyakit' }}">
|
||||
{{ $artikel->deskripsi_singkat }}
|
||||
</p>
|
||||
@endif
|
||||
|
||||
<div class="text-sm text-gray-700 leading-relaxed mb-6">
|
||||
{{-- Konten utama --}}
|
||||
<div class="konten-text mb-6">
|
||||
{!! nl2br(e($artikel->konten)) !!}
|
||||
</div>
|
||||
|
||||
<!-- Info Teknis -->
|
||||
{{-- Info Teknis --}}
|
||||
@if($artikel->gejala_visual || $artikel->cara_identifikasi || $artikel->pencegahan || $artikel->pengendalian)
|
||||
<div class="border-t border-gray-100 pt-6">
|
||||
<h3 class="font-bold text-gray-800 mb-4 flex items-center">
|
||||
<span class="w-8 h-8 bg-red-100 rounded-lg flex items-center justify-center mr-2 text-sm">📋</span>
|
||||
<div class="teknis-section">
|
||||
<h3 class="teknis-title">
|
||||
<span class="teknis-icon" style="background:#fef2f2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#b91c1c" viewBox="0 0 16 16">
|
||||
<path d="M5 10.5a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5m0-2a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5m0-2a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5m0-2a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5"/>
|
||||
<path d="M3 0h10a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2m0 1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1z"/>
|
||||
</svg>
|
||||
</span>
|
||||
Informasi Teknis
|
||||
</h3>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div class="teknis-grid">
|
||||
@if($artikel->gejala_visual)
|
||||
<div class="bg-yellow-50 border border-yellow-100 rounded-xl p-4">
|
||||
<h4 class="font-bold text-yellow-700 text-sm mb-2">👁️ Gejala Visual</h4>
|
||||
<p class="text-xs text-yellow-600 leading-relaxed">{{ $artikel->gejala_visual }}</p>
|
||||
<div class="teknis-card tc-yellow">
|
||||
<h4>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8M1.173 8a13 13 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5s3.879 1.168 5.168 2.457A13 13 0 0 1 14.828 8q-.086.13-.195.288c-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5s-3.879-1.168-5.168-2.457A13 13 0 0 1 1.172 8z"/>
|
||||
<path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5M4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0"/>
|
||||
</svg>
|
||||
Gejala Visual
|
||||
</h4>
|
||||
<p>{{ $artikel->gejala_visual }}</p>
|
||||
</div>
|
||||
@endif
|
||||
@if($artikel->cara_identifikasi)
|
||||
<div class="bg-blue-50 border border-blue-100 rounded-xl p-4">
|
||||
<h4 class="font-bold text-blue-700 text-sm mb-2">🔍 Cara Identifikasi</h4>
|
||||
<p class="text-xs text-blue-600 leading-relaxed">{{ $artikel->cara_identifikasi }}</p>
|
||||
<div class="teknis-card tc-blue">
|
||||
<h4>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001q.044.06.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1 1 0 0 0-.115-.099zm-5.242 1.656a5.5 5.5 0 1 1 0-11 5.5 5.5 0 0 1 0 11"/>
|
||||
</svg>
|
||||
Cara Identifikasi
|
||||
</h4>
|
||||
<p>{{ $artikel->cara_identifikasi }}</p>
|
||||
</div>
|
||||
@endif
|
||||
@if($artikel->pencegahan)
|
||||
<div class="bg-green-50 border border-green-100 rounded-xl p-4">
|
||||
<h4 class="font-bold text-green-700 text-sm mb-2">🛡️ Pencegahan</h4>
|
||||
<p class="text-xs text-green-600 leading-relaxed">{{ $artikel->pencegahan }}</p>
|
||||
<div class="teknis-card tc-green">
|
||||
<h4>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M5.338 1.59a61 61 0 0 0-2.837.856.48.48 0 0 0-.328.39c-.554 4.157.726 7.19 2.253 9.188a10.7 10.7 0 0 0 2.287 2.233c.346.244.652.42.893.533q.18.085.293.118a1 1 0 0 0 .101.025 1 1 0 0 0 .1-.025q.114-.034.294-.118c.24-.113.547-.29.893-.533a10.7 10.7 0 0 0 2.287-2.233c1.527-1.997 2.807-5.031 2.253-9.188a.48.48 0 0 0-.328-.39c-.651-.213-1.75-.56-2.837-.855C9.552 1.29 8.531 1.067 8 1.067c-.53 0-1.552.223-2.662.524zM5.072.56C6.157.265 7.31 0 8 0s1.843.265 2.928.56c1.11.3 2.229.655 2.887.87a1.54 1.54 0 0 1 1.044 1.262c.596 4.477-.787 7.795-2.465 9.99a11.8 11.8 0 0 1-2.517 2.453 7 7 0 0 1-1.048.625c-.28.132-.581.24-.829.24s-.548-.108-.829-.24a7 7 0 0 1-1.048-.625 11.8 11.8 0 0 1-2.517-2.453C1.928 10.487.545 7.169 1.141 2.692A1.54 1.54 0 0 1 2.185 1.43 63 63 0 0 1 5.072.56"/>
|
||||
</svg>
|
||||
Pencegahan
|
||||
</h4>
|
||||
<p>{{ $artikel->pencegahan }}</p>
|
||||
</div>
|
||||
@endif
|
||||
@if($artikel->pengendalian)
|
||||
<div class="bg-red-50 border border-red-100 rounded-xl p-4">
|
||||
<h4 class="font-bold text-red-700 text-sm mb-2">⚗️ Pengendalian</h4>
|
||||
<p class="text-xs text-red-600 leading-relaxed">{{ $artikel->pengendalian }}</p>
|
||||
<div class="teknis-card tc-red">
|
||||
<h4>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M9.405 1.05c-.413-1.4-2.397-1.4-2.81 0l-.1.34a1.464 1.464 0 0 1-2.105.872l-.31-.17c-1.283-.698-2.686.705-1.987 1.987l.169.311c.446.82.023 1.841-.872 2.105l-.34.1c-1.4.413-1.4 2.397 0 2.81l.34.1a1.464 1.464 0 0 1 .872 2.105l-.17.31c-.698 1.283.705 2.686 1.987 1.987l.311-.169a1.464 1.464 0 0 1 2.105.872l.1.34c.413 1.4 2.397 1.4 2.81 0l.1-.34a1.464 1.464 0 0 1 2.105-.872l.31.17c1.283.698 2.686-.705 1.987-1.987l-.169-.311a1.464 1.464 0 0 1 .872-2.105l.34-.1c1.4-.413 1.4-2.397 0-2.81l-.34-.1a1.464 1.464 0 0 1-.872-2.105l.17-.31c.698-1.283-.705-2.686-1.987-1.987l-.311.169a1.464 1.464 0 0 1-2.105-.872zM8 10.93a2.929 2.929 0 1 1 0-5.86 2.929 2.929 0 0 1 0 5.858z"/>
|
||||
</svg>
|
||||
Pengendalian
|
||||
</h4>
|
||||
<p>{{ $artikel->pengendalian }}</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Galeri -->
|
||||
{{-- Galeri --}}
|
||||
@if($artikel->galeri_gambar && count($artikel->galeri_gambar) > 0)
|
||||
<div class="bg-white rounded-2xl shadow-lg p-6">
|
||||
<h3 class="font-bold text-gray-800 mb-4 flex items-center">
|
||||
<span class="w-8 h-8 bg-gray-100 rounded-lg flex items-center justify-center mr-2 text-sm">🖼️</span>
|
||||
<div class="galeri-card">
|
||||
<h3 class="galeri-title">
|
||||
<span class="teknis-icon" style="background:#f3f4f6">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#374151" viewBox="0 0 16 16">
|
||||
<path d="M6.002 5.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0"/>
|
||||
<path d="M1.5 2A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h13a1.5 1.5 0 0 0 1.5-1.5v-9A1.5 1.5 0 0 0 14.5 2zm13 1a.5.5 0 0 1 .5.5v6l-3.775-1.947a.5.5 0 0 0-.577.093l-3.71 3.71-2.66-1.772a.5.5 0 0 0-.63.062L1.002 12v.54L1 12.5v-9a.5.5 0 0 1 .5-.5z"/>
|
||||
</svg>
|
||||
</span>
|
||||
Galeri Foto
|
||||
</h3>
|
||||
<div class="grid grid-cols-2 md:grid-cols-3 gap-3">
|
||||
<div class="galeri-grid">
|
||||
@foreach($artikel->galeri_gambar as $foto)
|
||||
<img src="{{ Storage::url($foto) }}" class="w-full h-32 object-cover rounded-xl hover:opacity-90 transition" alt="Galeri">
|
||||
<img src="{{ Storage::url($foto) }}" alt="Galeri">
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Sidebar -->
|
||||
<div class="space-y-6">
|
||||
<div class="bg-white rounded-2xl shadow-lg p-6">
|
||||
<h3 class="font-bold text-gray-800 mb-4 flex items-center">
|
||||
<span class="w-8 h-8 bg-blue-100 rounded-lg flex items-center justify-center mr-2 text-sm">ℹ️</span>
|
||||
{{-- ══════════════════════════════
|
||||
SIDEBAR
|
||||
══════════════════════════════ --}}
|
||||
<div class="space-y-5 sidebar-sticky">
|
||||
|
||||
{{-- Info Artikel --}}
|
||||
<div class="sidebar-card">
|
||||
<h3>
|
||||
<span class="sidebar-icon" style="background:#eff6ff">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" fill="#1565c0" viewBox="0 0 16 16">
|
||||
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/>
|
||||
<path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0"/>
|
||||
</svg>
|
||||
</span>
|
||||
Info Artikel
|
||||
</h3>
|
||||
<div class="space-y-3">
|
||||
<div class="flex justify-between py-2 border-b border-gray-100">
|
||||
<span class="text-xs text-gray-500">Jenis</span>
|
||||
<span class="text-xs font-bold {{ $artikel->jenis === 'Hama' ? 'text-orange-600' : 'text-red-600' }}">{{ $artikel->jenis }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between py-2 border-b border-gray-100">
|
||||
<span class="text-xs text-gray-500">Tanggal</span>
|
||||
<span class="text-xs font-semibold text-gray-800">{{ $artikel->published_at?->format('d M Y') ?? '-' }}</span>
|
||||
</div>
|
||||
@if($artikel->file_pdf)
|
||||
<div class="pt-2">
|
||||
<a href="{{ Storage::url($artikel->file_pdf) }}" target="_blank"
|
||||
class="w-full flex items-center justify-center gap-2 px-4 py-3 bg-red-500 text-white font-bold rounded-xl hover:bg-red-600 transition text-sm">
|
||||
📄 Download PDF
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="info-row">
|
||||
<span class="lbl">Jenis</span>
|
||||
<span class="val {{ $artikel->jenis === 'Hama' ? 'val-hama' : 'val-penyakit' }}">{{ $artikel->jenis }}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="lbl">Tanggal</span>
|
||||
<span class="val">{{ $artikel->published_at?->format('d M Y') ?? '-' }}</span>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-2xl shadow-lg p-6 space-y-3">
|
||||
<a href="{{ route('user.artikel.hama-penyakit') }}"
|
||||
class="w-full flex items-center justify-center gap-2 px-4 py-3 border-2 border-gray-200 text-gray-700 font-semibold rounded-xl hover:bg-gray-50 transition text-sm">
|
||||
← Kembali ke Daftar
|
||||
@if($artikel->file_pdf)
|
||||
<a href="{{ Storage::url($artikel->file_pdf) }}" target="_blank" class="btn-pdf">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M14 14V4.5L9.5 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2M9.5 3A1.5 1.5 0 0 0 11 4.5h2V14a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.5z"/>
|
||||
<path d="M4.603 14.087a.8.8 0 0 1-.438-.42c-.195-.388-.13-.776.08-1.102.198-.307.526-.568.897-.787a7.7 7.7 0 0 1 1.482-.645 20 20 0 0 0 1.062-2.227 7.3 7.3 0 0 1-.43-1.295c-.086-.4-.119-.796-.046-1.136.075-.354.274-.672.65-.823.192-.077.4-.12.602-.077a.7.7 0 0 1 .477.365c.088.164.12.356.127.538.007.188-.012.396-.047.614-.084.51-.27 1.134-.52 1.794a11 11 0 0 0 .98 1.686 5.8 5.8 0 0 1 1.334.05c.364.066.734.195.96.465.12.144.193.32.2.518.007.192-.047.382-.138.563a1.04 1.04 0 0 1-.354.416.86.86 0 0 1-.51.138c-.331-.014-.654-.196-.933-.417a5.7 5.7 0 0 1-.911-.95 11.7 11.7 0 0 0-1.997.406 11.3 11.3 0 0 1-1.02 1.51c-.292.35-.609.656-.927.787a.8.8 0 0 1-.58.029"/>
|
||||
</svg>
|
||||
Download PDF
|
||||
</a>
|
||||
<a href="{{ route('user.dashboard') }}"
|
||||
class="w-full flex items-center justify-center gap-2 px-4 py-3 border-2 border-gray-200 text-gray-700 font-semibold rounded-xl hover:bg-gray-50 transition text-sm">
|
||||
🏠 Dashboard
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Navigasi --}}
|
||||
<div class="sidebar-card space-y-3">
|
||||
<a href="{{ route('user.artikel.hama-penyakit') }}" class="btn-nav">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8"/>
|
||||
</svg>
|
||||
Kembali ke Daftar
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
|
@ -1,122 +1,390 @@
|
|||
@extends('layouts.user-app')
|
||||
|
||||
@section('page-title', '🦠 Artikel Hama & Penyakit')
|
||||
@section('page-title', 'Artikel Hama & Penyakit')
|
||||
@section('page-subtitle', 'Informasi seputar hama dan penyakit tanaman kopi')
|
||||
|
||||
@section('content')
|
||||
|
||||
<!-- Tab -->
|
||||
<div class="bg-white rounded-2xl shadow-lg p-2 mb-6 flex gap-2">
|
||||
<button onclick="switchTab('hama')" id="tab-hama"
|
||||
class="flex-1 py-3 px-4 rounded-xl font-bold text-sm transition tab-btn active-tab">
|
||||
🐛 Hama ({{ $hama->count() }})
|
||||
</button>
|
||||
<button onclick="switchTab('penyakit')" id="tab-penyakit"
|
||||
class="flex-1 py-3 px-4 rounded-xl font-bold text-sm transition tab-btn">
|
||||
🦠 Penyakit ({{ $penyakit->count() }})
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Hama -->
|
||||
<div id="content-hama">
|
||||
@if($hama->count() > 0)
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
@foreach($hama as $artikel)
|
||||
<a href="{{ route('user.artikel.hama-penyakit.detail', $artikel->slug) }}"
|
||||
class="bg-white rounded-2xl shadow-lg overflow-hidden hover:shadow-xl transition-all hover:-translate-y-1 group">
|
||||
<div class="h-48 bg-gradient-to-br from-orange-400 to-orange-600 overflow-hidden relative">
|
||||
@if($artikel->gambar_utama)
|
||||
<img src="{{ Storage::url($artikel->gambar_utama) }}" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300" alt="{{ $artikel->judul }}">
|
||||
@else
|
||||
<div class="w-full h-full flex items-center justify-center">
|
||||
<span class="text-6xl">🐛</span>
|
||||
</div>
|
||||
@endif
|
||||
<span class="absolute top-3 right-3 px-2 py-1 bg-orange-500 text-white text-xs font-bold rounded-full">Hama</span>
|
||||
</div>
|
||||
<div class="p-5">
|
||||
@if($artikel->tags)
|
||||
<div class="flex flex-wrap gap-1 mb-3">
|
||||
@foreach(array_slice($artikel->tags, 0, 2) as $tag)
|
||||
<span class="px-2 py-0.5 bg-orange-100 text-orange-700 text-xs font-semibold rounded-full">{{ $tag }}</span>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
<h3 class="font-bold text-gray-800 mb-2 group-hover:text-orange-600 transition-colors line-clamp-2">{{ $artikel->judul }}</h3>
|
||||
@if($artikel->deskripsi_singkat)
|
||||
<p class="text-xs text-gray-500 leading-relaxed line-clamp-3 mb-4">{{ $artikel->deskripsi_singkat }}</p>
|
||||
@endif
|
||||
<div class="flex items-center justify-between pt-3 border-t border-gray-100">
|
||||
<span class="text-xs text-gray-400">{{ $artikel->published_at?->format('d M Y') ?? '-' }}</span>
|
||||
<span class="text-xs font-semibold text-orange-600 group-hover:underline">Baca →</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
@else
|
||||
<div class="bg-white rounded-2xl shadow-lg p-16 text-center text-gray-400">
|
||||
<span class="text-6xl block mb-4">🐛</span>
|
||||
<p class="text-xl font-semibold">Belum ada artikel hama</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- Penyakit -->
|
||||
<div id="content-penyakit" class="hidden">
|
||||
@if($penyakit->count() > 0)
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
@foreach($penyakit as $artikel)
|
||||
<a href="{{ route('user.artikel.hama-penyakit.detail', $artikel->slug) }}"
|
||||
class="bg-white rounded-2xl shadow-lg overflow-hidden hover:shadow-xl transition-all hover:-translate-y-1 group">
|
||||
<div class="h-48 bg-gradient-to-br from-red-400 to-red-600 overflow-hidden relative">
|
||||
@if($artikel->gambar_utama)
|
||||
<img src="{{ Storage::url($artikel->gambar_utama) }}" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300" alt="{{ $artikel->judul }}">
|
||||
@else
|
||||
<div class="w-full h-full flex items-center justify-center">
|
||||
<span class="text-6xl">🦠</span>
|
||||
</div>
|
||||
@endif
|
||||
<span class="absolute top-3 right-3 px-2 py-1 bg-red-500 text-white text-xs font-bold rounded-full">Penyakit</span>
|
||||
</div>
|
||||
<div class="p-5">
|
||||
@if($artikel->tags)
|
||||
<div class="flex flex-wrap gap-1 mb-3">
|
||||
@foreach(array_slice($artikel->tags, 0, 2) as $tag)
|
||||
<span class="px-2 py-0.5 bg-red-100 text-red-700 text-xs font-semibold rounded-full">{{ $tag }}</span>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
<h3 class="font-bold text-gray-800 mb-2 group-hover:text-red-600 transition-colors line-clamp-2">{{ $artikel->judul }}</h3>
|
||||
@if($artikel->deskripsi_singkat)
|
||||
<p class="text-xs text-gray-500 leading-relaxed line-clamp-3 mb-4">{{ $artikel->deskripsi_singkat }}</p>
|
||||
@endif
|
||||
<div class="flex items-center justify-between pt-3 border-t border-gray-100">
|
||||
<span class="text-xs text-gray-400">{{ $artikel->published_at?->format('d M Y') ?? '-' }}</span>
|
||||
<span class="text-xs font-semibold text-red-600 group-hover:underline">Baca →</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
@else
|
||||
<div class="bg-white rounded-2xl shadow-lg p-16 text-center text-gray-400">
|
||||
<span class="text-6xl block mb-4">🦠</span>
|
||||
<p class="text-xl font-semibold">Belum ada artikel penyakit</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
.active-tab { background: #16a34a; color: white; }
|
||||
.tab-btn:not(.active-tab) { color: #6b7280; }
|
||||
.tab-btn:not(.active-tab):hover { background: #f3f4f6; }
|
||||
@import url('https://fonts.googleapis.com/css2?family=Lora:ital,wght@0,400;0,600;0,700;1,400&family=DM+Sans:wght@300;400;500;600&display=swap');
|
||||
|
||||
.hp-page { font-family: 'DM Sans', sans-serif; }
|
||||
|
||||
/* ── Tab Switcher ── */
|
||||
.tab-wrap {
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,.07);
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
.tab-btn {
|
||||
flex: 1;
|
||||
padding: 13px 20px;
|
||||
border-radius: 14px;
|
||||
border: none;
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 13.5px;
|
||||
cursor: pointer;
|
||||
transition: background .22s, color .22s, box-shadow .22s, transform .15s;
|
||||
color: #6b7280;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.tab-btn:hover:not(.active-tab) {
|
||||
background: #f9fafb;
|
||||
color: #374151;
|
||||
}
|
||||
|
||||
/* Hama active */
|
||||
#tab-hama.active-tab {
|
||||
background: linear-gradient(135deg, #f97316, #ea580c);
|
||||
color: #fff;
|
||||
box-shadow: 0 6px 20px rgba(234,88,12,.28);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
/* Penyakit active */
|
||||
#tab-penyakit.active-tab {
|
||||
background: linear-gradient(135deg, #ef4444, #b91c1c);
|
||||
color: #fff;
|
||||
box-shadow: 0 6px 20px rgba(185,28,28,.28);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
/* ── Grid ── */
|
||||
.artikel-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) { .artikel-grid { grid-template-columns: repeat(2,1fr); } }
|
||||
@media (min-width: 1024px) { .artikel-grid { grid-template-columns: repeat(3,1fr); } }
|
||||
|
||||
/* ── Card ── */
|
||||
.artikel-card {
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,.07);
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-decoration: none;
|
||||
border: 1.5px solid #f5f5f5;
|
||||
transition: transform .25s ease, box-shadow .25s ease, border-color .25s;
|
||||
}
|
||||
|
||||
.artikel-card.hama:hover { transform: translateY(-6px); box-shadow: 0 16px 40px rgba(234,88,12,.13); border-color: #fed7aa; }
|
||||
.artikel-card.penyakit:hover { transform: translateY(-6px); box-shadow: 0 16px 40px rgba(185,28,28,.13); border-color: #fecaca; }
|
||||
|
||||
/* Image */
|
||||
.card-img-wrap {
|
||||
height: 200px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.card-img-wrap img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
transition: transform .45s ease;
|
||||
}
|
||||
|
||||
.artikel-card:hover .card-img-wrap img { transform: scale(1.07); }
|
||||
|
||||
.card-img-overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(to top, rgba(20,10,0,.45) 0%, transparent 55%);
|
||||
}
|
||||
|
||||
.card-placeholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.card-placeholder span {
|
||||
font-size: 4rem;
|
||||
filter: drop-shadow(0 4px 8px rgba(0,0,0,.15));
|
||||
}
|
||||
|
||||
/* Badge */
|
||||
.card-badge {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
padding: 4px 12px;
|
||||
border-radius: 100px;
|
||||
font-size: 10.5px;
|
||||
font-weight: 700;
|
||||
letter-spacing: .4px;
|
||||
text-transform: uppercase;
|
||||
backdrop-filter: blur(6px);
|
||||
}
|
||||
|
||||
.badge-hama { background: rgba(234,88,12,.85); color: #fff; }
|
||||
.badge-penyakit { background: rgba(185,28,28,.85); color: #fff; }
|
||||
|
||||
/* Body */
|
||||
.card-body {
|
||||
padding: 18px 20px 20px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Tags */
|
||||
.card-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 11px; }
|
||||
|
||||
.card-tag {
|
||||
padding: 3px 10px;
|
||||
border-radius: 100px;
|
||||
font-size: 10.5px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .3px;
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.tag-hama { background: #fff7ed; color: #c2410c; border-color: #fdba74; }
|
||||
.tag-penyakit { background: #fef2f2; color: #b91c1c; border-color: #fca5a5; }
|
||||
|
||||
/* Title */
|
||||
.card-title {
|
||||
font-family: 'Lora', serif;
|
||||
font-weight: 700;
|
||||
font-size: .98rem;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 9px;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
transition: color .2s;
|
||||
}
|
||||
|
||||
.card-title.hama { color: #1c0a00; }
|
||||
.card-title.penyakit { color: #1c0000; }
|
||||
.artikel-card.hama:hover .card-title { color: #c2410c; }
|
||||
.artikel-card.penyakit:hover .card-title { color: #b91c1c; }
|
||||
|
||||
/* Excerpt */
|
||||
.card-excerpt {
|
||||
font-size: 12.5px;
|
||||
color: #6b7280;
|
||||
line-height: 1.75;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
flex: 1;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
.card-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid #f5f5f5;
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.card-date { font-size: 11.5px; color: #9ca3af; }
|
||||
|
||||
.card-cta {
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
padding: 6px 14px;
|
||||
border-radius: 100px;
|
||||
transition: background .2s, color .2s;
|
||||
}
|
||||
|
||||
.cta-hama { color: #c2410c; background: #fff7ed; }
|
||||
.cta-penyakit { color: #b91c1c; background: #fef2f2; }
|
||||
.artikel-card.hama:hover .card-cta { background: #ea580c; color: #fff; }
|
||||
.artikel-card.penyakit:hover .card-cta { background: #ef4444; color: #fff; }
|
||||
|
||||
/* ── Empty State ── */
|
||||
.empty-state {
|
||||
background: #fff;
|
||||
border-radius: 24px;
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,.07);
|
||||
padding: 80px 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.empty-state .empty-icon { font-size: 3.5rem; display: block; margin-bottom: 14px; opacity: .5; }
|
||||
|
||||
.empty-state h3 {
|
||||
font-family: 'Lora', serif;
|
||||
font-size: 1.2rem;
|
||||
font-weight: 700;
|
||||
color: #374151;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.empty-state p { font-size: 13px; color: #9ca3af; }
|
||||
|
||||
/* ── Tab content transition ── */
|
||||
.tab-content { animation: fadeIn .25s ease; }
|
||||
@keyframes fadeIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="hp-page">
|
||||
|
||||
{{-- ── Tab Switcher ── --}}
|
||||
<div class="tab-wrap">
|
||||
<button onclick="switchTab('hama')" id="tab-hama" class="tab-btn active-tab">
|
||||
Hama
|
||||
<span style="opacity:.75;font-weight:400;font-size:12px">({{ $hama->count() }})</span>
|
||||
</button>
|
||||
<button onclick="switchTab('penyakit')" id="tab-penyakit" class="tab-btn">
|
||||
Penyakit
|
||||
<span style="opacity:.75;font-weight:400;font-size:12px">({{ $penyakit->count() }})</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{{-- ── Konten Hama ── --}}
|
||||
<div id="content-hama" class="tab-content">
|
||||
@if($hama->count() > 0)
|
||||
<div class="artikel-grid">
|
||||
@foreach($hama as $artikel)
|
||||
<a href="{{ route('user.artikel.hama-penyakit.detail', $artikel->slug) }}" class="artikel-card hama">
|
||||
|
||||
<div class="card-img-wrap" style="background: linear-gradient(135deg,#fdba74,#ea580c)">
|
||||
@if($artikel->gambar_utama)
|
||||
<img src="{{ Storage::url($artikel->gambar_utama) }}" alt="{{ $artikel->judul }}">
|
||||
<div class="card-img-overlay"></div>
|
||||
@else
|
||||
<div class="card-placeholder">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" fill="rgba(255,255,255,0.6)" viewBox="0 0 16 16">
|
||||
<path d="M8 3.5a.5.5 0 0 0-1 0V9a.5.5 0 0 0 .252.434l3.5 2a.5.5 0 0 0 .496-.868L8 8.71z"/>
|
||||
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m7-8A7 7 0 1 1 1 8a7 7 0 0 1 14 0"/>
|
||||
</svg>
|
||||
</div>
|
||||
@endif
|
||||
<span class="card-badge badge-hama">Hama</span>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
@if($artikel->tags)
|
||||
<div class="card-tags">
|
||||
@foreach(array_slice($artikel->tags, 0, 2) as $tag)
|
||||
<span class="card-tag tag-hama">{{ $tag }}</span>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<h3 class="card-title hama">{{ $artikel->judul }}</h3>
|
||||
|
||||
@if($artikel->deskripsi_singkat)
|
||||
<p class="card-excerpt">{{ $artikel->deskripsi_singkat }}</p>
|
||||
@endif
|
||||
|
||||
<div class="card-footer">
|
||||
<span class="card-date" style="display:flex;align-items:center;gap:4px">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="11" height="11" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4z"/>
|
||||
</svg>
|
||||
{{ $artikel->published_at?->format('d M Y') ?? '-' }}
|
||||
</span>
|
||||
<span class="card-cta cta-hama">Baca →</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
@else
|
||||
<div class="empty-state">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" fill="#9ca3af" viewBox="0 0 16 16" style="margin:0 auto 14px;display:block;opacity:.5">
|
||||
<path d="M8 3.5a.5.5 0 0 0-1 0V9a.5.5 0 0 0 .252.434l3.5 2a.5.5 0 0 0 .496-.868L8 8.71z"/>
|
||||
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m7-8A7 7 0 1 1 1 8a7 7 0 0 1 14 0"/>
|
||||
</svg>
|
||||
<h3>Belum ada artikel hama</h3>
|
||||
<p>Artikel akan segera tersedia</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- ── Konten Penyakit ── --}}
|
||||
<div id="content-penyakit" class="tab-content hidden">
|
||||
@if($penyakit->count() > 0)
|
||||
<div class="artikel-grid">
|
||||
@foreach($penyakit as $artikel)
|
||||
<a href="{{ route('user.artikel.hama-penyakit.detail', $artikel->slug) }}" class="artikel-card penyakit">
|
||||
|
||||
<div class="card-img-wrap" style="background: linear-gradient(135deg,#fca5a5,#b91c1c)">
|
||||
@if($artikel->gambar_utama)
|
||||
<img src="{{ Storage::url($artikel->gambar_utama) }}" alt="{{ $artikel->judul }}">
|
||||
<div class="card-img-overlay"></div>
|
||||
@else
|
||||
<div class="card-placeholder">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" fill="rgba(255,255,255,0.6)" viewBox="0 0 16 16">
|
||||
<path d="M6.5 2a.5.5 0 0 0 0 1h3a.5.5 0 0 0 0-1zM11 7.5a4.002 4.002 0 0 1-3.512 3.96A1 1 0 0 1 7 12.5V14h1a.5.5 0 0 1 0 1H6a.5.5 0 0 1 0-1h.5V12.5a1 1 0 0 1-.988-.04A4.002 4.002 0 0 1 5 7.5H1.5a.5.5 0 0 1 0-1H5a4 4 0 0 1 6 0h3.5a.5.5 0 0 1 0 1z"/>
|
||||
</svg>
|
||||
</div>
|
||||
@endif
|
||||
<span class="card-badge badge-penyakit">Penyakit</span>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
@if($artikel->tags)
|
||||
<div class="card-tags">
|
||||
@foreach(array_slice($artikel->tags, 0, 2) as $tag)
|
||||
<span class="card-tag tag-penyakit">{{ $tag }}</span>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<h3 class="card-title penyakit">{{ $artikel->judul }}</h3>
|
||||
|
||||
@if($artikel->deskripsi_singkat)
|
||||
<p class="card-excerpt">{{ $artikel->deskripsi_singkat }}</p>
|
||||
@endif
|
||||
|
||||
<div class="card-footer">
|
||||
<span class="card-date" style="display:flex;align-items:center;gap:4px">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="11" height="11" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4z"/>
|
||||
</svg>
|
||||
{{ $artikel->published_at?->format('d M Y') ?? '-' }}
|
||||
</span>
|
||||
<span class="card-cta cta-penyakit">Baca →</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
@else
|
||||
<div class="empty-state">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" fill="#9ca3af" viewBox="0 0 16 16" style="margin:0 auto 14px;display:block;opacity:.5">
|
||||
<path d="M6.5 2a.5.5 0 0 0 0 1h3a.5.5 0 0 0 0-1zM11 7.5a4.002 4.002 0 0 1-3.512 3.96A1 1 0 0 1 7 12.5V14h1a.5.5 0 0 1 0 1H6a.5.5 0 0 1 0-1h.5V12.5a1 1 0 0 1-.988-.04A4.002 4.002 0 0 1 5 7.5H1.5a.5.5 0 0 1 0-1H5a4 4 0 0 1 6 0h3.5a.5.5 0 0 1 0 1z"/>
|
||||
</svg>
|
||||
<h3>Belum ada artikel penyakit</h3>
|
||||
<p>Artikel akan segera tersedia</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
function switchTab(tab) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue