This commit is contained in:
E31232303evimr 2026-03-31 02:37:16 +07:00
parent 36c7b869fe
commit 9dbeacf9cb
33 changed files with 3904 additions and 2689 deletions

View File

@ -0,0 +1,30 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
class ContactController extends Controller
{
public function send(Request $request)
{
$request->validate([
'nama' => 'required|string|max:100',
'email' => 'required|email',
'subjek' => 'required|string|max:200',
'pesan' => 'required|string',
]);
Mail::raw(
"Dari: {$request->nama} ({$request->email})\n\nSubjek: {$request->subjek}\n\nPesan:\n{$request->pesan}",
function ($message) use ($request) {
$message->to(config('mail.from.address'))
->subject('Pesan Kontak: ' . $request->subjek)
->replyTo($request->email, $request->nama);
}
);
return redirect()->back()->with('success', 'Pesan berhasil dikirim!');
}
}

View File

@ -24,33 +24,61 @@ public function proses(Request $request)
'gejala' => 'required|array|min:1', 'gejala' => 'required|array|min:1',
], [ ], [
'gejala.required' => 'Pilih minimal 1 gejala!', 'gejala.required' => 'Pilih minimal 1 gejala!',
'gejala.min' => 'Pilih minimal 1 gejala!', 'gejala.min' => 'Pilih minimal 1 gejala!',
]); ]);
$gejalaInput = $request->gejala; // array of id_gejala $gejalaInput = $request->gejala;
// Ambil semua rule yang relevan // Ambil semua rule yang relevan
$rules = RuleBasis::whereIn('id_gejala', $gejalaInput)->get(); $rules = RuleBasis::whereIn('id_gejala', $gejalaInput)->get();
// Hitung MB dan MD per penyakit dulu // --- SKENARIO B (Rumus 5 & 7 - MAX) ---
$mbPenyakit = []; // Kalau 1 gejala ada di beberapa penyakit,
$mdPenyakit = []; // ambil nilai MB dan MD tertinggi (Max) per gejala per penyakit
// Caranya: group rule per id_gejala, kalau ada duplikat ambil Max MB dan Max MD
$rulesTerproses = [];
foreach ($rules as $rule) { foreach ($rules as $rule) {
$idGejala = $rule->id_gejala;
$idPenyakit = $rule->id_penyakit; $idPenyakit = $rule->id_penyakit;
$key = $idPenyakit . '_' . $idGejala;
if (!isset($mbPenyakit[$idPenyakit])) { if (!isset($rulesTerproses[$key])) {
// Gejala pertama $rulesTerproses[$key] = [
$mbPenyakit[$idPenyakit] = $rule->mb; 'id_penyakit' => $idPenyakit,
$mdPenyakit[$idPenyakit] = $rule->md; 'id_gejala' => $idGejala,
'mb' => $rule->mb,
'md' => $rule->md,
];
} else { } else {
// Kombinasi gejala berikutnya (rumus 2 & 3) // Rumus 5 & 7: Pakai Max untuk MB dan MD
$mbPenyakit[$idPenyakit] = $mbPenyakit[$idPenyakit] * $rule->mb; $rulesTerproses[$key]['mb'] = max($rulesTerproses[$key]['mb'], $rule->mb);
$mdPenyakit[$idPenyakit] = $mdPenyakit[$idPenyakit] + $rule->md * (1 - $mdPenyakit[$idPenyakit]); $rulesTerproses[$key]['md'] = max($rulesTerproses[$key]['md'], $rule->md);
} }
} }
// Hitung CF = MB - MD // --- SKENARIO A (Rumus 2 & 3) ---
// Kombinasi banyak gejala untuk 1 penyakit
// MB[h, e1^e2] = MB[h,e1] + MB[h,e2] * (1 - MB[h,e1])
// MD[h, e1^e2] = MD[h,e1] + MD[h,e2] * (1 - MD[h,e1])
$mbPenyakit = [];
$mdPenyakit = [];
foreach ($rulesTerproses as $rule) {
$idPenyakit = $rule['id_penyakit'];
if (!isset($mbPenyakit[$idPenyakit])) {
// Gejala pertama
$mbPenyakit[$idPenyakit] = $rule['mb'];
$mdPenyakit[$idPenyakit] = $rule['md'];
} else {
// Kombinasi gejala berikutnya (Rumus 2 & 3)
$mbPenyakit[$idPenyakit] = $mbPenyakit[$idPenyakit] + $rule['mb'] * (1 - $mbPenyakit[$idPenyakit]);
$mdPenyakit[$idPenyakit] = $mdPenyakit[$idPenyakit] + $rule['md'] * (1 - $mdPenyakit[$idPenyakit]);
}
}
// --- RUMUS DASAR (Rumus 1) ---
// CF = MB - MD
$cfPenyakit = []; $cfPenyakit = [];
foreach ($mbPenyakit as $idPenyakit => $mb) { foreach ($mbPenyakit as $idPenyakit => $mb) {
$cfPenyakit[$idPenyakit] = $mb - $mdPenyakit[$idPenyakit]; $cfPenyakit[$idPenyakit] = $mb - $mdPenyakit[$idPenyakit];
@ -70,25 +98,25 @@ public function proses(Request $request)
$penyakit = MasterPenyakit::find($idPenyakit); $penyakit = MasterPenyakit::find($idPenyakit);
if ($penyakit) { if ($penyakit) {
$hasilDiagnosa[] = [ $hasilDiagnosa[] = [
'id_penyakit' => $idPenyakit, 'id_penyakit' => $idPenyakit,
'nama_penyakit' => $penyakit->nama_penyakit, 'nama_penyakit' => $penyakit->nama_penyakit,
'cf' => round($cf, 2), 'cf' => round($cf, 4),
'persentase' => round($cf * 100, 1), 'persentase' => round($cf * 100, 2),
]; ];
} }
} }
$penyakitFinal = $hasilDiagnosa[0]['id_penyakit']; $penyakitFinal = $hasilDiagnosa[0]['id_penyakit'];
$cfTertinggi = $hasilDiagnosa[0]['cf']; $cfTertinggi = $hasilDiagnosa[0]['cf'];
// Simpan ke riwayat // Simpan ke riwayat
$riwayat = RiwayatDiagnosis::create([ $riwayat = RiwayatDiagnosis::create([
'user_id' => auth()->id(), 'user_id' => auth()->id(),
'tanggal' => now(), 'tanggal' => now(),
'gejala_input' => $gejalaInput, 'gejala_input' => $gejalaInput,
'hasil_diagnosa'=> $hasilDiagnosa, 'hasil_diagnosa' => $hasilDiagnosa,
'cf_tertinggi' => $cfTertinggi, 'cf_tertinggi' => $cfTertinggi,
'penyakit_final'=> $penyakitFinal, 'penyakit_final' => $penyakitFinal,
]); ]);
return redirect()->route('user.diagnosa.hasil', $riwayat->id_diagnosis); return redirect()->route('user.diagnosa.hasil', $riwayat->id_diagnosis);
@ -104,7 +132,6 @@ public function hasil($id)
$gejalaInput = MasterGejala::whereIn('id_gejala', $riwayat->gejala_input)->get(); $gejalaInput = MasterGejala::whereIn('id_gejala', $riwayat->gejala_input)->get();
// Ambil relasi gejala-penyakit dari rule_basis
$relasiGejala = RuleBasis::whereIn('id_gejala', $riwayat->gejala_input) $relasiGejala = RuleBasis::whereIn('id_gejala', $riwayat->gejala_input)
->whereIn('id_penyakit', collect($riwayat->hasil_diagnosa)->pluck('id_penyakit')) ->whereIn('id_penyakit', collect($riwayat->hasil_diagnosa)->pluck('id_penyakit'))
->with(['penyakit', 'gejala']) ->with(['penyakit', 'gejala'])
@ -127,13 +154,13 @@ public function riwayat()
public function destroy($id) public function destroy($id)
{ {
$riwayat = RiwayatDiagnosis::findOrFail($id); $riwayat = RiwayatDiagnosis::findOrFail($id);
if ($riwayat->user_id !== auth()->id()) { if ($riwayat->user_id !== auth()->id()) {
abort(403); abort(403);
} }
$riwayat->delete(); $riwayat->delete();
return redirect()->route('user.diagnosa.riwayat') return redirect()->route('user.diagnosa.riwayat')
->with('success', 'Riwayat diagnosa berhasil dihapus!'); ->with('success', 'Riwayat diagnosa berhasil dihapus!');
} }

BIN
public/asset/images/ori.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

BIN
public/asset/images/v2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

View File

@ -3,182 +3,416 @@
@section('page-title', 'Tambah Artikel Budidaya') @section('page-title', 'Tambah Artikel Budidaya')
@section('page-subtitle', 'Tambah informasi budidaya kopi baru') @section('page-subtitle', 'Tambah informasi budidaya kopi baru')
@push('styles')
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<style>
:root {
--green-deep: #1a4d2e;
--green-mid: #2d7a4f;
--green-bright:#4ade80;
--bg-base: #f0f5f1;
--bg-card: #ffffff;
--text-primary:#0f1f14;
--text-muted: #6b7f72;
--shadow: 0 4px 24px rgba(29,77,46,.08), 0 1px 4px rgba(29,77,46,.05);
--radius: 20px;
--input-border:#d1d5db;
--input-focus: #2d7a4f;
}
body, .form-root { font-family: 'Plus Jakarta Sans', sans-serif; }
@keyframes fadeUp {
from { opacity:0; transform:translateY(12px); }
to { opacity:1; transform:translateY(0); }
}
.anim { animation: fadeUp .5s cubic-bezier(.22,1,.36,1) both; }
.a1 { animation-delay: .04s; }
.a2 { animation-delay: .12s; }
.a3 { animation-delay: .20s; }
/* ── outer card ── */
.form-card {
background: var(--bg-card);
border-radius: var(--radius);
border: 1.5px solid rgba(29,77,46,.07);
box-shadow: var(--shadow);
overflow: hidden;
}
/* ── form body ── */
.form-body { padding: 2rem; }
/* ── section divider ── */
.form-section { margin-bottom: 2rem; }
.form-section-title {
display: flex; align-items: center; gap: .5rem;
font-size: .78rem; font-weight: 700; text-transform: uppercase;
letter-spacing: .08em; color: var(--text-muted);
margin-bottom: 1.1rem; padding-bottom: .6rem;
border-bottom: 1.5px solid rgba(29,77,46,.08);
}
.form-section-title-bar { width: 3px; height: 14px; background: linear-gradient(180deg, var(--green-mid), var(--green-bright)); border-radius: 2px; flex-shrink: 0; }
/* ── labels ── */
.form-label {
display: block; font-size: .8rem; font-weight: 700;
color: var(--text-primary); margin-bottom: .45rem;
}
.form-label .req { color: #ef4444; margin-left: 2px; }
.form-hint { font-size: .7rem; color: var(--text-muted); margin-top: .3rem; }
.form-error { font-size: .7rem; color: #ef4444; margin-top: .3rem; }
/* ── inputs ── */
.form-input, .form-textarea, .form-file {
width: 100%;
padding: .7rem 1rem;
border: 1.5px solid var(--input-border);
border-radius: 12px;
font-size: .85rem; font-family: 'Plus Jakarta Sans', sans-serif;
color: var(--text-primary);
background: #fafafa;
transition: border-color .18s, box-shadow .18s, background .18s;
outline: none;
}
.form-input:focus, .form-textarea:focus {
border-color: var(--input-focus);
background: #fff;
box-shadow: 0 0 0 3px rgba(45,122,79,.12);
}
.form-input.error { border-color: #ef4444; }
.form-textarea { resize: vertical; line-height: 1.6; }
.form-file {
padding: .6rem .9rem;
cursor: pointer;
color: var(--text-muted);
}
.form-file::-webkit-file-upload-button {
background: #f0fdf4; border: 1px solid #bbf7d0;
color: var(--green-mid); font-weight: 700; font-size: .76rem;
padding: .3rem .75rem; border-radius: 7px; cursor: pointer;
margin-right: .65rem; font-family: 'Plus Jakarta Sans', sans-serif;
}
/* ── two-col grid ── */
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; }
@media (max-width: 640px) { .grid-2 { grid-template-columns: 1fr; } }
/* ── tags ── */
.tags-box {
width: 100%; min-height: 48px;
padding: .55rem .75rem;
border: 1.5px solid var(--input-border); border-radius: 12px;
background: #fafafa;
display: flex; flex-wrap: wrap; gap: .4rem; align-items: center;
cursor: text; transition: border-color .18s, box-shadow .18s;
}
.tags-box.focused { border-color: var(--input-focus); box-shadow: 0 0 0 3px rgba(45,122,79,.12); background: #fff; }
.tag-pill {
display: inline-flex; align-items: center; gap: .3rem;
padding: .22rem .7rem; background: #dcfce7; color: #166534;
font-size: .73rem; font-weight: 700; border-radius: 50px;
}
.tag-pill button { background: none; border: none; cursor: pointer; color: #4ade80; font-size: .8rem; line-height: 1; padding: 0; }
.tag-pill button:hover { color: #ef4444; }
/* ── sub-bab ── */
.sub-header {
display: flex; align-items: center; justify-content: space-between;
margin-bottom: 1rem;
}
.sub-header-left h3 { font-size: .85rem; font-weight: 700; color: var(--text-primary); }
.sub-header-left p { font-size: .73rem; color: var(--text-muted); margin-top: 2px; }
.btn-add-sub {
display: inline-flex; align-items: center; gap: .4rem;
padding: .55rem 1.1rem;
background: #f0fdf4; border: 1.5px solid #bbf7d0;
color: var(--green-mid); font-size: .8rem; font-weight: 700;
border-radius: 50px; cursor: pointer; transition: all .18s;
}
.btn-add-sub:hover { background: #dcfce7; border-color: var(--green-mid); transform: translateY(-1px); }
.sub-card {
background: #fafcfb;
border: 1.5px solid rgba(29,77,46,.1);
border-radius: 16px;
overflow: hidden;
margin-bottom: .85rem;
transition: box-shadow .2s;
}
.sub-card:hover { box-shadow: 0 4px 16px rgba(29,77,46,.08); }
.sub-card-header {
display: flex; align-items: center; justify-content: space-between;
padding: .85rem 1.1rem;
background: rgba(45,122,79,.05);
border-bottom: 1px solid rgba(29,77,46,.08);
}
.sub-card-header span { font-size: .8rem; font-weight: 700; color: var(--green-mid); display: flex; align-items: center; gap: .4rem; }
.sub-card-header span::before { content:''; display:inline-block; width:6px; height:6px; border-radius:50%; background:var(--green-mid); }
.btn-del-sub {
display: inline-flex; align-items: center; gap: .3rem;
font-size: .75rem; font-weight: 600; color: #9ca3af;
background: none; border: none; cursor: pointer; padding: .2rem .5rem;
border-radius: 6px; transition: all .15s;
}
.btn-del-sub:hover { color: #ef4444; background: #fee2e2; }
.sub-card-body { padding: 1.1rem; display: flex; flex-direction: column; gap: .85rem; }
.sub-label { display:block; font-size:.76rem; font-weight:700; color:var(--text-muted); margin-bottom:.35rem; }
.sub-label .req { color:#ef4444; }
/* ── empty state ── */
.empty-sub {
text-align: center; padding: 2.5rem 1rem;
background: #f9fafb;
border: 2px dashed rgba(29,77,46,.15); border-radius: 16px;
}
.empty-sub-icon { width: 44px; height: 44px; margin: 0 auto .75rem; opacity: .25; }
.empty-sub p { font-size: .82rem; color: var(--text-muted); }
/* ── publish toggle ── */
.publish-row {
display: flex; align-items: center; gap: .85rem;
padding: 1rem 1.2rem;
background: #f0fdf4; border: 1.5px solid #bbf7d0;
border-radius: 14px;
}
.publish-row input[type=checkbox] { width: 18px; height: 18px; accent-color: var(--green-mid); cursor: pointer; }
.publish-row label { font-size: .85rem; font-weight: 600; color: var(--green-deep); cursor: pointer; }
.publish-row p { font-size: .72rem; color: var(--text-muted); margin-top: 1px; }
/* ── footer buttons ── */
.form-footer {
display: flex; justify-content: flex-end; gap: .75rem;
padding: 1.4rem 2rem;
border-top: 1.5px solid rgba(29,77,46,.07);
background: #fafcfb;
}
.btn-cancel {
display: inline-flex; align-items: center; gap: .4rem;
padding: .7rem 1.4rem;
background: #fff; border: 1.5px solid rgba(29,77,46,.2);
color: var(--text-primary); font-size: .85rem; font-weight: 600;
border-radius: 12px; text-decoration: none; transition: all .18s;
}
.btn-cancel:hover { background: #f9fafb; border-color: #9ca3af; }
.btn-submit {
display: inline-flex; align-items: center; gap: .45rem;
padding: .7rem 1.5rem;
background: linear-gradient(135deg, #2d7a4f, #16a34a);
color: #fff; font-size: .85rem; font-weight: 700;
border-radius: 12px; border: none; cursor: pointer;
box-shadow: 0 4px 14px rgba(22,163,74,.3); transition: all .18s;
}
.btn-submit:hover { transform: translateY(-1px); box-shadow: 0 6px 20px rgba(22,163,74,.4); }
/* ── preview image ── */
.img-preview { width: 96px; height: 68px; object-fit: cover; border-radius: 10px; margin-bottom: .5rem; border: 1.5px solid rgba(29,77,46,.1); }
.pdf-link { font-size: .75rem; color: #2563eb; text-decoration: underline; display:inline-block; margin-bottom:.4rem; }
</style>
@endpush
@section('content') @section('content')
<div class="bg-white rounded-2xl shadow-lg"> <div class="form-root">
<div class="p-8"> <form action="{{ route('admin.artikel-budidaya.store') }}" method="POST" enctype="multipart/form-data">
<form action="{{ route('admin.artikel-budidaya.store') }}" method="POST" enctype="multipart/form-data"> @csrf
@csrf
<div class="space-y-6"> <div class="form-card anim a1">
<!-- Judul -->
<div>
<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="Contoh: Persiapan Lahan, Penanaman, dll...">
@error('judul') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
</div>
<!-- Deskripsi Singkat --> {{-- Form body --}}
<div> <div class="form-body">
<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 tentang bab ini...">{{ old('deskripsi_singkat') }}</textarea>
</div>
<!-- Gambar Utama & PDF --> {{-- ── Informasi Utama ── --}}
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> <div class="form-section anim a1">
<div> <div class="form-section-title">
<label class="block text-sm font-bold text-gray-700 mb-2">Gambar Cover</label> <div class="form-section-title-bar"></div>
<input type="file" name="gambar_utama" accept="image/*" Informasi Utama
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>
</div>
<div>
<label class="block text-sm font-bold text-gray-700 mb-2">File PDF</label>
<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">Format: PDF. Maks 5MB</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>
<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>
<!-- Sub-bab -->
<div>
<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 -->
<div class="flex items-center space-x-3">
<input type="checkbox" name="is_published" value="1" id="is_published" {{ old('is_published') ? 'checked' : '' }}
class="w-5 h-5 text-green-600 rounded focus:ring-green-500">
<label for="is_published" class="text-sm font-bold text-gray-700">Publikasikan sekarang</label>
</div>
</div> </div>
<!-- Buttons --> <div style="margin-bottom:1rem;">
<div class="flex justify-end space-x-3 mt-8 pt-6 border-t border-gray-200"> <label class="form-label">Judul Bab <span class="req">*</span></label>
<a href="{{ route('admin.artikel-budidaya.index') }}" class="px-6 py-3 border border-gray-300 text-gray-700 font-semibold rounded-xl hover:bg-gray-50 transition"> <input type="text" name="judul" value="{{ old('judul') }}"
Batal class="form-input {{ $errors->has('judul') ? 'error' : '' }}"
</a> placeholder="Contoh: Persiapan Lahan, Penanaman, dll...">
<button type="submit" class="px-6 py-3 bg-gradient-to-r from-green-500 to-green-600 text-white font-bold rounded-xl hover:from-green-600 hover:to-green-700 transition shadow-lg"> @error('judul') <p class="form-error">{{ $message }}</p> @enderror
Simpan Artikel </div>
<div>
<label class="form-label">Deskripsi Singkat</label>
<textarea name="deskripsi_singkat" rows="3" class="form-textarea"
placeholder="Ringkasan singkat tentang bab ini...">{{ old('deskripsi_singkat') }}</textarea>
</div>
</div>
{{-- ── Media ── --}}
<div class="form-section anim a2">
<div class="form-section-title">
<div class="form-section-title-bar"></div>
Media
</div>
<div class="grid-2">
<div>
<label class="form-label">Gambar Cover</label>
<input type="file" name="gambar_utama" accept="image/*" class="form-file">
<p class="form-hint">Format: JPG, PNG. Maks 2MB</p>
</div>
<div>
<label class="form-label">File PDF</label>
<input type="file" name="file_pdf" accept=".pdf" class="form-file">
<p class="form-hint">Format: PDF. Maks 5MB</p>
</div>
</div>
</div>
{{-- ── Tags ── --}}
<div class="form-section anim a2">
<div class="form-section-title">
<div class="form-section-title-bar"></div>
Tags
</div>
<div id="tags-box" class="tags-box" onclick="document.getElementById('tags-input').focus()"></div>
<input type="text" id="tags-input" class="form-input" style="margin-top:.5rem;"
placeholder="Ketik tag lalu tekan Enter atau koma...">
<p class="form-hint">Tekan Enter atau koma untuk menambahkan tag</p>
<input type="hidden" name="tags" id="tags-hidden" value="[]">
</div>
{{-- ── Sub-bab ── --}}
<div class="form-section anim a3">
<div class="form-section-title">
<div class="form-section-title-bar"></div>
Sub-bab
</div>
<div class="sub-header">
<div class="sub-header-left">
<h3>Daftar Sub-bab</h3>
<p>Tambahkan sub-bab untuk artikel ini</p>
</div>
<button type="button" onclick="tambahSub()" class="btn-add-sub">
<svg width="14" height="14" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4"/></svg>
Tambah Sub-bab
</button> </button>
</div> </div>
</form>
<div id="sub-container"></div>
<div id="empty-sub" class="empty-sub">
<svg class="empty-sub-icon" fill="none" stroke="#2d7a4f" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
</svg>
<p>Belum ada sub-bab. Klik <strong>Tambah Sub-bab</strong> untuk memulai.</p>
</div>
</div>
{{-- ── Publikasi ── --}}
<div class="anim a3">
<div class="publish-row">
<input type="checkbox" name="is_published" value="1" id="is_published" {{ old('is_published') ? 'checked' : '' }}>
<div>
<label for="is_published">Publikasikan sekarang</label>
<p>Artikel akan langsung tampil untuk pengguna</p>
</div>
</div>
</div>
</div>{{-- /form-body --}}
{{-- Footer --}}
<div class="form-footer">
<a href="{{ route('admin.artikel-budidaya.index') }}" class="btn-cancel">
<svg width="14" height="14" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M10 19l-7-7m0 0l7-7m-7 7h18"/></svg>
Batal
</a>
<button type="submit" class="btn-submit">
<svg width="14" height="14" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.2"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg>
Simpan Artikel
</button>
</div> </div>
</div>{{-- /form-card --}}
</form>
</div> </div>
@endsection @endsection
@push('scripts') @push('scripts')
<script> <script>
let subCount = 0; let subCount = 0;
function tambahSub() { function tambahSub() {
const container = document.getElementById('sub-container'); document.getElementById('empty-sub').style.display = 'none';
const empty = document.getElementById('empty-sub'); const index = subCount++;
empty.classList.add('hidden'); const div = document.createElement('div');
div.className = 'sub-card';
const index = subCount++; div.id = `sub-${index}`;
const div = document.createElement('div'); div.innerHTML = `
div.className = 'sub-item bg-gray-50 border border-gray-200 rounded-xl p-5 space-y-4'; <div class="sub-card-header">
div.id = `sub-${index}`; <span>Sub-bab ${index + 1}</span>
div.innerHTML = ` <button type="button" class="btn-del-sub" onclick="hapusSub(${index})">
<div class="flex items-center justify-between"> <svg width="12" height="12" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/></svg>
<h4 class="font-bold text-gray-700 text-sm">Sub-bab ${index + 1}</h4> Hapus
<button type="button" onclick="hapusSub(${index})" class="text-red-400 hover:text-red-600 text-sm font-semibold">Hapus</button> </button>
</div>
<div class="sub-card-body">
<div>
<label class="sub-label">Judul Sub-bab <span class="req">*</span></label>
<input type="text" name="sub_judul[]" class="form-input" placeholder="Contoh: Pemilihan Lahan">
</div> </div>
<div> <div>
<label class="block text-xs font-bold text-gray-600 mb-1">Judul Sub-bab <span class="text-red-500">*</span></label> <label class="sub-label">Konten</label>
<input type="text" name="sub_judul[]" <textarea name="sub_konten[]" rows="5" class="form-textarea" placeholder="Tulis isi sub-bab di sini..."></textarea>
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>
<div> <div>
<label class="block text-xs font-bold text-gray-600 mb-1">Konten</label> <label class="sub-label">Gambar <span style="font-weight:400;color:#9ca3af;">(opsional)</span></label>
<textarea name="sub_konten[]" rows="5" <input type="file" name="sub_gambar[${index}]" accept="image/*" class="form-file">
class="w-full px-4 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-green-500" <p class="form-hint">Format: JPG, PNG. Maks 2MB</p>
placeholder="Tulis isi sub-bab di sini..."></textarea>
</div> </div>
<div> </div>`;
<label class="block text-xs font-bold text-gray-600 mb-1">Gambar (opsional)</label> document.getElementById('sub-container').appendChild(div);
<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) { function hapusSub(index) {
const el = document.getElementById(`sub-${index}`); const el = document.getElementById(`sub-${index}`);
if (el) el.remove(); if (el) el.remove();
if (document.querySelectorAll('.sub-item').length === 0) { if (!document.querySelectorAll('.sub-card').length)
document.getElementById('empty-sub').classList.remove('hidden'); document.getElementById('empty-sub').style.display = '';
} }
}
// Tags /* ── Tags ── */
const tagsInput = document.getElementById('tags-input'); const tagsInput = document.getElementById('tags-input');
const tagsContainer = document.getElementById('tags-container'); const tagsBox = document.getElementById('tags-box');
const tagsHidden = document.getElementById('tags-hidden'); const tagsHidden = document.getElementById('tags-hidden');
let tags = []; let tags = [];
function renderTags() { tagsInput.addEventListener('focus', () => tagsBox.classList.add('focused'));
tagsContainer.innerHTML = ''; tagsInput.addEventListener('blur', () => tagsBox.classList.remove('focused'));
tags.forEach((tag, index) => {
tagsContainer.innerHTML += `
<span class="flex items-center px-3 py-1 bg-green-100 text-green-800 text-xs font-bold rounded-full">
${tag}
<button type="button" onclick="removeTag(${index})" class="ml-2 text-green-600 hover:text-red-500"></button>
</span>`;
});
tagsHidden.value = JSON.stringify(tags);
}
function removeTag(index) { function renderTags() {
tags.splice(index, 1); tagsBox.innerHTML = '';
renderTags(); tags.forEach((tag, i) => {
} const span = document.createElement('span');
span.className = 'tag-pill';
tagsInput.addEventListener('keydown', function(e) { span.innerHTML = `${tag}<button type="button" onclick="removeTag(${i})" title="Hapus">&#x2715;</button>`;
if (e.key === 'Enter' || e.key === ',') { tagsBox.appendChild(span);
e.preventDefault();
const val = tagsInput.value.trim();
if (val) {
tags.push(val);
tagsInput.value = '';
renderTags();
}
}
}); });
tagsBox.appendChild(tagsInput);
tagsHidden.value = JSON.stringify(tags);
}
function removeTag(i) { tags.splice(i, 1); renderTags(); }
tagsInput.addEventListener('keydown', e => {
if (e.key === 'Enter' || e.key === ',') {
e.preventDefault();
const val = tagsInput.value.trim().replace(/,$/, '');
if (val && !tags.includes(val)) { tags.push(val); renderTags(); }
else tagsInput.value = '';
}
if (e.key === 'Backspace' && !tagsInput.value && tags.length) {
tags.pop(); renderTags();
}
});
renderTags();
</script> </script>
@endpush @endpush

View File

@ -3,219 +3,407 @@
@section('page-title', 'Edit Artikel Budidaya') @section('page-title', 'Edit Artikel Budidaya')
@section('page-subtitle', 'Edit informasi budidaya kopi') @section('page-subtitle', 'Edit informasi budidaya kopi')
@push('styles')
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<style>
:root {
--green-deep: #1a4d2e;
--green-mid: #2d7a4f;
--green-bright:#4ade80;
--bg-base: #f0f5f1;
--bg-card: #ffffff;
--text-primary:#0f1f14;
--text-muted: #6b7f72;
--shadow: 0 4px 24px rgba(29,77,46,.08), 0 1px 4px rgba(29,77,46,.05);
--radius: 20px;
--input-border:#d1d5db;
--input-focus: #2d7a4f;
}
body, .form-root { font-family: 'Plus Jakarta Sans', sans-serif; }
@keyframes fadeUp {
from { opacity:0; transform:translateY(12px); }
to { opacity:1; transform:translateY(0); }
}
.anim { animation: fadeUp .5s cubic-bezier(.22,1,.36,1) both; }
.a1 { animation-delay: .04s; }
.a2 { animation-delay: .12s; }
.a3 { animation-delay: .20s; }
.form-card {
background: var(--bg-card);
border-radius: var(--radius);
border: 1.5px solid rgba(29,77,46,.07);
box-shadow: var(--shadow);
overflow: hidden;
}
.form-body { padding: 2rem; }
.form-section { margin-bottom: 2rem; }
.form-section-title {
display: flex; align-items: center; gap: .5rem;
font-size: .78rem; font-weight: 700; text-transform: uppercase;
letter-spacing: .08em; color: var(--text-muted);
margin-bottom: 1.1rem; padding-bottom: .6rem;
border-bottom: 1.5px solid rgba(29,77,46,.08);
}
.form-section-title-bar { width: 3px; height: 14px; background: linear-gradient(180deg, var(--green-mid), var(--green-bright)); border-radius: 2px; flex-shrink: 0; }
.form-label { display: block; font-size: .8rem; font-weight: 700; color: var(--text-primary); margin-bottom: .45rem; }
.form-label .req { color: #ef4444; margin-left: 2px; }
.form-hint { font-size: .7rem; color: var(--text-muted); margin-top: .3rem; }
.form-error { font-size: .7rem; color: #ef4444; margin-top: .3rem; }
.form-input, .form-textarea, .form-file {
width: 100%;
padding: .7rem 1rem;
border: 1.5px solid var(--input-border);
border-radius: 12px;
font-size: .85rem; font-family: 'Plus Jakarta Sans', sans-serif;
color: var(--text-primary);
background: #fafafa;
transition: border-color .18s, box-shadow .18s, background .18s;
outline: none;
}
.form-input:focus, .form-textarea:focus {
border-color: var(--input-focus); background: #fff;
box-shadow: 0 0 0 3px rgba(45,122,79,.12);
}
.form-input.error { border-color: #ef4444; }
.form-textarea { resize: vertical; line-height: 1.6; }
.form-file { padding: .6rem .9rem; cursor: pointer; color: var(--text-muted); }
.form-file::-webkit-file-upload-button {
background: #f0fdf4; border: 1px solid #bbf7d0;
color: var(--green-mid); font-weight: 700; font-size: .76rem;
padding: .3rem .75rem; border-radius: 7px; cursor: pointer;
margin-right: .65rem; font-family: 'Plus Jakarta Sans', sans-serif;
}
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; }
@media (max-width: 640px) { .grid-2 { grid-template-columns: 1fr; } }
/* current media previews */
.media-current {
display: flex; align-items: center; gap: .65rem;
padding: .55rem .8rem; background: #f0fdf4;
border: 1px solid #bbf7d0; border-radius: 10px;
margin-bottom: .6rem;
}
.media-current img { width: 52px; height: 38px; object-fit: cover; border-radius: 7px; flex-shrink: 0; }
.media-current span { font-size: .73rem; color: var(--text-muted); }
.media-current a { font-size: .73rem; color: #2563eb; text-decoration: underline; }
/* tags */
.tags-box {
width: 100%; min-height: 48px;
padding: .55rem .75rem;
border: 1.5px solid var(--input-border); border-radius: 12px;
background: #fafafa;
display: flex; flex-wrap: wrap; gap: .4rem; align-items: center;
cursor: text; transition: border-color .18s, box-shadow .18s;
}
.tags-box.focused { border-color: var(--input-focus); box-shadow: 0 0 0 3px rgba(45,122,79,.12); background: #fff; }
.tag-pill {
display: inline-flex; align-items: center; gap: .3rem;
padding: .22rem .7rem; background: #dcfce7; color: #166534;
font-size: .73rem; font-weight: 700; border-radius: 50px;
}
.tag-pill button { background:none; border:none; cursor:pointer; color:#4ade80; font-size:.8rem; line-height:1; padding:0; }
.tag-pill button:hover { color:#ef4444; }
/* sub-bab */
.sub-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 1rem; }
.sub-header-left h3 { font-size: .85rem; font-weight: 700; color: var(--text-primary); }
.sub-header-left p { font-size: .73rem; color: var(--text-muted); margin-top: 2px; }
.btn-add-sub {
display: inline-flex; align-items: center; gap: .4rem;
padding: .55rem 1.1rem;
background: #f0fdf4; border: 1.5px solid #bbf7d0;
color: var(--green-mid); font-size: .8rem; font-weight: 700;
border-radius: 50px; cursor: pointer; transition: all .18s;
}
.btn-add-sub:hover { background: #dcfce7; border-color: var(--green-mid); transform: translateY(-1px); }
.sub-card { background: #fafcfb; border: 1.5px solid rgba(29,77,46,.1); border-radius: 16px; overflow: hidden; margin-bottom: .85rem; transition: box-shadow .2s; }
.sub-card:hover { box-shadow: 0 4px 16px rgba(29,77,46,.08); }
.sub-card-header {
display: flex; align-items: center; justify-content: space-between;
padding: .85rem 1.1rem;
background: rgba(45,122,79,.05); border-bottom: 1px solid rgba(29,77,46,.08);
}
.sub-card-header span { font-size: .8rem; font-weight: 700; color: var(--green-mid); display: flex; align-items: center; gap: .4rem; }
.sub-card-header span::before { content:''; display:inline-block; width:6px; height:6px; border-radius:50%; background:var(--green-mid); }
.btn-del-sub { display:inline-flex; align-items:center; gap:.3rem; font-size:.75rem; font-weight:600; color:#9ca3af; background:none; border:none; cursor:pointer; padding:.2rem .5rem; border-radius:6px; transition:all .15s; }
.btn-del-sub:hover { color:#ef4444; background:#fee2e2; }
.sub-card-body { padding: 1.1rem; display: flex; flex-direction: column; gap: .85rem; }
.sub-label { display:block; font-size:.76rem; font-weight:700; color:var(--text-muted); margin-bottom:.35rem; }
.sub-label .req { color:#ef4444; }
/* existing sub image preview */
.sub-img-preview { width: 72px; height: 50px; object-fit: cover; border-radius: 8px; margin-bottom: .4rem; border: 1.5px solid rgba(29,77,46,.1); display: block; }
.empty-sub { text-align:center; padding:2.5rem 1rem; background:#f9fafb; border:2px dashed rgba(29,77,46,.15); border-radius:16px; }
.empty-sub-icon { width:44px; height:44px; margin:0 auto .75rem; opacity:.25; }
.empty-sub p { font-size:.82rem; color:var(--text-muted); }
.publish-row { display:flex; align-items:center; gap:.85rem; padding:1rem 1.2rem; background:#f0fdf4; border:1.5px solid #bbf7d0; border-radius:14px; }
.publish-row input[type=checkbox] { width:18px; height:18px; accent-color:var(--green-mid); cursor:pointer; }
.publish-row label { font-size:.85rem; font-weight:600; color:var(--green-deep); cursor:pointer; }
.publish-row p { font-size:.72rem; color:var(--text-muted); margin-top:1px; }
.form-footer { display:flex; justify-content:flex-end; gap:.75rem; padding:1.4rem 2rem; border-top:1.5px solid rgba(29,77,46,.07); background:#fafcfb; }
.btn-cancel { display:inline-flex; align-items:center; gap:.4rem; padding:.7rem 1.4rem; background:#fff; border:1.5px solid rgba(29,77,46,.2); color:var(--text-primary); font-size:.85rem; font-weight:600; border-radius:12px; text-decoration:none; transition:all .18s; }
.btn-cancel:hover { background:#f9fafb; border-color:#9ca3af; }
.btn-submit { display:inline-flex; align-items:center; gap:.45rem; padding:.7rem 1.5rem; background:linear-gradient(135deg,#2d7a4f,#16a34a); color:#fff; font-size:.85rem; font-weight:700; border-radius:12px; border:none; cursor:pointer; box-shadow:0 4px 14px rgba(22,163,74,.3); transition:all .18s; }
.btn-submit:hover { transform:translateY(-1px); box-shadow:0 6px 20px rgba(22,163,74,.4); }
</style>
@endpush
@section('content') @section('content')
<div class="bg-white rounded-2xl shadow-lg"> <div class="form-root">
<div class="p-8"> <form action="{{ route('admin.artikel-budidaya.update', $artikelBudidaya) }}" method="POST" enctype="multipart/form-data">
<form action="{{ route('admin.artikel-budidaya.update', $artikelBudidaya) }}" method="POST" enctype="multipart/form-data"> @csrf
@csrf @method('PUT')
@method('PUT')
<div class="space-y-6"> <div class="form-card anim a1">
<!-- Judul -->
<div>
<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
</div>
<!-- Deskripsi Singkat --> {{-- Form body --}}
<div> <div class="form-body">
<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">{{ old('deskripsi_singkat', $artikelBudidaya->deskripsi_singkat) }}</textarea>
</div>
<!-- Gambar Utama & PDF --> {{-- ── Informasi Utama ── --}}
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> <div class="form-section anim a1">
<div> <div class="form-section-title">
<label class="block text-sm font-bold text-gray-700 mb-2">Gambar Cover</label> <div class="form-section-title-bar"></div>
@if($artikelBudidaya->gambar_utama) Informasi 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</p>
</div>
<div>
<label class="block text-sm font-bold text-gray-700 mb-2">File PDF</label>
@if($artikelBudidaya->file_pdf)
<a href="{{ Storage::url($artikelBudidaya->file_pdf) }}" target="_blank" class="text-xs text-blue-500 underline mb-2 block">Lihat PDF saat ini</a>
@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</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>
<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...">
<input type="hidden" name="tags" id="tags-hidden" value="[]">
</div>
<!-- Sub-bab -->
<div>
<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>
@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' : '' }}
class="w-5 h-5 text-green-600 rounded focus:ring-green-500">
<label for="is_published" class="text-sm font-bold text-gray-700">Publikasikan</label>
</div>
</div> </div>
<!-- Buttons --> <div style="margin-bottom:1rem;">
<div class="flex justify-end space-x-3 mt-8 pt-6 border-t border-gray-200"> <label class="form-label">Judul Bab <span class="req">*</span></label>
<a href="{{ route('admin.artikel-budidaya.index') }}" class="px-6 py-3 border border-gray-300 text-gray-700 font-semibold rounded-xl hover:bg-gray-50 transition"> <input type="text" name="judul" value="{{ old('judul', $artikelBudidaya->judul) }}"
Batal class="form-input {{ $errors->has('judul') ? 'error' : '' }}">
</a> @error('judul') <p class="form-error">{{ $message }}</p> @enderror
<button type="submit" class="px-6 py-3 bg-gradient-to-r from-green-500 to-green-600 text-white font-bold rounded-xl hover:from-green-600 hover:to-green-700 transition shadow-lg"> </div>
Update Artikel
<div>
<label class="form-label">Deskripsi Singkat</label>
<textarea name="deskripsi_singkat" rows="3" class="form-textarea">{{ old('deskripsi_singkat', $artikelBudidaya->deskripsi_singkat) }}</textarea>
</div>
</div>
{{-- ── Media ── --}}
<div class="form-section anim a2">
<div class="form-section-title">
<div class="form-section-title-bar"></div>
Media
</div>
<div class="grid-2">
<div>
<label class="form-label">Gambar Cover</label>
@if($artikelBudidaya->gambar_utama)
<div class="media-current">
<img src="{{ Storage::url($artikelBudidaya->gambar_utama) }}" alt="Cover">
<span>Gambar saat ini</span>
</div>
@endif
<input type="file" name="gambar_utama" accept="image/*" class="form-file">
<p class="form-hint">Kosongkan jika tidak ingin mengubah. Format: JPG, PNG. Maks 2MB</p>
</div>
<div>
<label class="form-label">File PDF</label>
@if($artikelBudidaya->file_pdf)
<div class="media-current">
<svg width="28" height="28" fill="none" viewBox="0 0 24 24" stroke="#dc2626" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z"/></svg>
<a href="{{ Storage::url($artikelBudidaya->file_pdf) }}" target="_blank">Lihat PDF saat ini</a>
</div>
@endif
<input type="file" name="file_pdf" accept=".pdf" class="form-file">
<p class="form-hint">Kosongkan jika tidak ingin mengubah. Format: PDF. Maks 5MB</p>
</div>
</div>
</div>
{{-- ── Tags ── --}}
<div class="form-section anim a2">
<div class="form-section-title">
<div class="form-section-title-bar"></div>
Tags
</div>
<div id="tags-box" class="tags-box" onclick="document.getElementById('tags-input').focus()"></div>
<input type="text" id="tags-input" class="form-input" style="margin-top:.5rem;"
placeholder="Ketik tag lalu tekan Enter atau koma...">
<p class="form-hint">Tekan Enter atau koma untuk menambahkan tag. Backspace untuk menghapus tag terakhir.</p>
<input type="hidden" name="tags" id="tags-hidden" value="[]">
</div>
{{-- ── Sub-bab ── --}}
<div class="form-section anim a3">
<div class="form-section-title">
<div class="form-section-title-bar"></div>
Sub-bab
</div>
<div class="sub-header">
<div class="sub-header-left">
<h3>Daftar Sub-bab</h3>
<p>Edit atau tambah sub-bab artikel</p>
</div>
<button type="button" onclick="tambahSub()" class="btn-add-sub">
<svg width="14" height="14" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4"/></svg>
Tambah Sub-bab
</button> </button>
</div> </div>
</form>
<div id="sub-container">
@foreach($artikelBudidaya->subBab as $i => $sub)
<div class="sub-card" id="sub-existing-{{ $i }}">
<div class="sub-card-header">
<span>Sub-bab {{ $i + 1 }}</span>
<button type="button" class="btn-del-sub" onclick="hapusSub('sub-existing-{{ $i }}')">
<svg width="12" height="12" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/></svg>
Hapus
</button>
</div>
<div class="sub-card-body">
<div>
<label class="sub-label">Judul Sub-bab <span class="req">*</span></label>
<input type="text" name="sub_judul[]" value="{{ $sub->judul_sub }}" class="form-input">
</div>
<div>
<label class="sub-label">Konten</label>
<textarea name="sub_konten[]" rows="5" class="form-textarea">{{ $sub->konten }}</textarea>
</div>
<div>
<label class="sub-label">Gambar</label>
@if($sub->gambar)
<img src="{{ Storage::url($sub->gambar) }}" class="sub-img-preview" alt="Sub gambar">
@endif
<input type="file" name="sub_gambar[{{ $i }}]" accept="image/*" class="form-file">
<p class="form-hint">Kosongkan jika tidak ingin mengubah</p>
</div>
</div>
</div>
@endforeach
</div>
<div id="empty-sub" class="{{ $artikelBudidaya->subBab->isEmpty() ? '' : 'hidden' }} empty-sub">
<svg class="empty-sub-icon" fill="none" stroke="#2d7a4f" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
</svg>
<p>Belum ada sub-bab. Klik <strong>Tambah Sub-bab</strong> untuk memulai.</p>
</div>
</div>
{{-- ── Publikasi ── --}}
<div class="anim a3">
<div class="publish-row">
<input type="checkbox" name="is_published" value="1" id="is_published"
{{ old('is_published', $artikelBudidaya->is_published) ? 'checked' : '' }}>
<div>
<label for="is_published">Publikasikan</label>
<p>Artikel akan tampil untuk pengguna jika dicentang</p>
</div>
</div>
</div>
</div>{{-- /form-body --}}
{{-- Footer --}}
<div class="form-footer">
<a href="{{ route('admin.artikel-budidaya.index') }}" class="btn-cancel">
<svg width="14" height="14" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M10 19l-7-7m0 0l7-7m-7 7h18"/></svg>
Batal
</a>
<button type="submit" class="btn-submit">
<svg width="14" height="14" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.2"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg>
Update Artikel
</button>
</div> </div>
</div>{{-- /form-card --}}
</form>
</div> </div>
@endsection @endsection
@push('scripts') @push('scripts')
<script> <script>
let subCount = {{ $artikelBudidaya->subBab->count() }}; let subCount = {{ $artikelBudidaya->subBab->count() }};
function tambahSub() { function tambahSub() {
const container = document.getElementById('sub-container'); document.getElementById('empty-sub').classList.add('hidden');
const empty = document.getElementById('empty-sub'); const index = subCount++;
empty.classList.add('hidden'); const div = document.createElement('div');
div.className = 'sub-card';
const index = subCount++; div.id = `sub-new-${index}`;
const div = document.createElement('div'); div.innerHTML = `
div.className = 'sub-item bg-gray-50 border border-gray-200 rounded-xl p-5 space-y-4'; <div class="sub-card-header">
div.id = `sub-new-${index}`; <span>Sub-bab Baru</span>
div.innerHTML = ` <button type="button" class="btn-del-sub" onclick="hapusSub('sub-new-${index}')">
<div class="flex items-center justify-between"> <svg width="12" height="12" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/></svg>
<h4 class="font-bold text-gray-700 text-sm">Sub-bab Baru</h4> Hapus
<button type="button" onclick="hapusSubExisting('sub-new-${index}')" class="text-red-400 hover:text-red-600 text-sm font-semibold">Hapus</button> </button>
</div>
<div class="sub-card-body">
<div>
<label class="sub-label">Judul Sub-bab <span class="req">*</span></label>
<input type="text" name="sub_judul[]" class="form-input" placeholder="Contoh: Pemilihan Lahan">
</div> </div>
<div> <div>
<label class="block text-xs font-bold text-gray-600 mb-1">Judul Sub-bab <span class="text-red-500">*</span></label> <label class="sub-label">Konten</label>
<input type="text" name="sub_judul[]" <textarea name="sub_konten[]" rows="5" class="form-textarea" placeholder="Tulis isi sub-bab di sini..."></textarea>
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>
<div> <div>
<label class="block text-xs font-bold text-gray-600 mb-1">Konten</label> <label class="sub-label">Gambar <span style="font-weight:400;color:#9ca3af;">(opsional)</span></label>
<textarea name="sub_konten[]" rows="5" <input type="file" name="sub_gambar[${index}]" accept="image/*" class="form-file">
class="w-full px-4 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-green-500" <p class="form-hint">Format: JPG, PNG. Maks 2MB</p>
placeholder="Tulis isi sub-bab di sini..."></textarea>
</div> </div>
<div> </div>`;
<label class="block text-xs font-bold text-gray-600 mb-1">Gambar (opsional)</label> document.getElementById('sub-container').appendChild(div);
<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) { function hapusSub(id) {
const el = document.getElementById(id); const el = document.getElementById(id);
if (el) el.remove(); if (el) el.remove();
if (document.querySelectorAll('.sub-item').length === 0) { if (!document.querySelectorAll('.sub-card').length)
document.getElementById('empty-sub').classList.remove('hidden'); document.getElementById('empty-sub').classList.remove('hidden');
} }
}
// Tags /* ── Tags ── */
const tagsInput = document.getElementById('tags-input'); const tagsInput = document.getElementById('tags-input');
const tagsContainer = document.getElementById('tags-container'); const tagsBox = document.getElementById('tags-box');
const tagsHidden = document.getElementById('tags-hidden'); const tagsHidden = document.getElementById('tags-hidden');
let tags = {!! json_encode($artikelBudidaya->tags ?? []) !!}; let tags = {!! json_encode($artikelBudidaya->tags ?? []) !!};
function renderTags() { tagsInput.addEventListener('focus', () => tagsBox.classList.add('focused'));
tagsContainer.innerHTML = ''; tagsInput.addEventListener('blur', () => tagsBox.classList.remove('focused'));
tags.forEach((tag, index) => {
tagsContainer.innerHTML += `
<span class="flex items-center px-3 py-1 bg-green-100 text-green-800 text-xs font-bold rounded-full">
${tag}
<button type="button" onclick="removeTag(${index})" class="ml-2 text-green-600 hover:text-red-500"></button>
</span>`;
});
tagsHidden.value = JSON.stringify(tags);
}
function removeTag(index) { function renderTags() {
tags.splice(index, 1); tagsBox.innerHTML = '';
renderTags(); tags.forEach((tag, i) => {
} const span = document.createElement('span');
span.className = 'tag-pill';
tagsInput.addEventListener('keydown', function(e) { span.innerHTML = `${tag}<button type="button" onclick="removeTag(${i})" title="Hapus">&#x2715;</button>`;
if (e.key === 'Enter' || e.key === ',') { tagsBox.appendChild(span);
e.preventDefault();
const val = tagsInput.value.trim();
if (val) {
tags.push(val);
tagsInput.value = '';
renderTags();
}
}
}); });
tagsBox.appendChild(tagsInput);
tagsHidden.value = JSON.stringify(tags);
}
renderTags(); function removeTag(i) { tags.splice(i, 1); renderTags(); }
tagsInput.addEventListener('keydown', e => {
if (e.key === 'Enter' || e.key === ',') {
e.preventDefault();
const val = tagsInput.value.trim().replace(/,$/, '');
if (val && !tags.includes(val)) { tags.push(val); renderTags(); }
else tagsInput.value = '';
}
if (e.key === 'Backspace' && !tagsInput.value && tags.length) {
tags.pop(); renderTags();
}
});
renderTags();
</script> </script>
@endpush @endpush

View File

@ -3,102 +3,258 @@
@section('page-title', 'Artikel Budidaya') @section('page-title', 'Artikel Budidaya')
@section('page-subtitle', 'Kelola informasi budidaya kopi') @section('page-subtitle', 'Kelola informasi budidaya kopi')
@push('styles')
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<style>
:root {
--green-deep: #1a4d2e;
--green-mid: #2d7a4f;
--green-bright:#4ade80;
--bg-base: #f0f5f1;
--bg-card: #ffffff;
--text-primary:#0f1f14;
--text-muted: #6b7f72;
--shadow: 0 4px 24px rgba(29,77,46,.08), 0 1px 4px rgba(29,77,46,.05);
--radius: 20px;
}
body, .index-root { font-family: 'Plus Jakarta Sans', sans-serif; }
@keyframes fadeUp {
from { opacity:0; transform:translateY(12px); }
to { opacity:1; transform:translateY(0); }
}
.anim { animation: fadeUp .5s cubic-bezier(.22,1,.36,1) both; }
.a1 { animation-delay: .04s; }
.a2 { animation-delay: .12s; }
/* ── alert ── */
.alert-success {
display: flex; align-items: center; gap: .75rem;
padding: .9rem 1.2rem; margin-bottom: 1.25rem;
background: #f0fdf4; border: 1.5px solid #bbf7d0;
border-radius: 14px; font-size: .85rem; font-weight: 600; color: #166534;
}
.alert-success svg { flex-shrink: 0; }
/* ── main card ── */
.index-card {
background: var(--bg-card);
border-radius: var(--radius);
border: 1.5px solid rgba(29,77,46,.07);
box-shadow: var(--shadow);
overflow: hidden;
}
/* ── toolbar ── */
.toolbar {
display: flex; align-items: center; justify-content: space-between;
padding: 1.4rem 1.75rem;
border-bottom: 1.5px solid rgba(29,77,46,.07);
flex-wrap: wrap; gap: .75rem;
}
.toolbar-title {
font-size: 1rem; font-weight: 700;
color: var(--text-primary); letter-spacing: -.01em;
}
.toolbar-title span {
display: inline-flex; align-items: center; gap: .4rem;
}
.toolbar-title-bar {
display: inline-block; width: 3px; height: 16px;
background: linear-gradient(180deg, var(--green-mid), var(--green-bright));
border-radius: 2px; vertical-align: middle; margin-right: .3rem;
}
.btn-add {
display: inline-flex; align-items: center; gap: .45rem;
padding: .6rem 1.25rem;
background: linear-gradient(135deg, #2d7a4f, #16a34a);
color: #fff; font-size: .82rem; font-weight: 700;
border-radius: 50px; text-decoration: none;
box-shadow: 0 4px 14px rgba(22,163,74,.25);
transition: all .2s;
}
.btn-add:hover { transform: translateY(-1px); box-shadow: 0 6px 20px rgba(22,163,74,.35); }
/* ── table ── */
.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; }
thead tr { border-bottom: 1.5px solid rgba(29,77,46,.08); }
thead th {
padding: .75rem 1.25rem;
text-align: left; font-size: .68rem; font-weight: 700;
text-transform: uppercase; letter-spacing: .08em;
color: var(--text-muted); white-space: nowrap;
background: #fafcfb;
}
thead th.center { text-align: center; }
tbody tr { border-bottom: 1px solid rgba(29,77,46,.05); transition: background .15s; }
tbody tr:last-child { border-bottom: none; }
tbody tr:hover { background: #fafcfb; }
td { padding: .9rem 1.25rem; vertical-align: middle; }
.td-no { font-size: .78rem; color: var(--text-muted); font-weight: 500; width: 48px; }
.article-title { font-size: .85rem; font-weight: 700; color: var(--text-primary); }
.article-desc { font-size: .75rem; color: var(--text-muted); margin-top: .2rem; line-height: 1.4; }
/* status badge */
.badge {
display: inline-flex; align-items: center; gap: .3rem;
padding: .25rem .75rem; border-radius: 50px;
font-size: .7rem; font-weight: 700; white-space: nowrap;
}
.badge-published { background: #f0fdf4; color: #166534; border: 1px solid #bbf7d0; }
.badge-draft { background: #f9fafb; color: #6b7280; border: 1px solid #e5e7eb; }
.badge-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
.badge-published .badge-dot { background: #16a34a; }
.badge-draft .badge-dot { background: #9ca3af; }
.td-author { font-size: .8rem; color: var(--text-primary); font-weight: 500; }
.td-date { font-size: .78rem; color: var(--text-muted); white-space: nowrap; }
/* action buttons */
.actions { display: flex; align-items: center; justify-content: center; gap: .45rem; }
.btn-edit, .btn-del {
display: inline-flex; align-items: center; gap: .3rem;
padding: .38rem .85rem; border-radius: 8px;
font-size: .75rem; font-weight: 700;
text-decoration: none; border: 1.5px solid transparent;
cursor: pointer; transition: all .15s; white-space: nowrap;
}
.btn-edit {
background: #f0fdf4; color: #2d7a4f; border-color: #bbf7d0;
}
.btn-edit:hover { background: #dcfce7; border-color: #2d7a4f; }
.btn-del {
background: #fff5f5; color: #dc2626; border-color: #fecaca;
}
.btn-del:hover { background: #fee2e2; }
/* empty state */
.empty-state {
padding: 4rem 2rem; text-align: center;
}
.empty-icon { width: 52px; height: 52px; margin: 0 auto 1rem; opacity: .25; }
.empty-state h4 { font-size: .95rem; font-weight: 700; color: var(--text-primary); margin-bottom: .35rem; }
.empty-state p { font-size: .82rem; color: var(--text-muted); }
/* pagination */
.pagination-wrap { padding: 1.1rem 1.75rem; border-top: 1.5px solid rgba(29,77,46,.07); }
</style>
@endpush
@section('content') @section('content')
@if (session('success')) <div class="index-root">
<div class="mb-6 bg-green-100 border-l-4 border-green-500 text-green-700 p-4 rounded-lg flex items-center">
<svg class="w-6 h-6 mr-3" fill="currentColor" viewBox="0 0 20 20"> {{-- Alert --}}
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/> @if(session('success'))
<div class="alert-success anim a1">
<svg width="16" height="16" fill="none" stroke="#16a34a" viewBox="0 0 24 24" stroke-width="2.2">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg> </svg>
<span class="font-semibold">{{ session('success') }}</span> {{ session('success') }}
</div> </div>
@endif @endif
<div class="bg-white rounded-2xl shadow-lg"> <div class="index-card anim a2">
<div class="p-8">
<div class="flex justify-between items-center mb-6">
<div class="flex items-center">
<div class="bg-gradient-to-r from-green-500 to-green-600 rounded-xl p-3 mr-4">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2m-4-3H9M7 16h6M7 8h6v4H7V8z"></path>
</svg>
</div>
<h3 class="text-xl font-bold text-gray-800">Daftar Artikel Budidaya</h3>
</div>
<a href="{{ route('admin.artikel-budidaya.create') }}" class="flex items-center px-5 py-3 bg-gradient-to-r from-green-500 to-green-600 text-white font-bold rounded-xl hover:from-green-600 hover:to-green-700 transition-all shadow-lg hover:shadow-xl transform hover:scale-105">
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
</svg>
Tambah Artikel
</a>
</div>
<div class="overflow-x-auto rounded-xl border border-gray-200"> {{-- Toolbar --}}
<table class="min-w-full divide-y divide-gray-200"> <div class="toolbar">
<thead class="bg-gray-50"> <div class="toolbar-title">
<tr> <span class="toolbar-title-bar"></span>
<th class="px-6 py-4 text-left text-xs font-bold text-gray-600 uppercase">No</th> Daftar Artikel Budidaya
<th class="px-6 py-4 text-left text-xs font-bold text-gray-600 uppercase">Judul</th>
<th class="px-6 py-4 text-left text-xs font-bold text-gray-600 uppercase">Status</th>
<th class="px-6 py-4 text-left text-xs font-bold text-gray-600 uppercase">Penulis</th>
<th class="px-6 py-4 text-left text-xs font-bold text-gray-600 uppercase">Tanggal</th>
<th class="px-6 py-4 text-center text-xs font-bold text-gray-600 uppercase">Aksi</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
@forelse ($artikels as $index => $artikel)
<tr class="hover:bg-gray-50 transition-colors">
<td class="px-6 py-4 text-sm">{{ $artikels->firstItem() + $index }}</td>
<td class="px-6 py-4">
<div class="text-sm font-semibold text-gray-900">{{ $artikel->judul }}</div>
@if($artikel->deskripsi_singkat)
<div class="text-xs text-gray-400 mt-1">{{ Str::limit($artikel->deskripsi_singkat, 60) }}</div>
@endif
</td>
<td class="px-6 py-4">
@if($artikel->is_published)
<span class="px-3 py-1 text-xs font-bold rounded-full bg-green-100 text-green-800">Published</span>
@else
<span class="px-3 py-1 text-xs font-bold rounded-full bg-gray-100 text-gray-600">Draft</span>
@endif
</td>
<td class="px-6 py-4 text-sm text-gray-600">{{ $artikel->author->nama ?? 'Admin' }}</td>
<td class="px-6 py-4 text-sm text-gray-600">{{ $artikel->created_at->format('d M Y') }}</td>
<td class="px-6 py-4 text-center">
<div class="flex justify-center space-x-2">
<a href="{{ route('admin.artikel-budidaya.edit', $artikel) }}" class="inline-flex items-center px-3 py-2 bg-blue-500 text-white text-xs font-semibold rounded-lg hover:bg-blue-600 transition">
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path>
</svg>
Edit
</a>
<form action="{{ route('admin.artikel-budidaya.destroy', $artikel) }}" method="POST" onsubmit="return confirm('Yakin ingin menghapus artikel ini?')">
@csrf
@method('DELETE')
<button type="submit" class="inline-flex items-center px-3 py-2 bg-red-500 text-white text-xs font-semibold rounded-lg hover:bg-red-600 transition">
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
</svg>
Hapus
</button>
</form>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="6" class="px-6 py-12 text-center text-gray-400">
<svg class="w-16 h-16 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 006.586 13H4"></path>
</svg>
<p class="text-xl font-semibold mb-2">Belum ada artikel budidaya</p>
</td>
</tr>
@endforelse
</tbody>
</table>
</div> </div>
<a href="{{ route('admin.artikel-budidaya.create') }}" class="btn-add">
<div class="mt-6">{{ $artikels->links() }}</div> <svg width="13" height="13" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4"/>
</svg>
Tambah Artikel
</a>
</div> </div>
{{-- Table --}}
<div class="table-wrap">
<table>
<thead>
<tr>
<th>No</th>
<th>Judul</th>
<th>Status</th>
<th>Penulis</th>
<th>Tanggal</th>
<th class="center">Aksi</th>
</tr>
</thead>
<tbody>
@forelse($artikels as $index => $artikel)
<tr>
<td class="td-no">{{ $artikels->firstItem() + $index }}</td>
<td>
<div class="article-title">{{ $artikel->judul }}</div>
@if($artikel->deskripsi_singkat)
<div class="article-desc">{{ Str::limit($artikel->deskripsi_singkat, 65) }}</div>
@endif
</td>
<td>
@if($artikel->is_published)
<span class="badge badge-published">
<span class="badge-dot"></span> Published
</span>
@else
<span class="badge badge-draft">
<span class="badge-dot"></span> Draft
</span>
@endif
</td>
<td class="td-author">{{ $artikel->author->nama ?? 'Admin' }}</td>
<td class="td-date">{{ $artikel->created_at->format('d M Y') }}</td>
<td>
<div class="actions">
<a href="{{ route('admin.artikel-budidaya.edit', $artikel) }}" class="btn-edit">
<svg width="12" height="12" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.2">
<path stroke-linecap="round" stroke-linejoin="round" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
</svg>
Edit
</a>
<form action="{{ route('admin.artikel-budidaya.destroy', $artikel) }}" method="POST"
onsubmit="return confirm('Yakin ingin menghapus artikel ini?')" style="display:contents;">
@csrf
@method('DELETE')
<button type="submit" class="btn-del">
<svg width="12" height="12" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.2">
<path stroke-linecap="round" stroke-linejoin="round" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
</svg>
Hapus
</button>
</form>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="6">
<div class="empty-state">
<svg class="empty-icon" fill="none" stroke="#2d7a4f" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
</svg>
<h4>Belum ada artikel budidaya</h4>
<p>Klik <strong>Tambah Artikel</strong> untuk membuat artikel pertama.</p>
</div>
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
{{-- Pagination --}}
@if($artikels->hasPages())
<div class="pagination-wrap">
{{ $artikels->links() }}
</div>
@endif
</div> </div>
@endsection </div>
@endsection

View File

@ -8,206 +8,198 @@
@endpush @endpush
@section('content') @section('content')
<div class="bg-white rounded-2xl shadow-sm border border-gray-100"> <div style="background:white; border-radius:1.25rem; box-shadow:0 1px 4px rgba(0,0,0,0.07); border:1px solid #f0fdf4; overflow:hidden;">
{{-- Form Header --}} {{-- Header --}}
<div class="px-8 py-5 border-b border-gray-100 flex items-center gap-3"> <div style="padding:1.25rem 1.5rem; border-bottom:1px solid #f3f4f6; display:flex; align-items:center; gap:0.75rem;">
<div class="w-10 h-10 rounded-xl bg-red-50 flex items-center justify-center"> <div style="width:2.5rem; height:2.5rem; background:#dcfce7; border-radius:0.75rem; display:flex; align-items:center; justify-content:center; flex-shrink:0;">
<i class="bi bi-plus-circle text-red-500 text-lg"></i> <svg style="width:1.25rem; height:1.25rem; color:#16a34a;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"/>
</svg>
</div> </div>
<div> <div>
<h3 class="font-bold text-gray-800 text-base leading-tight">Tambah Artikel Baru</h3> <div style="font-size:0.9rem; font-weight:700; color:#111827;">Tambah Artikel Baru</div>
<p class="text-xs text-gray-400 mt-0.5">Isi formulir di bawah untuk menambahkan artikel hama & penyakit kopi</p> <div style="font-size:0.75rem; color:#9ca3af;">Isi formulir di bawah untuk menambahkan artikel hama & penyakit kopi</div>
</div> </div>
</div> </div>
<div class="p-8"> <div style="padding:2rem;">
<form action="{{ route('admin.artikel-hama-penyakit.store') }}" method="POST" enctype="multipart/form-data"> <form action="{{ route('admin.artikel-hama-penyakit.store') }}" method="POST" enctype="multipart/form-data">
@csrf @csrf
<div class="space-y-7"> <div style="display:flex; flex-direction:column; gap:1.5rem;">
{{-- Judul & Jenis --}} {{-- Judul & Jenis --}}
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> <div style="display:grid; grid-template-columns:1fr 1fr; gap:1.25rem;">
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">
Judul <span class="text-red-500">*</span> Judul <span style="color:#dc2626;">*</span>
</label> </label>
<input type="text" name="judul" value="{{ old('judul') }}" <input type="text" name="judul" value="{{ old('judul') }}"
class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-800 placeholder-gray-300 focus:ring-2 focus:ring-red-400 focus:border-transparent transition @error('judul') border-red-400 bg-red-50 @enderror" class="@error('judul') border-red-300 bg-red-50 @enderror"
style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; box-sizing:border-box;"
placeholder="Masukkan judul artikel..."> placeholder="Masukkan judul artikel...">
@error('judul') @error('judul')
<p class="text-red-500 text-xs mt-1.5 flex items-center gap-1"> <p style="color:#dc2626; font-size:0.75rem; margin-top:0.375rem; display:flex; align-items:center; gap:0.25rem;">
<i class="bi bi-exclamation-circle"></i> {{ $message }} <svg style="width:0.875rem; height:0.875rem;" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"/></svg>
{{ $message }}
</p> </p>
@enderror @enderror
</div> </div>
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">
Jenis <span class="text-red-500">*</span> Jenis <span style="color:#dc2626;">*</span>
</label> </label>
<div class="relative"> <div style="position:relative;">
<select name="jenis" class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-800 focus:ring-2 focus:ring-red-400 focus:border-transparent appearance-none transition bg-white @error('jenis') border-red-400 bg-red-50 @enderror"> <select name="jenis"
style="width:100%; padding:0.75rem 2.5rem 0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; background:white; appearance:none; outline:none; box-sizing:border-box;">
<option value="">-- Pilih Jenis --</option> <option value="">-- Pilih Jenis --</option>
<option value="Hama" {{ old('jenis') === 'Hama' ? 'selected' : '' }}>Hama</option> <option value="Hama" {{ old('jenis') === 'Hama' ? 'selected' : '' }}>Hama</option>
<option value="Penyakit" {{ old('jenis') === 'Penyakit' ? 'selected' : '' }}>Penyakit</option> <option value="Penyakit" {{ old('jenis') === 'Penyakit' ? 'selected' : '' }}>Penyakit</option>
</select> </select>
<i class="bi bi-chevron-down absolute right-4 top-1/2 -translate-y-1/2 text-gray-400 text-xs pointer-events-none"></i> <svg style="position:absolute; right:0.875rem; top:50%; transform:translateY(-50%); width:1rem; height:1rem; color:#9ca3af; pointer-events:none;" 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>
</div> </div>
@error('jenis') @error('jenis')
<p class="text-red-500 text-xs mt-1.5 flex items-center gap-1"> <p style="color:#dc2626; font-size:0.75rem; margin-top:0.375rem;">{{ $message }}</p>
<i class="bi bi-exclamation-circle"></i> {{ $message }}
</p>
@enderror @enderror
</div> </div>
</div> </div>
{{-- Deskripsi Singkat --}} {{-- Deskripsi Singkat --}}
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2">Deskripsi Singkat</label> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Deskripsi Singkat</label>
<textarea name="deskripsi_singkat" rows="3" <textarea name="deskripsi_singkat" rows="3"
class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-800 placeholder-gray-300 focus:ring-2 focus:ring-red-400 focus:border-transparent transition resize-none" style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; resize:none; box-sizing:border-box;"
placeholder="Ringkasan singkat artikel...">{{ old('deskripsi_singkat') }}</textarea> placeholder="Ringkasan singkat artikel...">{{ old('deskripsi_singkat') }}</textarea>
</div> </div>
{{-- Konten --}} {{-- Konten --}}
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">
Konten <span class="text-red-500">*</span> Konten <span style="color:#dc2626;">*</span>
</label> </label>
<textarea name="konten" rows="8" <textarea name="konten" rows="8"
class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-800 placeholder-gray-300 focus:ring-2 focus:ring-red-400 focus:border-transparent transition resize-y @error('konten') border-red-400 bg-red-50 @enderror" class="@error('konten') border-red-300 bg-red-50 @enderror"
style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; resize:vertical; box-sizing:border-box;"
placeholder="Tulis konten artikel secara lengkap...">{{ old('konten') }}</textarea> placeholder="Tulis konten artikel secara lengkap...">{{ old('konten') }}</textarea>
@error('konten') @error('konten')
<p class="text-red-500 text-xs mt-1.5 flex items-center gap-1"> <p style="color:#dc2626; font-size:0.75rem; margin-top:0.375rem;">{{ $message }}</p>
<i class="bi bi-exclamation-circle"></i> {{ $message }}
</p>
@enderror @enderror
</div> </div>
{{-- Informasi Teknis --}} {{-- Informasi Teknis --}}
<div class="border border-gray-100 rounded-2xl overflow-hidden"> <div style="border:1px solid #e5e7eb; border-radius:1rem; overflow:hidden;">
<div class="px-6 py-4 bg-gray-50 border-b border-gray-100 flex items-center gap-2"> <div style="padding:0.875rem 1.25rem; background:#f9fafb; border-bottom:1px solid #f3f4f6; display:flex; align-items:center; gap:0.5rem;">
<i class="bi bi-clipboard2-pulse text-gray-500 text-base"></i> <svg style="width:1rem; height:1rem; color:#6b7280;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<h4 class="font-semibold text-gray-700 text-sm">Informasi Teknis</h4> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
</svg>
<span style="font-size:0.875rem; font-weight:600; color:#374151;">Informasi Teknis</span>
</div> </div>
<div class="p-6 space-y-5"> <div style="padding:1.25rem; display:flex; flex-direction:column; gap:1.25rem;">
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Gejala Visual</label>
<i class="bi bi-eye text-gray-400 mr-1"></i>Gejala Visual
</label>
<textarea name="gejala_visual" rows="3" <textarea name="gejala_visual" rows="3"
class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-800 placeholder-gray-300 focus:ring-2 focus:ring-red-400 focus:border-transparent transition resize-none" style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; resize:none; box-sizing:border-box;"
placeholder="Deskripsikan gejala yang terlihat pada tanaman...">{{ old('gejala_visual') }}</textarea> placeholder="Deskripsikan gejala yang terlihat pada tanaman...">{{ old('gejala_visual') }}</textarea>
</div> </div>
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Cara Identifikasi</label>
<i class="bi bi-search text-gray-400 mr-1"></i>Cara Identifikasi
</label>
<textarea name="cara_identifikasi" rows="3" <textarea name="cara_identifikasi" rows="3"
class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-800 placeholder-gray-300 focus:ring-2 focus:ring-red-400 focus:border-transparent transition resize-none" style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; resize:none; box-sizing:border-box;"
placeholder="Cara mengidentifikasi hama/penyakit ini...">{{ old('cara_identifikasi') }}</textarea> placeholder="Cara mengidentifikasi hama/penyakit ini...">{{ old('cara_identifikasi') }}</textarea>
</div> </div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-5"> <div style="display:grid; grid-template-columns:1fr 1fr; gap:1.25rem;">
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Pencegahan</label>
<i class="bi bi-shield-check text-gray-400 mr-1"></i>Pencegahan
</label>
<textarea name="pencegahan" rows="4" <textarea name="pencegahan" rows="4"
class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-800 placeholder-gray-300 focus:ring-2 focus:ring-red-400 focus:border-transparent transition resize-none" style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; resize:none; box-sizing:border-box;"
placeholder="Langkah-langkah pencegahan...">{{ old('pencegahan') }}</textarea> placeholder="Langkah-langkah pencegahan...">{{ old('pencegahan') }}</textarea>
</div> </div>
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Pengendalian</label>
<i class="bi bi-tools text-gray-400 mr-1"></i>Pengendalian
</label>
<textarea name="pengendalian" rows="4" <textarea name="pengendalian" rows="4"
class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-800 placeholder-gray-300 focus:ring-2 focus:ring-red-400 focus:border-transparent transition resize-none" style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; resize:none; box-sizing:border-box;"
placeholder="Cara pengendalian yang efektif...">{{ old('pengendalian') }}</textarea> placeholder="Cara pengendalian...">{{ old('pengendalian') }}</textarea>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{{-- Gambar & PDF --}} {{-- Gambar & PDF --}}
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> <div style="display:grid; grid-template-columns:1fr 1fr; gap:1.25rem;">
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Gambar Utama</label>
<i class="bi bi-image text-gray-400 mr-1"></i>Gambar Utama
</label>
<input type="file" name="gambar_utama" accept="image/*" <input type="file" name="gambar_utama" accept="image/*"
class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-600 file:mr-3 file:py-1 file:px-3 file:rounded-lg file:border-0 file:text-xs file:font-semibold file:bg-red-50 file:text-red-600 hover:file:bg-red-100 transition"> style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#6b7280; box-sizing:border-box;">
<p class="text-xs text-gray-400 mt-1.5 flex items-center gap-1"> <p style="font-size:0.7rem; color:#9ca3af; margin-top:0.375rem;">Format: JPG, PNG. Maks 2MB</p>
<i class="bi bi-info-circle"></i> Format: JPG, PNG. Maks 2MB
</p>
</div> </div>
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">File PDF</label>
<i class="bi bi-file-earmark-pdf text-gray-400 mr-1"></i>File PDF
</label>
<input type="file" name="file_pdf" accept=".pdf" <input type="file" name="file_pdf" accept=".pdf"
class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-600 file:mr-3 file:py-1 file:px-3 file:rounded-lg file:border-0 file:text-xs file:font-semibold file:bg-red-50 file:text-red-600 hover:file:bg-red-100 transition"> style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#6b7280; box-sizing:border-box;">
<p class="text-xs text-gray-400 mt-1.5 flex items-center gap-1"> <p style="font-size:0.7rem; color:#9ca3af; margin-top:0.375rem;">Format: PDF. Maks 5MB</p>
<i class="bi bi-info-circle"></i> Format: PDF. Maks 5MB
</p>
</div> </div>
</div> </div>
{{-- Tags --}} {{-- Tags --}}
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Tags</label>
<i class="bi bi-tags text-gray-400 mr-1"></i>Tags
</label>
<div id="tags-container" <div id="tags-container"
class="w-full px-4 py-3 border border-gray-200 rounded-xl flex flex-wrap gap-2 min-h-[50px] bg-gray-50/50 cursor-text" style="width:100%; padding:0.625rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; display:flex; flex-wrap:wrap; gap:0.5rem; min-height:3rem; background:#fafafa; cursor:text; box-sizing:border-box;"
onclick="document.getElementById('tags-input').focus()"> onclick="document.getElementById('tags-input').focus()">
</div> </div>
<input type="text" id="tags-input" <input type="text" id="tags-input"
class="w-full mt-2 px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-800 placeholder-gray-300 focus:ring-2 focus:ring-red-400 focus:border-transparent transition" style="width:100%; margin-top:0.5rem; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; box-sizing:border-box;"
placeholder="Ketik tag lalu tekan Enter atau koma..."> placeholder="Ketik tag lalu tekan Enter atau koma...">
<p class="text-xs text-gray-400 mt-1.5 flex items-center gap-1"> <p style="font-size:0.7rem; color:#9ca3af; margin-top:0.375rem;">Tekan Enter atau koma untuk menambah tag</p>
<i class="bi bi-keyboard"></i> Tekan Enter atau koma untuk menambah tag
</p>
<input type="hidden" name="tags" id="tags-hidden" value="[]"> <input type="hidden" name="tags" id="tags-hidden" value="[]">
</div> </div>
{{-- Galeri Gambar --}} {{-- Galeri Gambar --}}
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Galeri Gambar</label>
<i class="bi bi-images text-gray-400 mr-1"></i>Galeri Gambar
</label>
<input type="file" name="galeri_gambar[]" accept="image/*" multiple <input type="file" name="galeri_gambar[]" accept="image/*" multiple
class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-600 file:mr-3 file:py-1 file:px-3 file:rounded-lg file:border-0 file:text-xs file:font-semibold file:bg-red-50 file:text-red-600 hover:file:bg-red-100 transition"> style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#6b7280; box-sizing:border-box;">
<p class="text-xs text-gray-400 mt-1.5 flex items-center gap-1"> <p style="font-size:0.7rem; color:#9ca3af; margin-top:0.375rem;">Bisa pilih beberapa foto sekaligus. Format: JPG, PNG. Maks 2MB per foto</p>
<i class="bi bi-info-circle"></i> Bisa pilih beberapa foto sekaligus. Format: JPG, PNG. Maks 2MB per foto
</p>
</div> </div>
{{-- Status Publish --}} {{-- Status Publish --}}
<div class="flex items-center gap-3 p-4 rounded-xl border border-gray-100 bg-gray-50/60"> <div style="display:flex; align-items:center; gap:0.75rem; padding:1rem; border:1px solid #e5e7eb; border-radius:0.75rem; background:#f9fafb;">
<label class="relative inline-flex items-center cursor-pointer"> <div style="position:relative; display:inline-flex; align-items:center; cursor:pointer;" onclick="togglePublish('is_published', 'track_is_published', 'knob_is_published')">
<input type="checkbox" name="is_published" value="1" id="is_published" <input type="checkbox" name="is_published" value="1" id="is_published"
{{ old('is_published') ? 'checked' : '' }} {{ old('is_published') ? 'checked' : '' }}
class="sr-only peer"> style="position:absolute; opacity:0; width:0; height:0;">
<div class="w-10 h-5 bg-gray-200 rounded-full peer peer-checked:bg-red-500 peer-focus:ring-2 peer-focus:ring-red-300 transition-all after:content-[''] after:absolute after:top-0.5 after:left-0.5 after:bg-white after:rounded-full after:h-4 after:w-4 after:transition-all peer-checked:after:translate-x-5"></div> <div id="track_is_published"
</label> style="width:2.5rem; height:1.375rem; border-radius:9999px; transition:background 0.2s; background:{{ old('is_published') ? '#16a34a' : '#d1d5db' }}; position:relative; flex-shrink:0;">
<div id="knob_is_published"
style="position:absolute; top:0.1875rem; width:1rem; height:1rem; background:white; border-radius:9999px; box-shadow:0 1px 3px rgba(0,0,0,0.2); transition:left 0.2s; left:{{ old('is_published') ? '1.25rem' : '0.1875rem' }};"></div>
</div>
</div>
<div> <div>
<label for="is_published" class="text-sm font-semibold text-gray-700 cursor-pointer">Publikasikan Sekarang</label> <label for="is_published" style="font-size:0.875rem; font-weight:600; color:#374151; cursor:pointer;" onclick="togglePublish('is_published', 'track_is_published', 'knob_is_published')">Publikasikan Sekarang</label>
<p class="text-xs text-gray-400">Artikel akan langsung tampil di halaman publik</p> <p style="font-size:0.75rem; color:#9ca3af;">Artikel akan langsung tampil di halaman publik</p>
</div> </div>
</div> </div>
</div> </div>
{{-- Action Buttons --}} {{-- Action Buttons --}}
<div class="flex items-center justify-between mt-8 pt-6 border-t border-gray-100"> <div style="display:flex; align-items:center; justify-content:space-between; margin-top:2rem; padding-top:1.5rem; border-top:1px solid #f3f4f6;">
<a href="{{ route('admin.artikel-hama-penyakit.index') }}" <a href="{{ route('admin.artikel-hama-penyakit.index') }}"
class="inline-flex items-center gap-2 px-5 py-2.5 border border-gray-200 text-gray-600 text-sm font-semibold rounded-xl hover:bg-gray-50 hover:border-gray-300 transition"> style="display:inline-flex; align-items:center; gap:0.5rem; padding:0.625rem 1.25rem; border:1px solid #e5e7eb; color:#6b7280; font-size:0.875rem; font-weight:600; border-radius:0.75rem; text-decoration:none; background:white;">
<i class="bi bi-arrow-left"></i> Batal <svg style="width:1rem; height:1rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
</svg>
Batal
</a> </a>
<button type="submit" <button type="submit"
class="inline-flex items-center gap-2 px-6 py-2.5 bg-gradient-to-r from-red-500 to-red-600 text-white text-sm font-bold rounded-xl hover:from-red-600 hover:to-red-700 transition shadow-md shadow-red-100 active:scale-95"> style="display:inline-flex; align-items:center; gap:0.5rem; padding:0.625rem 1.5rem; background:#16a34a; color:white; font-size:0.875rem; font-weight:700; border-radius:0.75rem; border:none; cursor:pointer;">
<i class="bi bi-floppy2-fill"></i> Simpan Artikel <svg style="width:1rem; height:1rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
</svg>
Simpan Artikel
</button> </button>
</div> </div>
</form> </form>
@ -226,13 +218,10 @@ function renderTags() {
tagsContainer.innerHTML = ''; tagsContainer.innerHTML = '';
tags.forEach((tag, index) => { tags.forEach((tag, index) => {
tagsContainer.innerHTML += ` tagsContainer.innerHTML += `
<span class="inline-flex items-center gap-1.5 px-3 py-1 bg-red-50 text-red-700 text-xs font-semibold rounded-lg border border-red-100"> <span style="display:inline-flex; align-items:center; gap:0.375rem; padding:0.25rem 0.625rem; background:#dcfce7; color:#15803d; font-size:0.75rem; font-weight:600; border-radius:0.5rem; border:1px solid #bbf7d0;">
<i class="bi bi-tag-fill text-red-400 text-[10px]"></i>
${tag} ${tag}
<button type="button" onclick="removeTag(${index})" <button type="button" onclick="removeTag(${index})"
class="ml-0.5 text-red-300 hover:text-red-600 transition leading-none"> style="color:#86efac; background:none; border:none; cursor:pointer; line-height:1; font-size:0.875rem;">&times;</button>
<i class="bi bi-x-lg text-[10px]"></i>
</button>
</span>`; </span>`;
}); });
tagsHidden.value = JSON.stringify(tags); tagsHidden.value = JSON.stringify(tags);
@ -247,12 +236,22 @@ function removeTag(index) {
if (e.key === 'Enter' || e.key === ',') { if (e.key === 'Enter' || e.key === ',') {
e.preventDefault(); e.preventDefault();
const val = tagsInput.value.trim(); const val = tagsInput.value.trim();
if (val) { if (val) { tags.push(val); tagsInput.value = ''; renderTags(); }
tags.push(val);
tagsInput.value = '';
renderTags();
}
} }
}); });
function togglePublish(cbId, trackId, knobId) {
const cb = document.getElementById(cbId);
const track = document.getElementById(trackId);
const knob = document.getElementById(knobId);
cb.checked = !cb.checked;
if (cb.checked) {
track.style.background = '#16a34a';
knob.style.left = '1.25rem';
} else {
track.style.background = '#d1d5db';
knob.style.left = '0.1875rem';
}
}
</script> </script>
@endpush @endpush

View File

@ -8,116 +8,113 @@
@endpush @endpush
@section('content') @section('content')
<div class="bg-white rounded-2xl shadow-sm border border-gray-100"> <div style="background:white; border-radius:1.25rem; box-shadow:0 1px 4px rgba(0,0,0,0.07); border:1px solid #f0fdf4; overflow:hidden;">
{{-- Form Header --}} {{-- Header --}}
<div class="px-8 py-5 border-b border-gray-100 flex items-center gap-3"> <div style="padding:1.25rem 1.5rem; border-bottom:1px solid #f3f4f6; display:flex; align-items:center; gap:0.75rem;">
<div class="w-10 h-10 rounded-xl bg-red-50 flex items-center justify-center"> <div style="width:2.5rem; height:2.5rem; background:#dcfce7; border-radius:0.75rem; display:flex; align-items:center; justify-content:center; flex-shrink:0;">
<i class="bi bi-pencil-square text-red-500 text-lg"></i> <svg style="width:1.25rem; height:1.25rem; color:#16a34a;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
</svg>
</div> </div>
<div> <div>
<h3 class="font-bold text-gray-800 text-base leading-tight">Edit Artikel</h3> <div style="font-size:0.9rem; font-weight:700; color:#111827;">Edit Artikel</div>
<p class="text-xs text-gray-400 mt-0.5">Perbarui informasi hama dan penyakit kopi</p> <div style="font-size:0.75rem; color:#9ca3af;">Perbarui informasi hama dan penyakit kopi</div>
</div> </div>
</div> </div>
<div class="p-8"> <div style="padding:2rem;">
<form action="{{ route('admin.artikel-hama-penyakit.update', $artikelHamaPenyakit) }}" method="POST" enctype="multipart/form-data"> <form action="{{ route('admin.artikel-hama-penyakit.update', $artikelHamaPenyakit) }}" method="POST" enctype="multipart/form-data">
@csrf @csrf
@method('PUT') @method('PUT')
<div class="space-y-7"> <div style="display:flex; flex-direction:column; gap:1.5rem;">
{{-- Judul & Jenis --}} {{-- Judul & Jenis --}}
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> <div style="display:grid; grid-template-columns:1fr 1fr; gap:1.25rem;">
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">
Judul <span class="text-red-500">*</span> Judul <span style="color:#dc2626;">*</span>
</label> </label>
<input type="text" name="judul" value="{{ old('judul', $artikelHamaPenyakit->judul) }}" <input type="text" name="judul" value="{{ old('judul', $artikelHamaPenyakit->judul) }}"
class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-800 placeholder-gray-300 focus:ring-2 focus:ring-red-400 focus:border-transparent transition @error('judul') border-red-400 bg-red-50 @enderror" class="@error('judul') border-red-300 bg-red-50 @enderror"
style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; box-sizing:border-box;"
placeholder="Judul artikel..."> placeholder="Judul artikel...">
@error('judul') @error('judul')
<p class="text-red-500 text-xs mt-1.5 flex items-center gap-1"> <p style="color:#dc2626; font-size:0.75rem; margin-top:0.375rem;">{{ $message }}</p>
<i class="bi bi-exclamation-circle"></i> {{ $message }}
</p>
@enderror @enderror
</div> </div>
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">
Jenis <span class="text-red-500">*</span> Jenis <span style="color:#dc2626;">*</span>
</label> </label>
<div class="relative"> <div style="position:relative;">
<select name="jenis" class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-800 focus:ring-2 focus:ring-red-400 focus:border-transparent appearance-none transition bg-white"> <select name="jenis"
style="width:100%; padding:0.75rem 2.5rem 0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; background:white; appearance:none; outline:none; box-sizing:border-box;">
<option value="Hama" {{ old('jenis', $artikelHamaPenyakit->jenis) === 'Hama' ? 'selected' : '' }}>Hama</option> <option value="Hama" {{ old('jenis', $artikelHamaPenyakit->jenis) === 'Hama' ? 'selected' : '' }}>Hama</option>
<option value="Penyakit" {{ old('jenis', $artikelHamaPenyakit->jenis) === 'Penyakit' ? 'selected' : '' }}>Penyakit</option> <option value="Penyakit" {{ old('jenis', $artikelHamaPenyakit->jenis) === 'Penyakit' ? 'selected' : '' }}>Penyakit</option>
</select> </select>
<i class="bi bi-chevron-down absolute right-4 top-1/2 -translate-y-1/2 text-gray-400 text-xs pointer-events-none"></i> <svg style="position:absolute; right:0.875rem; top:50%; transform:translateY(-50%); width:1rem; height:1rem; color:#9ca3af; pointer-events:none;" 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>
</div> </div>
</div> </div>
</div> </div>
{{-- Deskripsi Singkat --}} {{-- Deskripsi Singkat --}}
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2">Deskripsi Singkat</label> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Deskripsi Singkat</label>
<textarea name="deskripsi_singkat" rows="3" <textarea name="deskripsi_singkat" rows="3"
class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-800 placeholder-gray-300 focus:ring-2 focus:ring-red-400 focus:border-transparent transition resize-none" style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; resize:none; box-sizing:border-box;"
placeholder="Ringkasan singkat artikel...">{{ old('deskripsi_singkat', $artikelHamaPenyakit->deskripsi_singkat) }}</textarea> placeholder="Ringkasan singkat artikel...">{{ old('deskripsi_singkat', $artikelHamaPenyakit->deskripsi_singkat) }}</textarea>
</div> </div>
{{-- Konten --}} {{-- Konten --}}
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">
Konten <span class="text-red-500">*</span> Konten <span style="color:#dc2626;">*</span>
</label> </label>
<textarea name="konten" rows="8" <textarea name="konten" rows="8"
class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-800 placeholder-gray-300 focus:ring-2 focus:ring-red-400 focus:border-transparent transition resize-y @error('konten') border-red-400 bg-red-50 @enderror" class="@error('konten') border-red-300 bg-red-50 @enderror"
style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; resize:vertical; box-sizing:border-box;"
placeholder="Tulis konten artikel...">{{ old('konten', $artikelHamaPenyakit->konten) }}</textarea> placeholder="Tulis konten artikel...">{{ old('konten', $artikelHamaPenyakit->konten) }}</textarea>
@error('konten') @error('konten')
<p class="text-red-500 text-xs mt-1.5 flex items-center gap-1"> <p style="color:#dc2626; font-size:0.75rem; margin-top:0.375rem;">{{ $message }}</p>
<i class="bi bi-exclamation-circle"></i> {{ $message }}
</p>
@enderror @enderror
</div> </div>
{{-- Informasi Teknis --}} {{-- Informasi Teknis --}}
<div class="border border-gray-100 rounded-2xl overflow-hidden"> <div style="border:1px solid #e5e7eb; border-radius:1rem; overflow:hidden;">
<div class="px-6 py-4 bg-gray-50 border-b border-gray-100 flex items-center gap-2"> <div style="padding:0.875rem 1.25rem; background:#f9fafb; border-bottom:1px solid #f3f4f6; display:flex; align-items:center; gap:0.5rem;">
<i class="bi bi-clipboard2-pulse text-gray-500 text-base"></i> <svg style="width:1rem; height:1rem; color:#6b7280;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<h4 class="font-semibold text-gray-700 text-sm">Informasi Teknis</h4> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
</svg>
<span style="font-size:0.875rem; font-weight:600; color:#374151;">Informasi Teknis</span>
</div> </div>
<div class="p-6 space-y-5"> <div style="padding:1.25rem; display:flex; flex-direction:column; gap:1.25rem;">
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Gejala Visual</label>
<i class="bi bi-eye text-gray-400 mr-1"></i>Gejala Visual
</label>
<textarea name="gejala_visual" rows="3" <textarea name="gejala_visual" rows="3"
class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-800 placeholder-gray-300 focus:ring-2 focus:ring-red-400 focus:border-transparent transition resize-none" style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; resize:none; box-sizing:border-box;"
placeholder="Deskripsikan gejala yang terlihat...">{{ old('gejala_visual', $artikelHamaPenyakit->gejala_visual) }}</textarea> placeholder="Deskripsikan gejala yang terlihat...">{{ old('gejala_visual', $artikelHamaPenyakit->gejala_visual) }}</textarea>
</div> </div>
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Cara Identifikasi</label>
<i class="bi bi-search text-gray-400 mr-1"></i>Cara Identifikasi
</label>
<textarea name="cara_identifikasi" rows="3" <textarea name="cara_identifikasi" rows="3"
class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-800 placeholder-gray-300 focus:ring-2 focus:ring-red-400 focus:border-transparent transition resize-none" style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; resize:none; box-sizing:border-box;"
placeholder="Cara mengidentifikasi...">{{ old('cara_identifikasi', $artikelHamaPenyakit->cara_identifikasi) }}</textarea> placeholder="Cara mengidentifikasi...">{{ old('cara_identifikasi', $artikelHamaPenyakit->cara_identifikasi) }}</textarea>
</div> </div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-5"> <div style="display:grid; grid-template-columns:1fr 1fr; gap:1.25rem;">
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Pencegahan</label>
<i class="bi bi-shield-check text-gray-400 mr-1"></i>Pencegahan
</label>
<textarea name="pencegahan" rows="4" <textarea name="pencegahan" rows="4"
class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-800 placeholder-gray-300 focus:ring-2 focus:ring-red-400 focus:border-transparent transition resize-none" style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; resize:none; box-sizing:border-box;"
placeholder="Langkah pencegahan...">{{ old('pencegahan', $artikelHamaPenyakit->pencegahan) }}</textarea> placeholder="Langkah pencegahan...">{{ old('pencegahan', $artikelHamaPenyakit->pencegahan) }}</textarea>
</div> </div>
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Pengendalian</label>
<i class="bi bi-tools text-gray-400 mr-1"></i>Pengendalian
</label>
<textarea name="pengendalian" rows="4" <textarea name="pengendalian" rows="4"
class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-800 placeholder-gray-300 focus:ring-2 focus:ring-red-400 focus:border-transparent transition resize-none" style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; resize:none; box-sizing:border-box;"
placeholder="Cara pengendalian...">{{ old('pengendalian', $artikelHamaPenyakit->pengendalian) }}</textarea> placeholder="Cara pengendalian...">{{ old('pengendalian', $artikelHamaPenyakit->pengendalian) }}</textarea>
</div> </div>
</div> </div>
@ -125,106 +122,99 @@ class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-800
</div> </div>
{{-- Gambar & PDF --}} {{-- Gambar & PDF --}}
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> <div style="display:grid; grid-template-columns:1fr 1fr; gap:1.25rem;">
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Gambar Utama</label>
<i class="bi bi-image text-gray-400 mr-1"></i>Gambar Utama
</label>
@if($artikelHamaPenyakit->gambar_utama) @if($artikelHamaPenyakit->gambar_utama)
<div class="mb-3 relative inline-block"> <img src="{{ Storage::url($artikelHamaPenyakit->gambar_utama) }}"
<img src="{{ Storage::url($artikelHamaPenyakit->gambar_utama) }}" style="width:100%; height:8rem; object-fit:cover; border-radius:0.75rem; border:1px solid #e5e7eb; margin-bottom:0.5rem;">
class="w-32 h-24 object-cover rounded-xl border border-gray-200 shadow-sm">
<span class="absolute -top-1.5 -right-1.5 bg-green-500 text-white text-[10px] font-bold px-1.5 py-0.5 rounded-full">Aktif</span>
</div>
@endif @endif
<input type="file" name="gambar_utama" accept="image/*" <input type="file" name="gambar_utama" accept="image/*"
class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-600 file:mr-3 file:py-1 file:px-3 file:rounded-lg file:border-0 file:text-xs file:font-semibold file:bg-red-50 file:text-red-600 hover:file:bg-red-100 transition"> style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#6b7280; box-sizing:border-box;">
<p class="text-xs text-gray-400 mt-1.5 flex items-center gap-1"> <p style="font-size:0.7rem; color:#9ca3af; margin-top:0.375rem;">Kosongkan jika tidak ingin mengubah</p>
<i class="bi bi-info-circle"></i> Kosongkan jika tidak ingin mengubah
</p>
</div> </div>
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">File PDF</label>
<i class="bi bi-file-earmark-pdf text-gray-400 mr-1"></i>File PDF
</label>
@if($artikelHamaPenyakit->file_pdf) @if($artikelHamaPenyakit->file_pdf)
<a href="{{ Storage::url($artikelHamaPenyakit->file_pdf) }}" target="_blank" <a href="{{ Storage::url($artikelHamaPenyakit->file_pdf) }}" target="_blank"
class="inline-flex items-center gap-1.5 text-xs text-red-500 font-medium hover:text-red-700 mb-3 border border-red-100 bg-red-50 px-3 py-1.5 rounded-lg transition"> style="display:inline-flex; align-items:center; gap:0.375rem; font-size:0.75rem; color:#16a34a; text-decoration:none; margin-bottom:0.5rem; font-weight:600;">
<i class="bi bi-file-earmark-pdf-fill"></i> Lihat PDF saat ini <svg style="width:0.875rem; height:0.875rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<i class="bi bi-box-arrow-up-right text-[10px]"></i> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
</svg>
Lihat PDF saat ini
</a> </a>
@endif @endif
<input type="file" name="file_pdf" accept=".pdf" <input type="file" name="file_pdf" accept=".pdf"
class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-600 file:mr-3 file:py-1 file:px-3 file:rounded-lg file:border-0 file:text-xs file:font-semibold file:bg-red-50 file:text-red-600 hover:file:bg-red-100 transition"> style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#6b7280; box-sizing:border-box;">
<p class="text-xs text-gray-400 mt-1.5 flex items-center gap-1"> <p style="font-size:0.7rem; color:#9ca3af; margin-top:0.375rem;">Kosongkan jika tidak ingin mengubah</p>
<i class="bi bi-info-circle"></i> Kosongkan jika tidak ingin mengubah
</p>
</div> </div>
</div> </div>
{{-- Tags --}} {{-- Tags --}}
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Tags</label>
<i class="bi bi-tags text-gray-400 mr-1"></i>Tags
</label>
<div id="tags-container" <div id="tags-container"
class="w-full px-4 py-3 border border-gray-200 rounded-xl flex flex-wrap gap-2 min-h-[50px] bg-gray-50/50 cursor-text" style="width:100%; padding:0.625rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; display:flex; flex-wrap:wrap; gap:0.5rem; min-height:3rem; background:#fafafa; cursor:text; box-sizing:border-box;"
onclick="document.getElementById('tags-input').focus()"> onclick="document.getElementById('tags-input').focus()">
</div> </div>
<input type="text" id="tags-input" <input type="text" id="tags-input"
class="w-full mt-2 px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-800 placeholder-gray-300 focus:ring-2 focus:ring-red-400 focus:border-transparent transition" style="width:100%; margin-top:0.5rem; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; box-sizing:border-box;"
placeholder="Ketik tag lalu tekan Enter atau koma..."> placeholder="Ketik tag lalu tekan Enter atau koma...">
<p class="text-xs text-gray-400 mt-1.5 flex items-center gap-1"> <p style="font-size:0.7rem; color:#9ca3af; margin-top:0.375rem;">Tekan Enter atau koma untuk menambah tag</p>
<i class="bi bi-keyboard"></i> Tekan Enter atau koma untuk menambah tag
</p>
<input type="hidden" name="tags" id="tags-hidden" value="[]"> <input type="hidden" name="tags" id="tags-hidden" value="[]">
</div> </div>
{{-- Galeri Gambar --}} {{-- Galeri Gambar --}}
<div> <div>
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Galeri Gambar</label>
<i class="bi bi-images text-gray-400 mr-1"></i>Galeri Gambar
</label>
@if($artikelHamaPenyakit->galeri_gambar) @if($artikelHamaPenyakit->galeri_gambar)
<div class="flex flex-wrap gap-2 mb-3"> <div style="display:flex; flex-wrap:wrap; gap:0.5rem; margin-bottom:0.75rem;">
@foreach($artikelHamaPenyakit->galeri_gambar as $foto) @foreach($artikelHamaPenyakit->galeri_gambar as $foto)
<img src="{{ Storage::url($foto) }}" <img src="{{ Storage::url($foto) }}"
class="w-24 h-20 object-cover rounded-xl border border-gray-200 shadow-sm"> style="width:5rem; height:4rem; object-fit:cover; border-radius:0.75rem; border:1px solid #e5e7eb;">
@endforeach @endforeach
</div> </div>
@endif @endif
<input type="file" name="galeri_gambar[]" accept="image/*" multiple <input type="file" name="galeri_gambar[]" accept="image/*" multiple
class="w-full px-4 py-3 border border-gray-200 rounded-xl text-sm text-gray-600 file:mr-3 file:py-1 file:px-3 file:rounded-lg file:border-0 file:text-xs file:font-semibold file:bg-red-50 file:text-red-600 hover:file:bg-red-100 transition"> style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#6b7280; box-sizing:border-box;">
<p class="text-xs text-gray-400 mt-1.5 flex items-center gap-1"> <p style="font-size:0.7rem; color:#9ca3af; margin-top:0.375rem;">Upload foto baru akan menggantikan galeri yang lama</p>
<i class="bi bi-exclamation-triangle"></i> Upload foto baru akan menggantikan galeri yang lama
</p>
</div> </div>
{{-- Status Publish --}} {{-- Status Publish --}}
<div class="flex items-center gap-3 p-4 rounded-xl border border-gray-100 bg-gray-50/60"> <div style="display:flex; align-items:center; gap:0.75rem; padding:1rem; border:1px solid #e5e7eb; border-radius:0.75rem; background:#f9fafb;">
<label class="relative inline-flex items-center cursor-pointer"> <div style="position:relative; display:inline-flex; align-items:center; cursor:pointer; flex-shrink:0;" onclick="togglePublish('is_published', 'track_is_published', 'knob_is_published')">
<input type="checkbox" name="is_published" value="1" id="is_published" <input type="checkbox" name="is_published" value="1" id="is_published"
{{ old('is_published', $artikelHamaPenyakit->is_published) ? 'checked' : '' }} {{ old('is_published', $artikelHamaPenyakit->is_published) ? 'checked' : '' }}
class="sr-only peer"> style="position:absolute; opacity:0; width:0; height:0;">
<div class="w-10 h-5 bg-gray-200 rounded-full peer peer-checked:bg-red-500 peer-focus:ring-2 peer-focus:ring-red-300 transition-all after:content-[''] after:absolute after:top-0.5 after:left-0.5 after:bg-white after:rounded-full after:h-4 after:w-4 after:transition-all peer-checked:after:translate-x-5"></div> <div id="track_is_published"
</label> style="width:2.5rem; height:1.375rem; border-radius:9999px; transition:background 0.2s; background:{{ old('is_published', $artikelHamaPenyakit->is_published) ? '#16a34a' : '#d1d5db' }}; position:relative;">
<div id="knob_is_published"
style="position:absolute; top:0.1875rem; width:1rem; height:1rem; background:white; border-radius:9999px; box-shadow:0 1px 3px rgba(0,0,0,0.2); transition:left 0.2s; left:{{ old('is_published', $artikelHamaPenyakit->is_published) ? '1.25rem' : '0.1875rem' }};"></div>
</div>
</div>
<div> <div>
<label for="is_published" class="text-sm font-semibold text-gray-700 cursor-pointer">Publikasikan Artikel</label> <label for="is_published" style="font-size:0.875rem; font-weight:600; color:#374151; cursor:pointer;" onclick="togglePublish('is_published', 'track_is_published', 'knob_is_published')">Publikasikan Artikel</label>
<p class="text-xs text-gray-400">Artikel akan langsung tampil di halaman publik</p> <p style="font-size:0.75rem; color:#9ca3af;">Artikel akan langsung tampil di halaman publik</p>
</div> </div>
</div> </div>
</div> </div>
{{-- Action Buttons --}} {{-- Action Buttons --}}
<div class="flex items-center justify-between mt-8 pt-6 border-t border-gray-100"> <div style="display:flex; align-items:center; justify-content:space-between; margin-top:2rem; padding-top:1.5rem; border-top:1px solid #f3f4f6;">
<a href="{{ route('admin.artikel-hama-penyakit.index') }}" <a href="{{ route('admin.artikel-hama-penyakit.index') }}"
class="inline-flex items-center gap-2 px-5 py-2.5 border border-gray-200 text-gray-600 text-sm font-semibold rounded-xl hover:bg-gray-50 hover:border-gray-300 transition"> style="display:inline-flex; align-items:center; gap:0.5rem; padding:0.625rem 1.25rem; border:1px solid #e5e7eb; color:#6b7280; font-size:0.875rem; font-weight:600; border-radius:0.75rem; text-decoration:none; background:white;">
<i class="bi bi-arrow-left"></i> Batal <svg style="width:1rem; height:1rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
</svg>
Batal
</a> </a>
<button type="submit" <button type="submit"
class="inline-flex items-center gap-2 px-6 py-2.5 bg-gradient-to-r from-red-500 to-red-600 text-white text-sm font-bold rounded-xl hover:from-red-600 hover:to-red-700 transition shadow-md shadow-red-100 active:scale-95"> style="display:inline-flex; align-items:center; gap:0.5rem; padding:0.625rem 1.5rem; background:#16a34a; color:white; font-size:0.875rem; font-weight:700; border-radius:0.75rem; border:none; cursor:pointer;">
<i class="bi bi-check2-circle"></i> Update Artikel <svg style="width:1rem; height:1rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
</svg>
Update Artikel
</button> </button>
</div> </div>
</form> </form>
@ -237,21 +227,16 @@ class="inline-flex items-center gap-2 px-6 py-2.5 bg-gradient-to-r from-red-500
const tagsInput = document.getElementById('tags-input'); const tagsInput = document.getElementById('tags-input');
const tagsContainer = document.getElementById('tags-container'); const tagsContainer = document.getElementById('tags-container');
const tagsHidden = document.getElementById('tags-hidden'); const tagsHidden = document.getElementById('tags-hidden');
// Load tags yang sudah ada
let tags = {!! json_encode($artikelHamaPenyakit->tags ?? []) !!}; let tags = {!! json_encode($artikelHamaPenyakit->tags ?? []) !!};
function renderTags() { function renderTags() {
tagsContainer.innerHTML = ''; tagsContainer.innerHTML = '';
tags.forEach((tag, index) => { tags.forEach((tag, index) => {
tagsContainer.innerHTML += ` tagsContainer.innerHTML += `
<span class="inline-flex items-center gap-1.5 px-3 py-1 bg-red-50 text-red-700 text-xs font-semibold rounded-lg border border-red-100"> <span style="display:inline-flex; align-items:center; gap:0.375rem; padding:0.25rem 0.625rem; background:#dcfce7; color:#15803d; font-size:0.75rem; font-weight:600; border-radius:0.5rem; border:1px solid #bbf7d0;">
<i class="bi bi-tag-fill text-red-400 text-[10px]"></i>
${tag} ${tag}
<button type="button" onclick="removeTag(${index})" <button type="button" onclick="removeTag(${index})"
class="ml-0.5 text-red-300 hover:text-red-600 transition leading-none"> style="color:#86efac; background:none; border:none; cursor:pointer; line-height:1; font-size:0.875rem;">&times;</button>
<i class="bi bi-x-lg text-[10px]"></i>
</button>
</span>`; </span>`;
}); });
tagsHidden.value = JSON.stringify(tags); tagsHidden.value = JSON.stringify(tags);
@ -266,15 +251,24 @@ function removeTag(index) {
if (e.key === 'Enter' || e.key === ',') { if (e.key === 'Enter' || e.key === ',') {
e.preventDefault(); e.preventDefault();
const val = tagsInput.value.trim(); const val = tagsInput.value.trim();
if (val) { if (val) { tags.push(val); tagsInput.value = ''; renderTags(); }
tags.push(val);
tagsInput.value = '';
renderTags();
}
} }
}); });
// Render tags awal
renderTags(); renderTags();
function togglePublish(cbId, trackId, knobId) {
const cb = document.getElementById(cbId);
const track = document.getElementById(trackId);
const knob = document.getElementById(knobId);
cb.checked = !cb.checked;
if (cb.checked) {
track.style.background = '#16a34a';
knob.style.left = '1.25rem';
} else {
track.style.background = '#d1d5db';
knob.style.left = '0.1875rem';
}
}
</script> </script>
@endpush @endpush

View File

@ -4,107 +4,119 @@
@section('page-subtitle', 'Kelola informasi hama dan penyakit kopi') @section('page-subtitle', 'Kelola informasi hama dan penyakit kopi')
@section('content') @section('content')
@if (session('success'))
<div class="mb-6 bg-green-100 border-l-4 border-green-500 text-green-700 p-4 rounded-lg flex items-center">
<svg class="w-6 h-6 mr-3" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
</svg>
<span class="font-semibold">{{ session('success') }}</span>
</div>
@endif
<div class="bg-white rounded-2xl shadow-lg"> @if(session('success'))
<div class="p-8"> <div style="margin-bottom:1.5rem; background:#f0fdf4; border:1px solid #bbf7d0; color:#15803d; padding:1rem 1.25rem; border-radius:0.75rem; display:flex; align-items:center; gap:0.75rem;">
<div class="flex justify-between items-center mb-6"> <svg style="width:1.25rem; height:1.25rem; flex-shrink:0;" fill="currentColor" viewBox="0 0 20 20">
<div class="flex items-center"> <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
<div class="bg-gradient-to-r from-red-500 to-red-600 rounded-xl p-3 mr-4"> </svg>
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <span style="font-weight:600; font-size:0.875rem;">{{ session('success') }}</span>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
</svg>
</div>
<h3 class="text-xl font-bold text-gray-800">Daftar Artikel Hama & Penyakit</h3>
</div>
<a href="{{ route('admin.artikel-hama-penyakit.create') }}" class="flex items-center px-5 py-3 bg-gradient-to-r from-red-500 to-red-600 text-white font-bold rounded-xl hover:from-red-600 hover:to-red-700 transition-all shadow-lg hover:shadow-xl transform hover:scale-105">
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
</svg>
Tambah Artikel
</a>
</div>
<div class="overflow-x-auto rounded-xl border border-gray-200">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th class="px-6 py-4 text-left text-xs font-bold text-gray-600 uppercase">No</th>
<th class="px-6 py-4 text-left text-xs font-bold text-gray-600 uppercase">Judul</th>
<th class="px-6 py-4 text-left text-xs font-bold text-gray-600 uppercase">Jenis</th>
<th class="px-6 py-4 text-left text-xs font-bold text-gray-600 uppercase">Status</th>
<th class="px-6 py-4 text-left text-xs font-bold text-gray-600 uppercase">Tanggal</th>
<th class="px-6 py-4 text-center text-xs font-bold text-gray-600 uppercase">Aksi</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
@forelse ($artikels as $index => $artikel)
<tr class="hover:bg-gray-50 transition-colors">
<td class="px-6 py-4 text-sm">{{ $artikels->firstItem() + $index }}</td>
<td class="px-6 py-4">
<div class="text-sm font-semibold text-gray-900">{{ $artikel->judul }}</div>
@if($artikel->deskripsi_singkat)
<div class="text-xs text-gray-400 mt-1">{{ Str::limit($artikel->deskripsi_singkat, 60) }}</div>
@endif
</td>
<td class="px-6 py-4">
@if($artikel->jenis === 'Hama')
<span class="px-3 py-1 text-xs font-bold rounded-full bg-orange-100 text-orange-800">Hama</span>
@else
<span class="px-3 py-1 text-xs font-bold rounded-full bg-red-100 text-red-800">Penyakit</span>
@endif
</td>
<td class="px-6 py-4">
@if($artikel->is_published)
<span class="px-3 py-1 text-xs font-bold rounded-full bg-green-100 text-green-800">Published</span>
@else
<span class="px-3 py-1 text-xs font-bold rounded-full bg-gray-100 text-gray-600">Draft</span>
@endif
</td>
<td class="px-6 py-4 text-sm text-gray-600">{{ $artikel->created_at->format('d M Y') }}</td>
<td class="px-6 py-4 text-center">
<div class="flex justify-center space-x-2">
<a href="{{ route('admin.artikel-hama-penyakit.edit', $artikel) }}" class="inline-flex items-center px-3 py-2 bg-blue-500 text-white text-xs font-semibold rounded-lg hover:bg-blue-600 transition">
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path>
</svg>
Edit
</a>
<form action="{{ route('admin.artikel-hama-penyakit.destroy', $artikel) }}" method="POST" onsubmit="return confirm('Yakin ingin menghapus artikel ini?')">
@csrf
@method('DELETE')
<button type="submit" class="inline-flex items-center px-3 py-2 bg-red-500 text-white text-xs font-semibold rounded-lg hover:bg-red-600 transition">
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
</svg>
Hapus
</button>
</form>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="6" class="px-6 py-12 text-center text-gray-400">
<svg class="w-16 h-16 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 006.586 13H4"></path>
</svg>
<p class="text-xl font-semibold mb-2">Belum ada artikel hama & penyakit</p>
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="mt-6">{{ $artikels->links() }}</div>
</div>
</div> </div>
@endif
<div style="background:white; border-radius:1.25rem; box-shadow:0 1px 4px rgba(0,0,0,0.07); border:1px solid #f0fdf4; overflow:hidden;">
{{-- Header --}}
<div style="padding:1.25rem 1.5rem; border-bottom:1px solid #f3f4f6; display:flex; align-items:center; justify-content:space-between; gap:1rem; flex-wrap:wrap;">
<div style="display:flex; align-items:center; gap:0.75rem;">
<div style="width:2.5rem; height:2.5rem; background:#dcfce7; border-radius:0.75rem; display:flex; align-items:center; justify-content:center; flex-shrink:0;">
<svg style="width:1.25rem; height:1.25rem; color:#16a34a;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2m-4-3H9M7 16h6M7 8h6v4H7V8z"/>
</svg>
</div>
<div>
<div style="font-size:0.9rem; font-weight:700; color:#111827;">Daftar Artikel Hama & Penyakit</div>
<div style="font-size:0.75rem; color:#9ca3af;">Kelola artikel informasi hama dan penyakit tanaman kopi</div>
</div>
</div>
<a href="{{ route('admin.artikel-hama-penyakit.create') }}"
style="display:inline-flex; align-items:center; gap:0.5rem; padding:0.625rem 1.25rem; background:#16a34a; color:white; font-weight:700; font-size:0.875rem; border-radius:0.75rem; text-decoration:none; transition:background 0.15s; white-space:nowrap;">
<svg style="width:1rem; height:1rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"/>
</svg>
Tambah Artikel
</a>
</div>
{{-- Table --}}
<div style="overflow-x:auto;">
<table style="width:100%; border-collapse:collapse; font-size:0.875rem;">
<thead>
<tr style="background:#f9fafb;">
<th style="padding:0.875rem 1.25rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6;">No</th>
<th style="padding:0.875rem 1.25rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6;">Judul</th>
<th style="padding:0.875rem 1.25rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6;">Jenis</th>
<th style="padding:0.875rem 1.25rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6;">Status</th>
<th style="padding:0.875rem 1.25rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6;">Tanggal</th>
<th style="padding:0.875rem 1.25rem; text-align:center; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6;">Aksi</th>
</tr>
</thead>
<tbody>
@forelse($artikels as $index => $artikel)
<tr style="border-bottom:1px solid #f9fafb; transition:background 0.1s;" onmouseover="this.style.background='#f9fafb'" onmouseout="this.style.background=''">
<td style="padding:1rem 1.25rem; color:#6b7280;">{{ $artikels->firstItem() + $index }}</td>
<td style="padding:1rem 1.25rem;">
<div style="font-weight:600; color:#111827;">{{ $artikel->judul }}</div>
@if($artikel->deskripsi_singkat)
<div style="font-size:0.75rem; color:#9ca3af; margin-top:0.2rem;">{{ Str::limit($artikel->deskripsi_singkat, 60) }}</div>
@endif
</td>
<td style="padding:1rem 1.25rem;">
@if($artikel->jenis === 'Hama')
<span style="padding:0.25rem 0.75rem; font-size:0.7rem; font-weight:700; border-radius:9999px; background:#dcfce7; color:#14532d; border:1px solid #bbf7d0;">Hama</span>
@else
<span style="padding:0.25rem 0.75rem; font-size:0.7rem; font-weight:700; border-radius:9999px; background:#f0fdf4; color:#166534; border:1px solid #bbf7d0;">Penyakit</span>
@endif
</td>
<td style="padding:1rem 1.25rem;">
@if($artikel->is_published)
<span style="padding:0.25rem 0.75rem; font-size:0.7rem; font-weight:700; border-radius:9999px; background:#16a34a; color:white;">Published</span>
@else
<span style="padding:0.25rem 0.75rem; font-size:0.7rem; font-weight:700; border-radius:9999px; background:#f3f4f6; color:#6b7280;">Draft</span>
@endif
</td>
<td style="padding:1rem 1.25rem; color:#6b7280;">{{ $artikel->created_at->format('d M Y') }}</td>
<td style="padding:1rem 1.25rem; text-align:center;">
<div style="display:inline-flex; align-items:center; gap:0.5rem;">
<a href="{{ route('admin.artikel-hama-penyakit.edit', $artikel) }}"
style="display:inline-flex; align-items:center; gap:0.375rem; padding:0.4rem 0.875rem; background:#f0fdf4; color:#16a34a; font-size:0.75rem; font-weight:600; border-radius:0.5rem; border:1px solid #bbf7d0; text-decoration:none; transition:background 0.15s;">
<svg style="width:0.875rem; height:0.875rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
</svg>
Edit
</a>
<form action="{{ route('admin.artikel-hama-penyakit.destroy', $artikel) }}" method="POST" onsubmit="return confirm('Yakin ingin menghapus artikel ini?')" style="display:inline;">
@csrf
@method('DELETE')
<button type="submit"
style="display:inline-flex; align-items:center; gap:0.375rem; padding:0.4rem 0.875rem; background:#fef2f2; color:#dc2626; font-size:0.75rem; font-weight:600; border-radius:0.5rem; border:1px solid #fecaca; cursor:pointer; transition:background 0.15s;">
<svg style="width:0.875rem; height:0.875rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
</svg>
Hapus
</button>
</form>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="6" style="padding:3rem; text-align:center; color:#9ca3af;">
<svg style="width:3rem; height:3rem; margin:0 auto 1rem; color:#d1fae5;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 006.586 13H4"/>
</svg>
<p style="font-size:1rem; font-weight:600; color:#374151; margin-bottom:0.25rem;">Belum ada artikel hama & penyakit</p>
<p style="font-size:0.8rem;">Mulai tambahkan artikel baru</p>
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div style="padding:1rem 1.5rem; border-top:1px solid #f3f4f6;">
{{ $artikels->links() }}
</div>
</div>
@endsection @endsection

View File

@ -4,97 +4,102 @@
@section('page-subtitle', 'Overview statistik sistem pakar') @section('page-subtitle', 'Overview statistik sistem pakar')
@section('content') @section('content')
<!-- Welcome Banner --> <!-- Welcome Banner -->
<div class="bg-gradient-to-r from-green-600 via-green-700 to-green-800 rounded-2xl p-8 mb-6 text-white relative overflow-hidden shadow-xl"> <div style="background: linear-gradient(135deg, #14532d 0%, #166534 50%, #15803d 100%); border-radius: 1.25rem; padding: 2rem; margin-bottom: 1.5rem; color: white; position: relative; overflow: hidden; box-shadow: 0 10px 25px rgba(21,128,61,0.3);">
<div class="absolute right-0 top-0 w-64 h-64 bg-white opacity-5 rounded-full -mr-32 -mt-32"></div> <div style="position:absolute; right:-4rem; top:-4rem; width:12rem; height:12rem; background:rgba(255,255,255,0.05); border-radius:50%;"></div>
<div class="absolute right-10 bottom-0 w-48 h-48 bg-white opacity-5 rounded-full -mb-24"></div> <div style="position:absolute; right:3rem; bottom:-3rem; width:8rem; height:8rem; background:rgba(255,255,255,0.05); border-radius:50%;"></div>
<div class="relative z-10"> <div style="position:relative; z-index:1;">
<h1 class="text-3xl font-bold mb-2">Selamat Datang Kembali!</h1> <p style="font-size:0.8rem; font-weight:600; letter-spacing:0.1em; color:rgba(187,247,208,0.8); text-transform:uppercase; margin-bottom:0.5rem;">
<p class="text-green-100 text-lg">{{ Auth::user()->nama }}</p> {{ now()->translatedFormat('l, d F Y') }}
<p class="text-green-50 mt-4">{{ now()->translatedFormat('l, d F Y') }}</p> </p>
<h1 style="font-size:1.75rem; font-weight:800; margin-bottom:0.25rem;">Selamat Datang Kembali</h1>
<p style="font-size:1.1rem; color:#bbf7d0; font-weight:500;">{{ Auth::user()->nama }}</p>
</div> </div>
</div> </div>
<!-- Statistics Cards --> <!-- Statistics Cards -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-6"> <div style="display:grid; grid-template-columns:repeat(auto-fit, minmax(200px, 1fr)); gap:1rem; margin-bottom:1.5rem;">
<!-- Total Gejala --> <!-- Total Gejala -->
<div class="bg-white rounded-2xl p-6 shadow-lg hover:shadow-xl transition-shadow"> <div style="background:white; border-radius:1.25rem; padding:1.5rem; box-shadow:0 1px 4px rgba(0,0,0,0.07); border:1px solid #f0fdf4; display:flex; align-items:center; justify-content:space-between; gap:1rem;">
<div class="flex items-center justify-between"> <div>
<div class="flex-1"> <p style="font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Total Gejala</p>
<p class="text-sm font-semibold text-gray-500 uppercase">Total Gejala</p> <h3 style="font-size:2.25rem; font-weight:800; color:#14532d; line-height:1;">{{ $totalGejala }}</h3>
<h3 class="text-4xl font-bold text-gray-800 mt-2">{{ $totalGejala }}</h3> </div>
</div> <div style="width:3.25rem; height:3.25rem; background:#dcfce7; border-radius:1rem; display:flex; align-items:center; justify-content:center; flex-shrink:0;">
<div class="w-14 h-14 bg-gradient-to-br from-green-400 to-green-600 rounded-2xl flex items-center justify-center shadow-lg"> <svg style="width:1.5rem; height:1.5rem; color:#16a34a;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"/>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path> </svg>
</svg>
</div>
</div> </div>
</div> </div>
<!-- Total Penyakit --> <!-- Total Penyakit -->
<div class="bg-white rounded-2xl p-6 shadow-lg hover:shadow-xl transition-shadow"> <div style="background:white; border-radius:1.25rem; padding:1.5rem; box-shadow:0 1px 4px rgba(0,0,0,0.07); border:1px solid #f0fdf4; display:flex; align-items:center; justify-content:space-between; gap:1rem;">
<div class="flex items-center justify-between"> <div>
<div class="flex-1"> <p style="font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Total Penyakit</p>
<p class="text-sm font-semibold text-gray-500 uppercase">Total Penyakit</p> <h3 style="font-size:2.25rem; font-weight:800; color:#14532d; line-height:1;">{{ $totalPenyakit }}</h3>
<h3 class="text-4xl font-bold text-gray-800 mt-2">{{ $totalPenyakit }}</h3> </div>
</div> <div style="width:3.25rem; height:3.25rem; background:#dcfce7; border-radius:1rem; display:flex; align-items:center; justify-content:center; flex-shrink:0;">
<div class="w-14 h-14 bg-gradient-to-br from-red-400 to-red-600 rounded-2xl flex items-center justify-center shadow-lg"> <svg style="width:1.5rem; height:1.5rem; color:#16a34a;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path> </svg>
</svg>
</div>
</div> </div>
</div> </div>
<!-- Total Diagnosa --> <!-- Total Diagnosa -->
<div class="bg-white rounded-2xl p-6 shadow-lg hover:shadow-xl transition-shadow"> <div style="background:white; border-radius:1.25rem; padding:1.5rem; box-shadow:0 1px 4px rgba(0,0,0,0.07); border:1px solid #f0fdf4; display:flex; align-items:center; justify-content:space-between; gap:1rem;">
<div class="flex items-center justify-between"> <div>
<div class="flex-1"> <p style="font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Total Diagnosa</p>
<p class="text-sm font-semibold text-gray-500 uppercase">Total Diagnosa</p> <h3 style="font-size:2.25rem; font-weight:800; color:#14532d; line-height:1;">{{ $totalDiagnosa }}</h3>
<h3 class="text-4xl font-bold text-gray-800 mt-2">{{ $totalDiagnosa }}</h3> </div>
</div> <div style="width:3.25rem; height:3.25rem; background:#dcfce7; border-radius:1rem; display:flex; align-items:center; justify-content:center; flex-shrink:0;">
<div class="w-14 h-14 bg-gradient-to-br from-purple-400 to-purple-600 rounded-2xl flex items-center justify-center shadow-lg"> <svg style="width:1.5rem; height:1.5rem; color:#16a34a;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path> </svg>
</svg>
</div>
</div> </div>
</div> </div>
<!-- Total Artikel --> <!-- Total Artikel -->
<div class="bg-white rounded-2xl p-6 shadow-lg hover:shadow-xl transition-shadow"> <div style="background:white; border-radius:1.25rem; padding:1.5rem; box-shadow:0 1px 4px rgba(0,0,0,0.07); border:1px solid #f0fdf4; display:flex; align-items:center; justify-content:space-between; gap:1rem;">
<div class="flex items-center justify-between"> <div>
<div class="flex-1"> <p style="font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Total Artikel</p>
<p class="text-sm font-semibold text-gray-500 uppercase">Total Artikel</p> <h3 style="font-size:2.25rem; font-weight:800; color:#14532d; line-height:1;">{{ $totalArtikel }}</h3>
<h3 class="text-4xl font-bold text-gray-800 mt-2">{{ $totalArtikel }}</h3> </div>
</div> <div style="width:3.25rem; height:3.25rem; background:#dcfce7; border-radius:1rem; display:flex; align-items:center; justify-content:center; flex-shrink:0;">
<div class="w-14 h-14 bg-gradient-to-br from-yellow-400 to-yellow-600 rounded-2xl flex items-center justify-center shadow-lg"> <svg style="width:1.5rem; height:1.5rem; color:#16a34a;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2m-4-3H9M7 16h6M7 8h6v4H7V8z"/>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2m-4-3H9M7 16h6M7 8h6v4H7V8z"></path> </svg>
</svg>
</div>
</div> </div>
</div> </div>
</div> </div>
<!-- Charts Section --> <!-- Charts Section -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6"> <div style="display:grid; grid-template-columns:repeat(auto-fit, minmax(320px, 1fr)); gap:1.5rem;">
<!-- Penyakit Chart --> <!-- Penyakit Chart -->
<div class="bg-white rounded-2xl p-6 shadow-lg"> <div style="background:white; border-radius:1.25rem; padding:1.5rem; box-shadow:0 1px 4px rgba(0,0,0,0.07); border:1px solid #f0fdf4;">
<h3 class="text-xl font-bold text-gray-800 mb-4">Penyakit Paling Sering Didiagnosa</h3> <div style="margin-bottom:1.25rem;">
<div style="height: 300px;"> <h3 style="font-size:1rem; font-weight:700; color:#111827; margin-bottom:0.25rem;">Penyakit Paling Sering Didiagnosa</h3>
<p style="font-size:0.75rem; color:#9ca3af;">Berdasarkan total riwayat diagnosa</p>
</div>
<div style="height:280px;">
<canvas id="penyakitChart"></canvas> <canvas id="penyakitChart"></canvas>
</div> </div>
</div> </div>
<!-- Diagnosa Trend Chart --> <!-- Diagnosa Trend Chart -->
<div class="bg-white rounded-2xl p-6 shadow-lg"> <div style="background:white; border-radius:1.25rem; padding:1.5rem; box-shadow:0 1px 4px rgba(0,0,0,0.07); border:1px solid #f0fdf4;">
<h3 class="text-xl font-bold text-gray-800 mb-4">Trend Diagnosa (6 Bulan Terakhir)</h3> <div style="margin-bottom:1.25rem;">
<div style="height: 300px;"> <h3 style="font-size:1rem; font-weight:700; color:#111827; margin-bottom:0.25rem;">Trend Diagnosa</h3>
<p style="font-size:0.75rem; color:#9ca3af;">6 bulan terakhir</p>
</div>
<div style="height:280px;">
<canvas id="diagnosaChart"></canvas> <canvas id="diagnosaChart"></canvas>
</div> </div>
</div> </div>
</div> </div>
<!-- Chart.js Script --> <!-- Chart.js Script -->
@ -110,14 +115,33 @@
datasets: [{ datasets: [{
label: 'Jumlah Diagnosa', label: 'Jumlah Diagnosa',
data: penyakitData.data, data: penyakitData.data,
backgroundColor: ['rgba(239, 68, 68, 0.8)', 'rgba(249, 115, 22, 0.8)', 'rgba(234, 179, 8, 0.8)', 'rgba(34, 197, 94, 0.8)', 'rgba(59, 130, 246, 0.8)'], backgroundColor: [
borderRadius: 8, 'rgba(20, 83, 45, 0.85)',
'rgba(22, 101, 52, 0.85)',
'rgba(21, 128, 61, 0.85)',
'rgba(22, 163, 74, 0.85)',
'rgba(34, 197, 94, 0.85)',
],
borderRadius: 6,
borderSkipped: false,
}] }]
}, },
options: { options: {
responsive: true, responsive: true,
maintainAspectRatio: false, maintainAspectRatio: false,
plugins: { legend: { display: false } } plugins: {
legend: { display: false },
tooltip: {
backgroundColor: '#14532d',
titleFont: { weight: '600' },
padding: 10,
cornerRadius: 8,
}
},
scales: {
x: { grid: { display: false }, ticks: { font: { size: 11 }, color: '#6b7280' } },
y: { grid: { color: '#f3f4f6' }, ticks: { font: { size: 11 }, color: '#6b7280' }, beginAtZero: true }
}
} }
}); });
@ -131,18 +155,36 @@
datasets: [{ datasets: [{
label: 'Jumlah Diagnosa', label: 'Jumlah Diagnosa',
data: diagnosaData.data, data: diagnosaData.data,
borderColor: 'rgb(95, 163, 87)', borderColor: '#16a34a',
backgroundColor: 'rgba(95, 163, 87, 0.1)', backgroundColor: 'rgba(22, 163, 74, 0.08)',
borderWidth: 3, borderWidth: 2.5,
fill: true, fill: true,
tension: 0.4, tension: 0.4,
pointBackgroundColor: '#16a34a',
pointBorderColor: 'white',
pointBorderWidth: 2,
pointRadius: 5,
pointHoverRadius: 7,
}] }]
}, },
options: { options: {
responsive: true, responsive: true,
maintainAspectRatio: false, maintainAspectRatio: false,
plugins: { legend: { display: false } } plugins: {
legend: { display: false },
tooltip: {
backgroundColor: '#14532d',
titleFont: { weight: '600' },
padding: 10,
cornerRadius: 8,
}
},
scales: {
x: { grid: { display: false }, ticks: { font: { size: 11 }, color: '#6b7280' } },
y: { grid: { color: '#f3f4f6' }, ticks: { font: { size: 11 }, color: '#6b7280' }, beginAtZero: true }
}
} }
}); });
</script> </script>
@endsection @endsection

View File

@ -4,94 +4,89 @@
@section('page-subtitle', 'Edit data gejala penyakit') @section('page-subtitle', 'Edit data gejala penyakit')
@section('content') @section('content')
@if ($errors->any())
<div class="mb-6 bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded-lg"> @if($errors->any())
<div class="flex items-start"> <div style="margin-bottom:1.5rem; background:#fef2f2; border:1px solid #fecaca; color:#dc2626; padding:1rem 1.25rem; border-radius:0.75rem; display:flex; align-items:flex-start; gap:0.75rem;">
<svg class="w-6 h-6 mr-3 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20"> <svg style="width:1.25rem; height:1.25rem; flex-shrink:0; margin-top:0.1rem;" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/> <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/>
</svg>
<div>
<p style="font-weight:600; font-size:0.875rem; margin-bottom:0.375rem;">Terdapat kesalahan:</p>
<ul style="font-size:0.8rem; padding-left:1rem; display:flex; flex-direction:column; gap:0.2rem;">
@foreach($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
</div>
@endif
<form action="{{ route('admin.gejala.update', $gejala) }}" method="POST">
@csrf
@method('PUT')
<div style="background:white; border-radius:1.25rem; box-shadow:0 1px 4px rgba(0,0,0,0.07); border:1px solid #f0fdf4; overflow:hidden;">
{{-- Header --}}
<div style="padding:1.25rem 1.5rem; border-bottom:1px solid #f3f4f6; display:flex; align-items:center; gap:0.75rem;">
<div style="width:2.5rem; height:2.5rem; background:#dcfce7; border-radius:0.75rem; display:flex; align-items:center; justify-content:center; flex-shrink:0;">
<svg style="width:1.25rem; height:1.25rem; color:#16a34a;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
</svg> </svg>
<div> </div>
<p class="font-semibold mb-2">Terdapat kesalahan:</p> <div>
<ul class="list-disc list-inside space-y-1"> <div style="font-size:0.9rem; font-weight:700; color:#111827;">Form Edit Gejala</div>
@foreach ($errors->all() as $error) <div style="font-size:0.75rem; color:#9ca3af;">Perbarui data gejala penyakit tanaman kopi</div>
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
</div> </div>
</div> </div>
@endif
<form action="{{ route('admin.gejala.update', $gejala) }}" method="POST"> {{-- Form Body --}}
@csrf <div style="padding:2rem; display:flex; flex-direction:column; gap:1.5rem;">
@method('PUT')
<div class="bg-white rounded-2xl shadow-lg"> {{-- Kode Gejala (readonly) --}}
<!-- Header --> <div>
<div class="p-6 border-b border-gray-200"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Kode Gejala</label>
<div class="flex items-center"> <input type="text" name="id_gejala" id="id_gejala" value="{{ $gejala->id_gejala }}"
<div class="bg-gradient-to-r from-blue-500 to-blue-600 rounded-xl p-3 mr-4"> style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#6b7280; background:#f9fafb; font-family:monospace; box-sizing:border-box; cursor:not-allowed;"
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> readonly disabled>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path> <p style="font-size:0.75rem; color:#9ca3af; margin-top:0.375rem;">Kode gejala tidak dapat diubah setelah dibuat.</p>
</svg>
</div>
<h3 class="text-xl font-bold text-gray-800">Form Edit Gejala</h3>
</div>
</div> </div>
<!-- Form Body --> {{-- Nama Gejala --}}
<div class="p-8 space-y-6"> <div>
<label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">
<!-- Kode Gejala (Read-only) --> Nama Gejala <span style="color:#dc2626;">*</span>
<div> </label>
<label for="id_gejala" class="block text-sm font-semibold text-gray-700 mb-2"> <input type="text" name="nama_gejala" id="nama_gejala"
Kode Gejala value="{{ old('nama_gejala', $gejala->nama_gejala) }}"
</label> style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; box-sizing:border-box;"
<input placeholder="Contoh: Daun menguning" required>
type="text" @error('nama_gejala')
name="id_gejala" <p style="color:#dc2626; font-size:0.75rem; margin-top:0.375rem;">{{ $message }}</p>
id="id_gejala" @enderror
value="{{ $gejala->id_gejala }}"
class="w-full px-4 py-3 border border-gray-300 rounded-xl bg-gray-100 cursor-not-allowed"
readonly
disabled
>
<p class="mt-1 text-sm text-gray-500">Kode gejala tidak dapat diubah setelah dibuat.</p>
</div>
<!-- Nama Gejala -->
<div>
<label for="nama_gejala" class="block text-sm font-semibold text-gray-700 mb-2">
Nama Gejala <span class="text-red-500">*</span>
</label>
<input
type="text"
name="nama_gejala"
id="nama_gejala"
value="{{ old('nama_gejala', $gejala->nama_gejala) }}"
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition @error('nama_gejala') border-red-500 @enderror"
placeholder="Contoh: Daun menguning"
required
>
@error('nama_gejala')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
</div> </div>
<!-- Footer Buttons -->
<div class="px-8 py-6 bg-gray-50 border-t border-gray-200 flex justify-between items-center rounded-b-2xl">
<a href="{{ route('admin.gejala.index') }}" class="px-6 py-3 bg-gray-300 text-gray-700 font-semibold rounded-xl hover:bg-gray-400 transition">
Batal
</a>
<button type="submit" class="px-6 py-3 bg-gradient-to-r from-blue-500 to-blue-600 text-white font-bold rounded-xl hover:from-blue-600 hover:to-blue-700 transition-all shadow-lg hover:shadow-xl transform hover:scale-105 flex items-center">
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4"></path>
</svg>
Update Data
</button>
</div>
</div> </div>
</form>
{{-- Footer --}}
<div style="padding:1rem 1.5rem; background:#f9fafb; border-top:1px solid #f3f4f6; display:flex; align-items:center; justify-content:space-between;">
<a href="{{ route('admin.gejala.index') }}"
style="display:inline-flex; align-items:center; gap:0.5rem; padding:0.625rem 1.25rem; border:1px solid #e5e7eb; color:#6b7280; font-size:0.875rem; font-weight:600; border-radius:0.75rem; text-decoration:none; background:white;">
<svg style="width:1rem; height:1rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
</svg>
Batal
</a>
<button type="submit"
style="display:inline-flex; align-items:center; gap:0.5rem; padding:0.625rem 1.5rem; background:#16a34a; color:white; font-size:0.875rem; font-weight:700; border-radius:0.75rem; border:none; cursor:pointer;">
<svg style="width:1rem; height:1rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
</svg>
Update Data
</button>
</div>
</div>
</form>
@endsection @endsection

View File

@ -4,94 +4,106 @@
@section('page-subtitle', 'Kelola data gejala penyakit') @section('page-subtitle', 'Kelola data gejala penyakit')
@section('content') @section('content')
@if (session('success'))
<div class="mb-6 bg-green-100 border-l-4 border-green-500 text-green-700 p-4 rounded-lg flex items-center">
<svg class="w-6 h-6 mr-3" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
</svg>
<span class="font-semibold">{{ session('success') }}</span>
</div>
@endif
<div class="bg-white rounded-2xl shadow-lg"> @if(session('success'))
<div class="p-8"> <div style="margin-bottom:1.5rem; background:#f0fdf4; border:1px solid #bbf7d0; color:#15803d; padding:1rem 1.25rem; border-radius:0.75rem; display:flex; align-items:center; gap:0.75rem;">
<div class="flex justify-between items-center mb-6"> <svg style="width:1.25rem; height:1.25rem; flex-shrink:0;" fill="currentColor" viewBox="0 0 20 20">
<div class="flex items-center"> <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
<div class="bg-gradient-to-r from-green-500 to-green-600 rounded-xl p-3 mr-4"> </svg>
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <span style="font-weight:600; font-size:0.875rem;">{{ session('success') }}</span>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path>
</svg>
</div>
<h3 class="text-xl font-bold text-gray-800">Daftar Gejala Penyakit</h3>
</div>
<a href="{{ route('admin.gejala.create') }}" class="flex items-center px-5 py-3 bg-gradient-to-r from-green-500 to-green-600 text-white font-bold rounded-xl hover:from-green-600 hover:to-green-700 transition-all shadow-lg hover:shadow-xl transform hover:scale-105">
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
</svg>
Tambah Gejala
</a>
</div>
<div class="overflow-x-auto rounded-xl border border-gray-200">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th class="px-6 py-4 text-left text-xs font-bold text-gray-600 uppercase">No</th>
<th class="px-6 py-4 text-left text-xs font-bold text-gray-600 uppercase">Kode</th>
<th class="px-6 py-4 text-left text-xs font-bold text-gray-600 uppercase">Nama Gejala</th>
<th class="px-6 py-4 text-center text-xs font-bold text-gray-600 uppercase">Aksi</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
@forelse ($gejalas as $index => $gejala)
<tr class="hover:bg-gray-50 transition-colors">
<td class="px-6 py-4 text-sm text-gray-900">{{ $gejalas->firstItem() + $index }}</td>
<td class="px-6 py-4">
<span class="px-3 py-1 text-xs font-bold rounded-full bg-green-100 text-green-800">
{{ $gejala->id_gejala }}
</span>
</td>
<td class="px-6 py-4">
<div class="text-sm font-semibold text-gray-900">{{ $gejala->nama_gejala }}</div>
</td>
<td class="px-6 py-4 text-center">
<div class="flex justify-center space-x-2">
<a href="{{ route('admin.gejala.edit', $gejala) }}" class="inline-flex items-center px-3 py-2 bg-blue-500 text-white text-xs font-semibold rounded-lg hover:bg-blue-600 transition">
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path>
</svg>
Edit
</a>
<form action="{{ route('admin.gejala.destroy', $gejala) }}" method="POST" onsubmit="return confirm('Yakin ingin menghapus gejala ini?')">
@csrf
@method('DELETE')
<button type="submit" class="inline-flex items-center px-3 py-2 bg-red-500 text-white text-xs font-semibold rounded-lg hover:bg-red-600 transition">
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
</svg>
Hapus
</button>
</form>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="4" class="px-6 py-12 text-center">
<div class="text-gray-400">
<svg class="w-16 h-16 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4"></path>
</svg>
<p class="text-xl font-semibold mb-2">Belum ada data gejala</p>
</div>
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="mt-6">{{ $gejalas->links() }}</div>
</div>
</div> </div>
@endif
<div style="background:white; border-radius:1.25rem; box-shadow:0 1px 4px rgba(0,0,0,0.07); border:1px solid #f0fdf4; overflow:hidden;">
{{-- Header --}}
<div style="padding:1.25rem 1.5rem; border-bottom:1px solid #f3f4f6; display:flex; align-items:center; justify-content:space-between; gap:1rem; flex-wrap:wrap;">
<div style="display:flex; align-items:center; gap:0.75rem;">
<div style="width:2.5rem; height:2.5rem; background:#dcfce7; border-radius:0.75rem; display:flex; align-items:center; justify-content:center; flex-shrink:0;">
<svg style="width:1.25rem; height:1.25rem; color:#16a34a;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"/>
</svg>
</div>
<div>
<div style="font-size:0.9rem; font-weight:700; color:#111827;">Daftar Gejala Penyakit</div>
<div style="font-size:0.75rem; color:#9ca3af;">Kelola data gejala penyakit tanaman kopi</div>
</div>
</div>
<a href="{{ route('admin.gejala.create') }}"
style="display:inline-flex; align-items:center; gap:0.5rem; padding:0.625rem 1.25rem; background:#16a34a; color:white; font-weight:700; font-size:0.875rem; border-radius:0.75rem; text-decoration:none; white-space:nowrap;">
<svg style="width:1rem; height:1rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"/>
</svg>
Tambah Gejala
</a>
</div>
{{-- Table --}}
<div style="overflow-x:auto;">
<table style="width:100%; border-collapse:collapse; font-size:0.875rem;">
<thead>
<tr style="background:#f9fafb;">
<th style="padding:0.875rem 1.25rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6;">No</th>
<th style="padding:0.875rem 1.25rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6;">Kode</th>
<th style="padding:0.875rem 1.25rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6;">Nama Gejala</th>
<th style="padding:0.875rem 1.25rem; text-align:center; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6;">Aksi</th>
</tr>
</thead>
<tbody>
@forelse($gejalas as $index => $gejala)
<tr style="border-bottom:1px solid #f9fafb;" onmouseover="this.style.background='#f9fafb'" onmouseout="this.style.background=''">
<td style="padding:1rem 1.25rem; color:#6b7280;">{{ $gejalas->firstItem() + $index }}</td>
<td style="padding:1rem 1.25rem;">
<span style="padding:0.2rem 0.6rem; font-size:0.7rem; font-weight:700; border-radius:0.375rem; background:#111827; color:white; font-family:monospace;">
{{ $gejala->id_gejala }}
</span>
</td>
<td style="padding:1rem 1.25rem; font-weight:600; color:#111827;">
{{ $gejala->nama_gejala }}
</td>
<td style="padding:1rem 1.25rem; text-align:center;">
<div style="display:inline-flex; align-items:center; gap:0.5rem;">
<a href="{{ route('admin.gejala.edit', $gejala) }}"
style="display:inline-flex; align-items:center; gap:0.375rem; padding:0.4rem 0.875rem; background:#f0fdf4; color:#16a34a; font-size:0.75rem; font-weight:600; border-radius:0.5rem; border:1px solid #bbf7d0; text-decoration:none;">
<svg style="width:0.875rem; height:0.875rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
</svg>
Edit
</a>
<form action="{{ route('admin.gejala.destroy', $gejala) }}" method="POST"
onsubmit="return confirm('Yakin ingin menghapus gejala ini?')" style="display:inline;">
@csrf
@method('DELETE')
<button type="submit"
style="display:inline-flex; align-items:center; gap:0.375rem; padding:0.4rem 0.875rem; background:#fef2f2; color:#dc2626; font-size:0.75rem; font-weight:600; border-radius:0.5rem; border:1px solid #fecaca; cursor:pointer;">
<svg style="width:0.875rem; height:0.875rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
</svg>
Hapus
</button>
</form>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="4" style="padding:3rem; text-align:center; color:#9ca3af;">
<svg style="width:3rem; height:3rem; margin:0 auto 1rem; color:#d1fae5;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 006.586 13H4"/>
</svg>
<p style="font-size:1rem; font-weight:600; color:#374151; margin-bottom:0.25rem;">Belum ada data gejala</p>
<p style="font-size:0.8rem;">Klik tombol "Tambah Gejala" untuk menambahkan data</p>
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div style="padding:1rem 1.5rem; border-top:1px solid #f3f4f6;">
{{ $gejalas->links() }}
</div>
</div>
@endsection @endsection

View File

@ -4,277 +4,231 @@
@section('page-subtitle', 'Edit data penyakit tanaman kopi') @section('page-subtitle', 'Edit data penyakit tanaman kopi')
@section('content') @section('content')
@if ($errors->any())
<div class="mb-6 bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded-lg"> @if($errors->any())
<div class="flex items-start"> <div style="margin-bottom:1.5rem; background:#fef2f2; border:1px solid #fecaca; color:#dc2626; padding:1rem 1.25rem; border-radius:0.75rem; display:flex; align-items:flex-start; gap:0.75rem;">
<svg class="w-6 h-6 mr-3 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20"> <svg style="width:1.25rem; height:1.25rem; flex-shrink:0; margin-top:0.1rem;" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/> <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/>
</svg>
<div>
<p style="font-weight:600; font-size:0.875rem; margin-bottom:0.375rem;">Terdapat kesalahan:</p>
<ul style="font-size:0.8rem; padding-left:1rem; display:flex; flex-direction:column; gap:0.2rem;">
@foreach($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
</div>
@endif
<form action="{{ route('admin.penyakit.update', $penyakit) }}" method="POST" enctype="multipart/form-data">
@csrf
@method('PUT')
<div style="background:white; border-radius:1.25rem; box-shadow:0 1px 4px rgba(0,0,0,0.07); border:1px solid #f0fdf4; overflow:hidden;">
{{-- Header --}}
<div style="padding:1.25rem 1.5rem; border-bottom:1px solid #f3f4f6; display:flex; align-items:center; gap:0.75rem;">
<div style="width:2.5rem; height:2.5rem; background:#dcfce7; border-radius:0.75rem; display:flex; align-items:center; justify-content:center; flex-shrink:0;">
<svg style="width:1.25rem; height:1.25rem; color:#16a34a;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
</svg> </svg>
<div> </div>
<p class="font-semibold mb-2">Terdapat kesalahan:</p> <div>
<ul class="list-disc list-inside space-y-1"> <div style="font-size:0.9rem; font-weight:700; color:#111827;">Form Edit Penyakit</div>
@foreach ($errors->all() as $error) <div style="font-size:0.75rem; color:#9ca3af;">Perbarui data penyakit atau hama tanaman kopi</div>
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
</div> </div>
</div> </div>
@endif
<form action="{{ route('admin.penyakit.update', $penyakit) }}" method="POST" enctype="multipart/form-data"> {{-- Form Body --}}
@csrf <div style="padding:2rem; display:flex; flex-direction:column; gap:1.5rem;">
@method('PUT')
<div class="bg-white rounded-2xl shadow-lg"> {{-- Kode Penyakit (readonly) --}}
<!-- Header --> <div>
<div class="p-6 border-b border-gray-200"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Kode Penyakit</label>
<div class="flex items-center"> <input type="text" name="id_penyakit" id="id_penyakit" value="{{ $penyakit->id_penyakit }}"
<div class="bg-gradient-to-r from-blue-500 to-blue-600 rounded-xl p-3 mr-4"> style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#6b7280; background:#f9fafb; font-family:monospace; box-sizing:border-box; cursor:not-allowed;"
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> readonly disabled>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path> <p style="font-size:0.75rem; color:#9ca3af; margin-top:0.375rem;">Kode penyakit tidak dapat diubah setelah dibuat.</p>
</div>
{{-- Nama Penyakit --}}
<div>
<label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">
Nama Penyakit <span style="color:#dc2626;">*</span>
</label>
<input type="text" name="nama_penyakit" id="nama_penyakit"
value="{{ old('nama_penyakit', $penyakit->nama_penyakit) }}"
style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; box-sizing:border-box;"
placeholder="Contoh: Penggerek Buah Kopi" required>
@error('nama_penyakit')
<p style="color:#dc2626; font-size:0.75rem; margin-top:0.375rem;">{{ $message }}</p>
@enderror
</div>
{{-- Nama Latin --}}
<div>
<label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Nama Latin</label>
<input type="text" name="nama_latin" id="nama_latin"
value="{{ old('nama_latin', $penyakit->nama_latin) }}"
style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; box-sizing:border-box; font-style:italic;"
placeholder="Contoh: Hypothenemus hampei">
</div>
{{-- Kategori & Tingkat Bahaya (2 kolom) --}}
<div style="display:grid; grid-template-columns:1fr 1fr; gap:1.25rem;">
<div>
<label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">
Kategori <span style="color:#dc2626;">*</span>
</label>
<div style="position:relative;">
<select name="kategori" id="kategori" required
style="width:100%; padding:0.75rem 2.5rem 0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; background:white; appearance:none; outline:none; box-sizing:border-box;">
<option value="">-- Pilih Kategori --</option>
<option value="Hama" {{ old('kategori', $penyakit->kategori) == 'Hama' ? 'selected' : '' }}>Hama</option>
<option value="Penyakit" {{ old('kategori', $penyakit->kategori) == 'Penyakit' ? 'selected' : '' }}>Penyakit</option>
</select>
<svg style="position:absolute; right:0.875rem; top:50%; transform:translateY(-50%); width:1rem; height:1rem; color:#9ca3af; pointer-events:none;" 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> </svg>
</div> </div>
<h3 class="text-xl font-bold text-gray-800">Form Edit Penyakit</h3>
</div>
</div>
<!-- Form Body -->
<div class="p-8 space-y-6">
<!-- ID Penyakit (Read-only) -->
<div>
<label for="id_penyakit" class="block text-sm font-semibold text-gray-700 mb-2">
Kode Penyakit
</label>
<input
type="text"
name="id_penyakit"
id="id_penyakit"
value="{{ $penyakit->id_penyakit }}"
class="w-full px-4 py-3 border border-gray-300 rounded-xl bg-gray-100 cursor-not-allowed"
readonly
disabled
>
<p class="mt-1 text-sm text-gray-500">Kode penyakit tidak dapat diubah setelah dibuat.</p>
</div>
<!-- Nama Penyakit -->
<div>
<label for="nama_penyakit" class="block text-sm font-semibold text-gray-700 mb-2">
Nama Penyakit <span class="text-red-500">*</span>
</label>
<input
type="text"
name="nama_penyakit"
id="nama_penyakit"
value="{{ old('nama_penyakit', $penyakit->nama_penyakit) }}"
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition @error('nama_penyakit') border-red-500 @enderror"
placeholder="Contoh: Penggerek Buah Kopi"
required
>
@error('nama_penyakit')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
<!-- Nama Latin -->
<div>
<label for="nama_latin" class="block text-sm font-semibold text-gray-700 mb-2">
Nama Latin
</label>
<input
type="text"
name="nama_latin"
id="nama_latin"
value="{{ old('nama_latin', $penyakit->nama_latin) }}"
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
placeholder="Contoh: Hypothenemus hampei"
>
</div>
<!-- Kategori -->
<div>
<label for="kategori" class="block text-sm font-semibold text-gray-700 mb-2">
Kategori <span class="text-red-500">*</span>
</label>
<select
name="kategori"
id="kategori"
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
required
>
<option value="">-- Pilih Kategori --</option>
<option value="Hama" {{ old('kategori', $penyakit->kategori) == 'Hama' ? 'selected' : '' }}>Hama</option>
<option value="Penyakit" {{ old('kategori', $penyakit->kategori) == 'Penyakit' ? 'selected' : '' }}>Penyakit</option>
</select>
@error('kategori') @error('kategori')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p> <p style="color:#dc2626; font-size:0.75rem; margin-top:0.375rem;">{{ $message }}</p>
@enderror @enderror
</div> </div>
<!-- Deskripsi Singkat -->
<div> <div>
<label for="deskripsi_singkat" class="block text-sm font-semibold text-gray-700 mb-2"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Tingkat Bahaya</label>
Deskripsi Singkat <div style="position:relative;">
</label> <select name="tingkat_bahaya" id="tingkat_bahaya"
<textarea style="width:100%; padding:0.75rem 2.5rem 0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; background:white; appearance:none; outline:none; box-sizing:border-box;">
name="deskripsi_singkat" <option value="">-- Pilih Tingkat Bahaya --</option>
id="deskripsi_singkat" <option value="Rendah" {{ old('tingkat_bahaya', $penyakit->tingkat_bahaya) == 'Rendah' ? 'selected' : '' }}>Rendah</option>
rows="3" <option value="Sedang" {{ old('tingkat_bahaya', $penyakit->tingkat_bahaya) == 'Sedang' ? 'selected' : '' }}>Sedang</option>
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition" <option value="Tinggi" {{ old('tingkat_bahaya', $penyakit->tingkat_bahaya) == 'Tinggi' ? 'selected' : '' }}>Tinggi</option>
placeholder="Ringkasan singkat tentang penyakit/hama ini..." <option value="Sangat Tinggi" {{ old('tingkat_bahaya', $penyakit->tingkat_bahaya) == 'Sangat Tinggi' ? 'selected' : '' }}>Sangat Tinggi</option>
>{{ old('deskripsi_singkat', $penyakit->deskripsi_singkat) }}</textarea> </select>
</div> <svg style="position:absolute; right:0.875rem; top:50%; transform:translateY(-50%); width:1rem; height:1rem; color:#9ca3af; pointer-events:none;" 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"/>
<!-- Deskripsi Lengkap --> </svg>
<div>
<label for="deskripsi_lengkap" class="block text-sm font-semibold text-gray-700 mb-2">
Deskripsi Lengkap
</label>
<textarea
name="deskripsi_lengkap"
id="deskripsi_lengkap"
rows="5"
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
placeholder="Penjelasan detail tentang penyakit/hama, gejala, dampak, dll..."
>{{ old('deskripsi_lengkap', $penyakit->deskripsi_lengkap) }}</textarea>
</div>
<!-- Pengendalian Pencegahan -->
<div>
<label for="pengendalian_pencegahan" class="block text-sm font-semibold text-gray-700 mb-2">
Pengendalian Pencegahan
</label>
<textarea
name="pengendalian_pencegahan"
id="pengendalian_pencegahan"
rows="4"
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
placeholder="Cara pencegahan sebelum terjadi serangan..."
>{{ old('pengendalian_pencegahan', $penyakit->pengendalian_pencegahan) }}</textarea>
</div>
<!-- Pengendalian Kimia -->
<div>
<label for="pengendalian_kimia" class="block text-sm font-semibold text-gray-700 mb-2">
Pengendalian Kimia
</label>
<textarea
name="pengendalian_kimia"
id="pengendalian_kimia"
rows="4"
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
placeholder="Pestisida atau bahan kimia yang dapat digunakan..."
>{{ old('pengendalian_kimia', $penyakit->pengendalian_kimia) }}</textarea>
</div>
<!-- Pengendalian Organik -->
<div>
<label for="pengendalian_organik" class="block text-sm font-semibold text-gray-700 mb-2">
Pengendalian Organik
</label>
<textarea
name="pengendalian_organik"
id="pengendalian_organik"
rows="4"
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
placeholder="Cara pengendalian dengan bahan organik/alami..."
>{{ old('pengendalian_organik', $penyakit->pengendalian_organik) }}</textarea>
</div>
<!-- Pengendalian Budidaya -->
<div>
<label for="pengendalian_budidaya" class="block text-sm font-semibold text-gray-700 mb-2">
Pengendalian Budidaya
</label>
<textarea
name="pengendalian_budidaya"
id="pengendalian_budidaya"
rows="4"
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
placeholder="Teknik budidaya untuk mengendalikan hama/penyakit..."
>{{ old('pengendalian_budidaya', $penyakit->pengendalian_budidaya) }}</textarea>
</div>
<!-- Tingkat Bahaya -->
<div>
<label for="tingkat_bahaya" class="block text-sm font-semibold text-gray-700 mb-2">
Tingkat Bahaya
</label>
<select
name="tingkat_bahaya"
id="tingkat_bahaya"
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
>
<option value="">-- Pilih Tingkat Bahaya --</option>
<option value="Rendah" {{ old('tingkat_bahaya', $penyakit->tingkat_bahaya) == 'Rendah' ? 'selected' : '' }}>Rendah</option>
<option value="Sedang" {{ old('tingkat_bahaya', $penyakit->tingkat_bahaya) == 'Sedang' ? 'selected' : '' }}>Sedang</option>
<option value="Tinggi" {{ old('tingkat_bahaya', $penyakit->tingkat_bahaya) == 'Tinggi' ? 'selected' : '' }}>Tinggi</option>
<option value="Sangat Tinggi" {{ old('tingkat_bahaya', $penyakit->tingkat_bahaya) == 'Sangat Tinggi' ? 'selected' : '' }}>Sangat Tinggi</option>
</select>
</div>
<!-- Upload Gambar -->
<div>
<label for="gambar" class="block text-sm font-semibold text-gray-700 mb-2">
Upload Gambar
</label>
<input
type="file"
name="gambar"
id="gambar"
accept="image/*"
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition file:mr-4 file:py-2 file:px-4 file:rounded-lg file:border-0 file:text-sm file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100"
onchange="previewImage(event)"
>
<p class="mt-2 text-sm text-gray-500">Format: JPG, PNG, WebP. Maksimal 2MB</p>
<!-- Preview Gambar Baru -->
<div id="imagePreview" class="mt-3 hidden">
<p class="text-sm text-gray-600 mb-2">Preview gambar baru:</p>
<img id="preview" src="" alt="Preview" class="w-32 h-32 object-cover rounded-lg shadow-sm">
</div> </div>
</div>
<!-- Preview Gambar Lama --> </div>
@if($penyakit->gambar_url)
<div class="mt-3"> {{-- Deskripsi Singkat --}}
<p class="text-sm text-gray-600 mb-2">Gambar saat ini:</p> <div>
<img src="{{ $penyakit->gambar_url }}" alt="Current" class="w-32 h-32 object-cover rounded-lg shadow-sm"> <label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Deskripsi Singkat</label>
<p class="text-xs text-gray-500 mt-2">Upload gambar baru untuk mengganti</p> <textarea name="deskripsi_singkat" id="deskripsi_singkat" rows="3"
style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; resize:none; box-sizing:border-box;"
placeholder="Ringkasan singkat tentang penyakit/hama ini...">{{ old('deskripsi_singkat', $penyakit->deskripsi_singkat) }}</textarea>
</div>
{{-- Deskripsi Lengkap --}}
<div>
<label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Deskripsi Lengkap</label>
<textarea name="deskripsi_lengkap" id="deskripsi_lengkap" rows="5"
style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; resize:vertical; box-sizing:border-box;"
placeholder="Penjelasan detail tentang penyakit/hama, gejala, dampak, dll...">{{ old('deskripsi_lengkap', $penyakit->deskripsi_lengkap) }}</textarea>
</div>
{{-- Pengendalian (group dalam card) --}}
<div style="border:1px solid #e5e7eb; border-radius:1rem; overflow:hidden;">
<div style="padding:0.875rem 1.25rem; background:#f9fafb; border-bottom:1px solid #f3f4f6; display:flex; align-items:center; gap:0.5rem;">
<svg style="width:1rem; height:1rem; color:#6b7280;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
</svg>
<span style="font-size:0.875rem; font-weight:600; color:#374151;">Metode Pengendalian</span>
</div>
<div style="padding:1.25rem; display:flex; flex-direction:column; gap:1.25rem;">
<div style="display:grid; grid-template-columns:1fr 1fr; gap:1.25rem;">
<div>
<label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Pencegahan</label>
<textarea name="pengendalian_pencegahan" rows="4"
style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; resize:none; box-sizing:border-box;"
placeholder="Cara pencegahan sebelum terjadi serangan...">{{ old('pengendalian_pencegahan', $penyakit->pengendalian_pencegahan) }}</textarea>
</div> </div>
@endif <div>
<label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Kimia</label>
<textarea name="pengendalian_kimia" rows="4"
style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; resize:none; box-sizing:border-box;"
placeholder="Pestisida atau bahan kimia yang dapat digunakan...">{{ old('pengendalian_kimia', $penyakit->pengendalian_kimia) }}</textarea>
</div>
<div>
<label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Organik</label>
<textarea name="pengendalian_organik" rows="4"
style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; resize:none; box-sizing:border-box;"
placeholder="Cara pengendalian dengan bahan organik/alami...">{{ old('pengendalian_organik', $penyakit->pengendalian_organik) }}</textarea>
</div>
<div>
<label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Budidaya</label>
<textarea name="pengendalian_budidaya" rows="4"
style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#111827; outline:none; resize:none; box-sizing:border-box;"
placeholder="Teknik budidaya untuk mengendalikan hama/penyakit...">{{ old('pengendalian_budidaya', $penyakit->pengendalian_budidaya) }}</textarea>
</div>
</div>
</div>
</div>
{{-- Upload Gambar --}}
<div>
<label style="display:block; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">Upload Gambar</label>
<input type="file" name="gambar" id="gambar" accept="image/*"
style="width:100%; padding:0.75rem 1rem; border:1px solid #e5e7eb; border-radius:0.75rem; font-size:0.875rem; color:#6b7280; box-sizing:border-box;"
onchange="previewImage(event)">
<p style="font-size:0.7rem; color:#9ca3af; margin-top:0.375rem;">Format: JPG, PNG, WebP. Maksimal 2MB</p>
{{-- Preview gambar baru --}}
<div id="imagePreview" style="display:none; margin-top:0.75rem;">
<p style="font-size:0.75rem; color:#6b7280; margin-bottom:0.375rem;">Preview gambar baru:</p>
<img id="preview" src="" alt="Preview"
style="width:6rem; height:6rem; object-fit:cover; border-radius:0.75rem; border:1px solid #e5e7eb;">
</div> </div>
{{-- Gambar lama --}}
@if($penyakit->gambar_url)
<div style="margin-top:0.75rem;">
<p style="font-size:0.75rem; color:#6b7280; margin-bottom:0.375rem;">Gambar saat ini:</p>
<img src="{{ $penyakit->gambar_url }}" alt="Current"
style="width:6rem; height:6rem; object-fit:cover; border-radius:0.75rem; border:1px solid #e5e7eb;">
<p style="font-size:0.7rem; color:#9ca3af; margin-top:0.375rem;">Upload gambar baru untuk mengganti</p>
</div>
@endif
</div> </div>
<!-- Footer Buttons -->
<div class="px-8 py-6 bg-gray-50 border-t border-gray-200 flex justify-between items-center rounded-b-2xl">
<a href="{{ route('admin.penyakit.index') }}" class="px-6 py-3 bg-gray-300 text-gray-700 font-semibold rounded-xl hover:bg-gray-400 transition">
Batal
</a>
<button type="submit" class="px-6 py-3 bg-gradient-to-r from-blue-500 to-blue-600 text-white font-bold rounded-xl hover:from-blue-600 hover:to-blue-700 transition-all shadow-lg hover:shadow-xl transform hover:scale-105 flex items-center">
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4"></path>
</svg>
Update Data
</button>
</div>
</div> </div>
</form>
<!-- JavaScript for Image Preview --> {{-- Footer --}}
<script> <div style="padding:1rem 1.5rem; background:#f9fafb; border-top:1px solid #f3f4f6; display:flex; align-items:center; justify-content:space-between;">
function previewImage(event) { <a href="{{ route('admin.penyakit.index') }}"
const file = event.target.files[0]; style="display:inline-flex; align-items:center; gap:0.5rem; padding:0.625rem 1.25rem; border:1px solid #e5e7eb; color:#6b7280; font-size:0.875rem; font-weight:600; border-radius:0.75rem; text-decoration:none; background:white;">
if (file) { <svg style="width:1rem; height:1rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
const reader = new FileReader(); <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
reader.onload = function(e) { </svg>
document.getElementById('preview').src = e.target.result; Batal
document.getElementById('imagePreview').classList.remove('hidden'); </a>
} <button type="submit"
reader.readAsDataURL(file); style="display:inline-flex; align-items:center; gap:0.5rem; padding:0.625rem 1.5rem; background:#16a34a; color:white; font-size:0.875rem; font-weight:700; border-radius:0.75rem; border:none; cursor:pointer;">
<svg style="width:1rem; height:1rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
</svg>
Update Data
</button>
</div>
</div>
</form>
<script>
function previewImage(event) {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(e) {
document.getElementById('preview').src = e.target.result;
document.getElementById('imagePreview').style.display = 'block';
} }
reader.readAsDataURL(file);
} }
</script> }
</script>
@endsection @endsection

View File

@ -4,263 +4,250 @@
@section('page-subtitle', 'Kelola data penyakit tanaman kopi') @section('page-subtitle', 'Kelola data penyakit tanaman kopi')
@section('content') @section('content')
@if (session('success'))
<div class="mb-6 bg-green-100 border-l-4 border-green-500 text-green-700 p-4 rounded-lg flex items-center" role="alert">
<svg class="w-6 h-6 mr-3" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
</svg>
<span class="font-semibold">{{ session('success') }}</span>
</div>
@endif
@if (session('error')) @if(session('success'))
<div class="mb-6 bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded-lg flex items-center" role="alert"> <div style="margin-bottom:1.5rem; background:#f0fdf4; border:1px solid #bbf7d0; color:#15803d; padding:1rem 1.25rem; border-radius:0.75rem; display:flex; align-items:center; gap:0.75rem;">
<svg class="w-6 h-6 mr-3" fill="currentColor" viewBox="0 0 20 20"> <svg style="width:1.25rem; height:1.25rem; flex-shrink:0;" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/> <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
</svg> </svg>
<span class="font-semibold">{{ session('error') }}</span> <span style="font-weight:600; font-size:0.875rem;">{{ session('success') }}</span>
</div>
@endif
<div class="bg-white rounded-2xl shadow-lg">
<!-- Header Section - Normal (No Sticky) -->
<div class="p-6 border-b border-gray-200">
<div class="flex justify-between items-center">
<div class="flex items-center">
<div class="bg-gradient-to-r from-green-500 to-green-600 rounded-xl p-3 mr-4">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
</svg>
</div>
<h3 class="text-xl font-bold text-gray-800">Daftar Penyakit & Hama Tanaman Kopi</h3>
</div>
<a href="{{ route('admin.penyakit.create') }}" class="flex items-center px-5 py-3 bg-gradient-to-r from-green-500 to-green-600 text-white font-bold rounded-xl hover:from-red-600 hover:to-red-700 transition-all shadow-lg hover:shadow-xl transform hover:scale-105">
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
</svg>
Tambah Data
</a>
</div>
</div>
<!-- Table Section with Horizontal Scroll Only -->
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th class="px-4 py-3 text-left text-xs font-bold text-gray-600 uppercase">No</th>
<th class="px-4 py-3 text-left text-xs font-bold text-gray-600 uppercase">Kode</th>
<th class="px-4 py-3 text-left text-xs font-bold text-gray-600 uppercase">Gambar</th>
<th class="px-4 py-3 text-left text-xs font-bold text-gray-600 uppercase">Nama Penyakit</th>
<th class="px-4 py-3 text-left text-xs font-bold text-gray-600 uppercase">Nama Latin</th>
<th class="px-4 py-3 text-left text-xs font-bold text-gray-600 uppercase">Kategori</th>
<th class="px-4 py-3 text-left text-xs font-bold text-gray-600 uppercase">Deskripsi Singkat</th>
<th class="px-4 py-3 text-left text-xs font-bold text-gray-600 uppercase">Deskripsi Lengkap</th>
<th class="px-4 py-3 text-left text-xs font-bold text-gray-600 uppercase">Pengendalian Pencegahan</th>
<th class="px-4 py-3 text-left text-xs font-bold text-gray-600 uppercase">Pengendalian Kimia</th>
<th class="px-4 py-3 text-left text-xs font-bold text-gray-600 uppercase">Pengendalian Organik</th>
<th class="px-4 py-3 text-left text-xs font-bold text-gray-600 uppercase">Pengendalian Budidaya</th>
<th class="px-4 py-3 text-left text-xs font-bold text-gray-600 uppercase">Tingkat Bahaya</th>
<th class="px-4 py-3 text-center text-xs font-bold text-gray-600 uppercase">Aksi</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
@forelse ($penyakits as $index => $penyakit)
<tr class="hover:bg-gray-50 transition-colors">
<!-- No -->
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-900 font-semibold">
{{ $penyakits->firstItem() + $index }}
</td>
<!-- Kode Penyakit -->
<td class="px-4 py-4 whitespace-nowrap">
<span class="px-3 py-1 text-xs font-bold rounded-full bg-gray-800 text-white">
{{ $penyakit->id_penyakit }}
</span>
</td>
<!-- Gambar Preview -->
<td class="px-4 py-4">
@if($penyakit->gambar_url)
<img
src="{{ $penyakit->gambar_url }}"
alt="{{ $penyakit->nama_penyakit }}"
class="w-16 h-16 object-cover rounded-lg shadow-sm cursor-pointer hover:scale-110 transition-transform"
onclick="openModal('{{ $penyakit->gambar_url }}', '{{ $penyakit->nama_penyakit }}')"
>
@else
<div class="w-16 h-16 bg-gray-200 rounded-lg flex items-center justify-center">
<svg class="w-8 h-8 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
</svg>
</div>
@endif
</td>
<!-- Nama Penyakit -->
<td class="px-4 py-4">
<div class="text-sm font-bold text-gray-900 min-w-[150px]">{{ $penyakit->nama_penyakit }}</div>
</td>
<!-- Nama Latin -->
<td class="px-4 py-4">
<div class="text-sm text-gray-600 italic min-w-[120px]">{{ $penyakit->nama_latin ?? '-' }}</div>
</td>
<!-- Kategori -->
<td class="px-4 py-4 whitespace-nowrap">
@if($penyakit->kategori === 'Penyakit')
<span class="px-3 py-1 text-xs font-bold rounded-full bg-red-100 text-red-800">
Penyakit
</span>
@elseif($penyakit->kategori === 'Hama')
<span class="px-3 py-1 text-xs font-bold rounded-full bg-orange-100 text-orange-800">
Hama
</span>
@else
<span class="px-3 py-1 text-xs font-bold rounded-full bg-gray-100 text-gray-800">
{{ $penyakit->kategori ?? '-' }}
</span>
@endif
</td>
<!-- Deskripsi Singkat -->
<td class="px-4 py-4">
<div class="text-sm text-gray-600 max-w-xs">{{ Str::limit($penyakit->deskripsi_singkat ?? '-', 80) }}</div>
</td>
<!-- Deskripsi Lengkap -->
<td class="px-4 py-4">
<div class="text-sm text-gray-600 max-w-xs">{{ Str::limit($penyakit->deskripsi_lengkap ?? '-', 80) }}</div>
</td>
<!-- Pengendalian Pencegahan -->
<td class="px-4 py-4">
<div class="text-sm text-gray-600 max-w-xs">{{ Str::limit($penyakit->pengendalian_pencegahan ?? '-', 60) }}</div>
</td>
<!-- Pengendalian Kimia -->
<td class="px-4 py-4">
<div class="text-sm text-gray-600 max-w-xs">{{ Str::limit($penyakit->pengendalian_kimia ?? '-', 60) }}</div>
</td>
<!-- Pengendalian Organik -->
<td class="px-4 py-4">
<div class="text-sm text-gray-600 max-w-xs">{{ Str::limit($penyakit->pengendalian_organik ?? '-', 60) }}</div>
</td>
<!-- Pengendalian Budidaya -->
<td class="px-4 py-4">
<div class="text-sm text-gray-600 max-w-xs">{{ Str::limit($penyakit->pengendalian_budidaya ?? '-', 60) }}</div>
</td>
<!-- Tingkat Bahaya -->
<td class="px-4 py-4 whitespace-nowrap">
@if($penyakit->tingkat_bahaya === 'Sangat Tinggi')
<span class="px-2 py-1 text-xs font-bold rounded-full bg-red-600 text-white">{{ $penyakit->tingkat_bahaya }}</span>
@elseif($penyakit->tingkat_bahaya === 'Tinggi')
<span class="px-2 py-1 text-xs font-bold rounded-full bg-orange-500 text-white">{{ $penyakit->tingkat_bahaya }}</span>
@elseif($penyakit->tingkat_bahaya === 'Sedang')
<span class="px-2 py-1 text-xs font-bold rounded-full bg-yellow-500 text-white">{{ $penyakit->tingkat_bahaya }}</span>
@elseif($penyakit->tingkat_bahaya === 'Rendah')
<span class="px-2 py-1 text-xs font-bold rounded-full bg-green-500 text-white">{{ $penyakit->tingkat_bahaya }}</span>
@else
<span class="text-sm text-gray-500">{{ $penyakit->tingkat_bahaya ?? '-' }}</span>
@endif
</td>
<!-- Aksi -->
<td class="px-4 py-4 whitespace-nowrap text-center">
<div class="flex justify-center space-x-2">
<a href="{{ route('admin.penyakit.edit', $penyakit) }}" class="inline-flex items-center px-3 py-2 bg-blue-500 text-white text-xs font-semibold rounded-lg hover:bg-blue-600 transition">
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path>
</svg>
Edit
</a>
<form action="{{ route('admin.penyakit.destroy', $penyakit) }}" method="POST" class="inline" onsubmit="return confirm('Yakin ingin menghapus data ini?')">
@csrf
@method('DELETE')
<button type="submit" class="inline-flex items-center px-3 py-2 bg-red-500 text-white text-xs font-semibold rounded-lg hover:bg-red-600 transition">
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
</svg>
Hapus
</button>
</form>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="13" class="px-6 py-12 text-center">
<div class="text-gray-400">
<svg class="w-16 h-16 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4"></path>
</svg>
<p class="text-xl font-semibold mb-2">Belum ada data</p>
<p class="text-sm">Klik tombol "Tambah Data" untuk menambahkan penyakit atau hama</p>
</div>
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<!-- Pagination -->
<div class="px-6 py-4 border-t border-gray-200">
{{ $penyakits->links() }}
</div>
</div> </div>
@endif
<!-- Image Modal Lightbox --> @if(session('error'))
<div id="imageModal" class="fixed inset-0 z-50 hidden bg-black bg-opacity-75 flex items-center justify-center p-4" onclick="closeModal()"> <div style="margin-bottom:1.5rem; background:#fef2f2; border:1px solid #fecaca; color:#dc2626; padding:1rem 1.25rem; border-radius:0.75rem; display:flex; align-items:center; gap:0.75rem;">
<div class="relative max-w-5xl max-h-full" onclick="event.stopPropagation()"> <svg style="width:1.25rem; height:1.25rem; flex-shrink:0;" fill="currentColor" viewBox="0 0 20 20">
<!-- Close Button --> <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/>
<button </svg>
onclick="closeModal()" <span style="font-weight:600; font-size:0.875rem;">{{ session('error') }}</span>
class="absolute -top-12 right-0 text-white hover:text-gray-300 transition" </div>
> @endif
<svg class="w-10 h-10" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path> <div style="background:white; border-radius:1.25rem; box-shadow:0 1px 4px rgba(0,0,0,0.07); border:1px solid #f0fdf4; overflow:hidden;">
{{-- Header --}}
<div style="padding:1.25rem 1.5rem; border-bottom:1px solid #f3f4f6; display:flex; align-items:center; justify-content:space-between; gap:1rem; flex-wrap:wrap;">
<div style="display:flex; align-items:center; gap:0.75rem;">
<div style="width:2.5rem; height:2.5rem; background:#dcfce7; border-radius:0.75rem; display:flex; align-items:center; justify-content:center; flex-shrink:0;">
<svg style="width:1.25rem; height:1.25rem; color:#16a34a;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
</svg> </svg>
</button> </div>
<div>
<!-- Image --> <div style="font-size:0.9rem; font-weight:700; color:#111827;">Daftar Penyakit & Hama Tanaman Kopi</div>
<img <div style="font-size:0.75rem; color:#9ca3af;">Kelola data penyakit dan hama tanaman kopi</div>
id="modalImage"
src=""
alt=""
class="max-w-full max-h-[80vh] object-contain rounded-lg shadow-2xl"
>
<!-- Image Title -->
<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black to-transparent p-4 rounded-b-lg">
<p id="modalTitle" class="text-white text-lg font-semibold"></p>
</div> </div>
</div> </div>
<a href="{{ route('admin.penyakit.create') }}"
style="display:inline-flex; align-items:center; gap:0.5rem; padding:0.625rem 1.25rem; background:#16a34a; color:white; font-weight:700; font-size:0.875rem; border-radius:0.75rem; text-decoration:none; white-space:nowrap;">
<svg style="width:1rem; height:1rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"/>
</svg>
Tambah Data
</a>
</div> </div>
<!-- JavaScript for Modal --> {{-- Table --}}
<script> <div style="overflow-x:auto;">
function openModal(imageUrl, title) { <table style="width:100%; border-collapse:collapse; font-size:0.875rem;">
document.getElementById('modalImage').src = imageUrl; <thead>
document.getElementById('modalTitle').textContent = title; <tr style="background:#f9fafb;">
document.getElementById('imageModal').classList.remove('hidden'); <th style="padding:0.75rem 1rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6; white-space:nowrap;">No</th>
document.body.style.overflow = 'hidden'; // Prevent background scroll <th style="padding:0.75rem 1rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6; white-space:nowrap;">Kode</th>
} <th style="padding:0.75rem 1rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6; white-space:nowrap;">Gambar</th>
<th style="padding:0.75rem 1rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6; white-space:nowrap;">Nama Penyakit</th>
<th style="padding:0.75rem 1rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6; white-space:nowrap;">Nama Latin</th>
<th style="padding:0.75rem 1rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6; white-space:nowrap;">Kategori</th>
<th style="padding:0.75rem 1rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6; white-space:nowrap;">Deskripsi Singkat</th>
<th style="padding:0.75rem 1rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6; white-space:nowrap;">Deskripsi Lengkap</th>
<th style="padding:0.75rem 1rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6; white-space:nowrap;">Pencegahan</th>
<th style="padding:0.75rem 1rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6; white-space:nowrap;">Kimia</th>
<th style="padding:0.75rem 1rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6; white-space:nowrap;">Organik</th>
<th style="padding:0.75rem 1rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6; white-space:nowrap;">Budidaya</th>
<th style="padding:0.75rem 1rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6; white-space:nowrap;">Bahaya</th>
<th style="padding:0.75rem 1rem; text-align:center; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6; white-space:nowrap;">Aksi</th>
</tr>
</thead>
<tbody>
@forelse($penyakits as $index => $penyakit)
<tr style="border-bottom:1px solid #f9fafb;" onmouseover="this.style.background='#f9fafb'" onmouseout="this.style.background=''">
function closeModal() { {{-- No --}}
document.getElementById('imageModal').classList.add('hidden'); <td style="padding:0.875rem 1rem; color:#6b7280; white-space:nowrap;">{{ $penyakits->firstItem() + $index }}</td>
document.body.style.overflow = 'auto'; // Restore scroll
} {{-- Kode --}}
<td style="padding:0.875rem 1rem; white-space:nowrap;">
<span style="padding:0.2rem 0.6rem; font-size:0.7rem; font-weight:700; border-radius:0.375rem; background:#111827; color:white; font-family:monospace;">
{{ $penyakit->id_penyakit }}
</span>
</td>
{{-- Gambar --}}
<td style="padding:0.875rem 1rem;">
@if($penyakit->gambar_url)
<img src="{{ $penyakit->gambar_url }}"
alt="{{ $penyakit->nama_penyakit }}"
style="width:3.5rem; height:3.5rem; object-fit:cover; border-radius:0.5rem; border:1px solid #e5e7eb; cursor:pointer; transition:transform 0.15s;"
onclick="openModal('{{ $penyakit->gambar_url }}', '{{ $penyakit->nama_penyakit }}')"
onmouseover="this.style.transform='scale(1.08)'" onmouseout="this.style.transform='scale(1)'">
@else
<div style="width:3.5rem; height:3.5rem; background:#f3f4f6; border-radius:0.5rem; display:flex; align-items:center; justify-content:center; border:1px solid #e5e7eb;">
<svg style="width:1.5rem; height:1.5rem; color:#d1d5db;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/>
</svg>
</div>
@endif
</td>
{{-- Nama Penyakit --}}
<td style="padding:0.875rem 1rem; min-width:10rem;">
<div style="font-weight:700; color:#111827; font-size:0.875rem;">{{ $penyakit->nama_penyakit }}</div>
</td>
{{-- Nama Latin --}}
<td style="padding:0.875rem 1rem; min-width:8rem;">
<div style="font-size:0.8rem; color:#6b7280; font-style:italic;">{{ $penyakit->nama_latin ?? '-' }}</div>
</td>
{{-- Kategori --}}
<td style="padding:0.875rem 1rem; white-space:nowrap;">
@if($penyakit->kategori === 'Penyakit')
<span style="padding:0.2rem 0.65rem; font-size:0.7rem; font-weight:700; border-radius:9999px; background:#14532d; color:white;">Penyakit</span>
@elseif($penyakit->kategori === 'Hama')
<span style="padding:0.2rem 0.65rem; font-size:0.7rem; font-weight:700; border-radius:9999px; background:#dcfce7; color:#14532d; border:1px solid #bbf7d0;">Hama</span>
@else
<span style="padding:0.2rem 0.65rem; font-size:0.7rem; font-weight:700; border-radius:9999px; background:#f3f4f6; color:#6b7280;">{{ $penyakit->kategori ?? '-' }}</span>
@endif
</td>
{{-- Deskripsi Singkat --}}
<td style="padding:0.875rem 1rem; max-width:10rem;">
<div style="font-size:0.8rem; color:#6b7280; overflow:hidden; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;">{{ $penyakit->deskripsi_singkat ?? '-' }}</div>
</td>
{{-- Deskripsi Lengkap --}}
<td style="padding:0.875rem 1rem; max-width:10rem;">
<div style="font-size:0.8rem; color:#6b7280; overflow:hidden; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;">{{ Str::limit($penyakit->deskripsi_lengkap ?? '-', 60) }}</div>
</td>
{{-- Pencegahan --}}
<td style="padding:0.875rem 1rem; max-width:9rem;">
<div style="font-size:0.8rem; color:#6b7280; overflow:hidden; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;">{{ Str::limit($penyakit->pengendalian_pencegahan ?? '-', 60) }}</div>
</td>
{{-- Kimia --}}
<td style="padding:0.875rem 1rem; max-width:9rem;">
<div style="font-size:0.8rem; color:#6b7280; overflow:hidden; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;">{{ Str::limit($penyakit->pengendalian_kimia ?? '-', 60) }}</div>
</td>
{{-- Organik --}}
<td style="padding:0.875rem 1rem; max-width:9rem;">
<div style="font-size:0.8rem; color:#6b7280; overflow:hidden; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;">{{ Str::limit($penyakit->pengendalian_organik ?? '-', 60) }}</div>
</td>
{{-- Budidaya --}}
<td style="padding:0.875rem 1rem; max-width:9rem;">
<div style="font-size:0.8rem; color:#6b7280; overflow:hidden; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;">{{ Str::limit($penyakit->pengendalian_budidaya ?? '-', 60) }}</div>
</td>
{{-- Tingkat Bahaya --}}
<td style="padding:0.875rem 1rem; white-space:nowrap;">
@if($penyakit->tingkat_bahaya === 'Sangat Tinggi')
<span style="padding:0.2rem 0.65rem; font-size:0.7rem; font-weight:700; border-radius:9999px; background:#14532d; color:white;">Sangat Tinggi</span>
@elseif($penyakit->tingkat_bahaya === 'Tinggi')
<span style="padding:0.2rem 0.65rem; font-size:0.7rem; font-weight:700; border-radius:9999px; background:#166534; color:white;">Tinggi</span>
@elseif($penyakit->tingkat_bahaya === 'Sedang')
<span style="padding:0.2rem 0.65rem; font-size:0.7rem; font-weight:700; border-radius:9999px; background:#dcfce7; color:#15803d; border:1px solid #bbf7d0;">Sedang</span>
@elseif($penyakit->tingkat_bahaya === 'Rendah')
<span style="padding:0.2rem 0.65rem; font-size:0.7rem; font-weight:700; border-radius:9999px; background:#f0fdf4; color:#166534; border:1px solid #bbf7d0;">Rendah</span>
@else
<span style="font-size:0.8rem; color:#9ca3af;">{{ $penyakit->tingkat_bahaya ?? '-' }}</span>
@endif
</td>
{{-- Aksi --}}
<td style="padding:0.875rem 1rem; text-align:center; white-space:nowrap;">
<div style="display:inline-flex; align-items:center; gap:0.5rem;">
<a href="{{ route('admin.penyakit.edit', $penyakit) }}"
style="display:inline-flex; align-items:center; gap:0.375rem; padding:0.4rem 0.875rem; background:#f0fdf4; color:#16a34a; font-size:0.75rem; font-weight:600; border-radius:0.5rem; border:1px solid #bbf7d0; text-decoration:none;">
<svg style="width:0.875rem; height:0.875rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
</svg>
Edit
</a>
<form action="{{ route('admin.penyakit.destroy', $penyakit) }}" method="POST"
onsubmit="return confirm('Yakin ingin menghapus data ini?')" style="display:inline;">
@csrf
@method('DELETE')
<button type="submit"
style="display:inline-flex; align-items:center; gap:0.375rem; padding:0.4rem 0.875rem; background:#fef2f2; color:#dc2626; font-size:0.75rem; font-weight:600; border-radius:0.5rem; border:1px solid #fecaca; cursor:pointer;">
<svg style="width:0.875rem; height:0.875rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
</svg>
Hapus
</button>
</form>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="14" style="padding:3rem; text-align:center; color:#9ca3af;">
<svg style="width:3rem; height:3rem; margin:0 auto 1rem; color:#d1fae5;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 006.586 13H4"/>
</svg>
<p style="font-size:1rem; font-weight:600; color:#374151; margin-bottom:0.25rem;">Belum ada data</p>
<p style="font-size:0.8rem;">Klik tombol "Tambah Data" untuk menambahkan penyakit atau hama</p>
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
{{-- Pagination --}}
<div style="padding:1rem 1.5rem; border-top:1px solid #f3f4f6;">
{{ $penyakits->links() }}
</div>
</div>
{{-- Image Modal --}}
<div id="imageModal"
style="display:none; position:fixed; inset:0; z-index:50; background:rgba(0,0,0,0.75); align-items:center; justify-content:center; padding:1rem;"
onclick="closeModal()">
<div style="position:relative; max-width:56rem; max-height:100%;" onclick="event.stopPropagation()">
<button onclick="closeModal()"
style="position:absolute; top:-3rem; right:0; background:none; border:none; color:white; cursor:pointer;">
<svg style="width:2.5rem; height:2.5rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
</svg>
</button>
<img id="modalImage" src="" alt=""
style="max-width:100%; max-height:80vh; object-fit:contain; border-radius:0.75rem; box-shadow:0 25px 50px rgba(0,0,0,0.5);">
<div style="position:absolute; bottom:0; left:0; right:0; background:linear-gradient(to top, rgba(0,0,0,0.7), transparent); padding:1rem; border-radius:0 0 0.75rem 0.75rem;">
<p id="modalTitle" style="color:white; font-size:1rem; font-weight:600;"></p>
</div>
</div>
</div>
<script>
function openModal(imageUrl, title) {
document.getElementById('modalImage').src = imageUrl;
document.getElementById('modalTitle').textContent = title;
const modal = document.getElementById('imageModal');
modal.style.display = 'flex';
document.body.style.overflow = 'hidden';
}
function closeModal() {
document.getElementById('imageModal').style.display = 'none';
document.body.style.overflow = 'auto';
}
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') closeModal();
});
</script>
// Close modal with ESC key
document.addEventListener('keydown', function(event) {
if (event.key === 'Escape') {
closeModal();
}
});
</script>
@endsection @endsection

View File

@ -3,130 +3,248 @@
@section('page-title', 'Manajemen Rule Basis') @section('page-title', 'Manajemen Rule Basis')
@section('page-subtitle', 'Kelola aturan diagnosa sistem pakar') @section('page-subtitle', 'Kelola aturan diagnosa sistem pakar')
@push('styles')
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<style>
:root {
--green-deep: #1a4d2e;
--green-mid: #2d7a4f;
--green-bright:#4ade80;
--bg-base: #f0f5f1;
--bg-card: #ffffff;
--text-primary:#0f1f14;
--text-muted: #6b7f72;
--shadow: 0 4px 24px rgba(29,77,46,.08), 0 1px 4px rgba(29,77,46,.05);
--radius: 20px;
--input-border:#d1d5db;
--input-focus: #2d7a4f;
}
body, .index-root { font-family: 'Plus Jakarta Sans', sans-serif; }
@keyframes fadeUp {
from { opacity:0; transform:translateY(12px); }
to { opacity:1; transform:translateY(0); }
}
.anim { animation: fadeUp .5s cubic-bezier(.22,1,.36,1) both; }
.a1 { animation-delay:.04s; }
.a2 { animation-delay:.12s; }
.a3 { animation-delay:.20s; }
/* ── alert ── */
.alert-success {
display:flex; align-items:center; gap:.75rem;
padding:.9rem 1.2rem; margin-bottom:1.25rem;
background:#f0fdf4; border:1.5px solid #bbf7d0;
border-radius:14px; font-size:.85rem; font-weight:600; color:#166534;
}
/* ── main card ── */
.index-card {
background:var(--bg-card);
border-radius:var(--radius);
border:1.5px solid rgba(29,77,46,.07);
box-shadow:var(--shadow);
overflow:hidden;
}
/* ── toolbar ── */
.toolbar {
display:flex; align-items:center; justify-content:space-between;
padding:1.4rem 1.75rem;
border-bottom:1.5px solid rgba(29,77,46,.07);
flex-wrap:wrap; gap:.75rem;
}
.toolbar-title-bar { display:inline-block; width:3px; height:16px; background:linear-gradient(180deg,var(--green-mid),var(--green-bright)); border-radius:2px; vertical-align:middle; margin-right:.4rem; }
.toolbar-title { font-size:1rem; font-weight:700; color:var(--text-primary); letter-spacing:-.01em; }
.btn-add {
display:inline-flex; align-items:center; gap:.45rem;
padding:.6rem 1.25rem;
background:linear-gradient(135deg,#2d7a4f,#16a34a);
color:#fff; font-size:.82rem; font-weight:700;
border-radius:50px; text-decoration:none;
box-shadow:0 4px 14px rgba(22,163,74,.25); transition:all .2s;
}
.btn-add:hover { transform:translateY(-1px); box-shadow:0 6px 20px rgba(22,163,74,.35); }
/* ── filter bar ── */
.filter-bar {
padding:1.1rem 1.75rem;
background:#fafcfb;
border-bottom:1.5px solid rgba(29,77,46,.07);
display:flex; gap:1rem; flex-wrap:wrap; align-items:flex-end;
}
.filter-group { display:flex; flex-direction:column; gap:.35rem; flex:1; min-width:160px; }
.filter-label { font-size:.72rem; font-weight:700; text-transform:uppercase; letter-spacing:.07em; color:var(--text-muted); }
.filter-select, .filter-input {
padding:.6rem .9rem;
border:1.5px solid var(--input-border); border-radius:10px;
font-size:.82rem; font-family:'Plus Jakarta Sans',sans-serif;
color:var(--text-primary); background:#fff; outline:none;
transition:border-color .15s, box-shadow .15s;
}
.filter-select:focus, .filter-input:focus {
border-color:var(--input-focus);
box-shadow:0 0 0 3px rgba(45,122,79,.1);
}
.filter-actions { display:flex; gap:.5rem; align-items:flex-end; }
.btn-filter {
display:inline-flex; align-items:center; gap:.35rem;
padding:.6rem 1.1rem;
background:#f0fdf4; border:1.5px solid #bbf7d0;
color:var(--green-mid); font-size:.8rem; font-weight:700;
border-radius:10px; cursor:pointer; transition:all .15s;
}
.btn-filter:hover { background:#dcfce7; border-color:var(--green-mid); }
.btn-reset {
display:inline-flex; align-items:center; gap:.35rem;
padding:.6rem 1rem;
background:#f9fafb; border:1.5px solid #e5e7eb;
color:var(--text-muted); font-size:.8rem; font-weight:600;
border-radius:10px; text-decoration:none; transition:all .15s;
}
.btn-reset:hover { background:#f3f4f6; }
/* ── table ── */
.table-wrap { overflow-x:auto; }
table { width:100%; border-collapse:collapse; }
thead tr { border-bottom:1.5px solid rgba(29,77,46,.08); }
thead th {
padding:.75rem 1.1rem;
text-align:left; font-size:.67rem; font-weight:700;
text-transform:uppercase; letter-spacing:.08em;
color:var(--text-muted); background:#fafcfb; white-space:nowrap;
}
thead th.center { text-align:center; }
tbody tr { border-bottom:1px solid rgba(29,77,46,.05); transition:background .15s; }
tbody tr:last-child { border-bottom:none; }
tbody tr:hover { background:#fafcfb; }
td { padding:.85rem 1.1rem; vertical-align:middle; }
.td-no { font-size:.78rem; color:var(--text-muted); font-weight:500; }
/* id badge */
.id-pill {
display:inline-block; padding:.18rem .6rem;
background:#f0fdf4; border:1px solid #bbf7d0;
color:var(--green-mid); font-size:.68rem; font-weight:700;
border-radius:6px; font-family:'DM Mono',monospace; letter-spacing:.02em;
margin-bottom:.3rem;
}
.cell-name { font-size:.82rem; font-weight:600; color:var(--text-primary); }
.cell-sub { font-size:.75rem; color:var(--text-muted); }
/* numeric badge */
.num-badge {
display:inline-block; padding:.25rem .65rem;
background:#f9fafb; border:1.5px solid #e5e7eb;
color:var(--text-primary); font-size:.8rem; font-weight:700;
border-radius:8px; font-family:'DM Mono',monospace;
min-width:52px; text-align:center;
}
/* cf badge color by value */
.cf-high { background:#f0fdf4; border-color:#bbf7d0; color:#166534; }
.cf-mid { background:#fefce8; border-color:#fde68a; color:#a16207; }
.cf-low { background:#f9fafb; border-color:#e5e7eb; color:#6b7280; }
.td-keterangan { font-size:.78rem; color:var(--text-muted); max-width:180px; }
/* action buttons */
.actions { display:flex; align-items:center; justify-content:center; gap:.4rem; }
.btn-edit, .btn-del {
display:inline-flex; align-items:center; gap:.3rem;
padding:.38rem .85rem; border-radius:8px;
font-size:.75rem; font-weight:700;
text-decoration:none; border:1.5px solid transparent;
cursor:pointer; transition:all .15s; white-space:nowrap;
font-family:'Plus Jakarta Sans',sans-serif;
}
.btn-edit { background:#f0fdf4; color:#2d7a4f; border-color:#bbf7d0; }
.btn-edit:hover { background:#dcfce7; border-color:#2d7a4f; }
.btn-del { background:#fff5f5; color:#dc2626; border-color:#fecaca; }
.btn-del:hover { background:#fee2e2; border-color:#dc2626; }
/* empty state */
.empty-state { padding:4rem 2rem; text-align:center; }
.empty-icon { width:48px; height:48px; margin:0 auto 1rem; opacity:.22; }
.empty-state h4 { font-size:.95rem; font-weight:700; color:var(--text-primary); margin-bottom:.35rem; }
.empty-state p { font-size:.82rem; color:var(--text-muted); }
/* pagination */
.pagination-wrap {
padding:1.1rem 1.75rem;
border-top:1.5px solid rgba(29,77,46,.07);
}
</style>
@endpush
@section('content') @section('content')
@if (session('success')) <div class="index-root">
<div class="mb-6 bg-green-100 border-l-4 border-green-500 text-green-700 p-4 rounded-lg flex items-center">
<svg class="w-6 h-6 mr-3" fill="currentColor" viewBox="0 0 20 20"> {{-- Alert --}}
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/> @if(session('success'))
<div class="alert-success anim a1">
<svg width="16" height="16" fill="none" stroke="#16a34a" viewBox="0 0 24 24" stroke-width="2.2">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg> </svg>
<span class="font-semibold">{{ session('success') }}</span> {{ session('success') }}
</div> </div>
@endif @endif
<!-- Statistics Cards --> <div class="index-card anim a2">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-6">
<div class="bg-white rounded-2xl p-6 shadow-lg hover:shadow-xl transition-shadow"> {{-- Toolbar --}}
<div class="flex items-center justify-between"> <div class="toolbar">
<div class="flex-1"> <div class="toolbar-title">
<p class="text-sm font-semibold text-gray-500 uppercase">Total Rule</p> <span class="toolbar-title-bar"></span>
<h3 class="text-4xl font-bold text-gray-800 mt-2">{{ $totalRules }}</h3> Daftar Rule Basis
</div>
<div class="w-14 h-14 bg-gradient-to-br from-purple-400 to-purple-600 rounded-2xl flex items-center justify-center shadow-lg">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01"></path>
</svg>
</div>
</div> </div>
<a href="{{ route('admin.rule-basis.create') }}" class="btn-add">
<svg width="13" height="13" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4"/>
</svg>
Tambah Rule
</a>
</div> </div>
<div class="bg-white rounded-2xl p-6 shadow-lg hover:shadow-xl transition-shadow"> {{-- Filter --}}
<div class="flex items-center justify-between"> <div class="filter-bar anim a2">
<div class="flex-1"> <form method="GET" action="{{ route('admin.rule-basis.index') }}" style="display:contents;">
<p class="text-sm font-semibold text-gray-500 uppercase">Rata-rata CF</p> <div class="filter-group">
<h3 class="text-4xl font-bold text-gray-800 mt-2">{{ number_format($avgCF ?? 0, 2) }}</h3> <label class="filter-label">Filter Penyakit</label>
</div> <select name="penyakit" class="filter-select">
<div class="w-14 h-14 bg-gradient-to-br from-blue-400 to-blue-600 rounded-2xl flex items-center justify-center shadow-lg">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path>
</svg>
</div>
</div>
</div>
<div class="bg-white rounded-2xl p-6 shadow-lg hover:shadow-xl transition-shadow">
<div class="flex items-center justify-between">
<div class="flex-1">
<p class="text-sm font-semibold text-gray-500 uppercase">CF Tinggi (≥0.7)</p>
<h3 class="text-4xl font-bold text-gray-800 mt-2">{{ $highConfidenceRules }}</h3>
</div>
<div class="w-14 h-14 bg-gradient-to-br from-green-400 to-green-600 rounded-2xl flex items-center justify-center shadow-lg">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
</div>
</div>
<div class="bg-white rounded-2xl p-6 shadow-lg hover:shadow-xl transition-shadow">
<div class="flex items-center justify-between">
<div class="flex-1">
<p class="text-sm font-semibold text-gray-500 uppercase">Penyakit Terintegrasi</p>
<h3 class="text-4xl font-bold text-gray-800 mt-2">{{ $totalPenyakitWithRules }}</h3>
</div>
<div class="w-14 h-14 bg-gradient-to-br from-red-400 to-red-600 rounded-2xl flex items-center justify-center shadow-lg">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
</svg>
</div>
</div>
</div>
</div>
<div class="bg-white rounded-2xl shadow-lg">
<!-- Header -->
<div class="p-6 border-b border-gray-200">
<div class="flex justify-between items-center">
<div class="flex items-center">
<div class="bg-gradient-to-r from-green-500 to-green-600 rounded-xl p-3 mr-4">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01"></path>
</svg>
</div>
<h3 class="text-xl font-bold text-gray-800">Daftar Rule Basis</h3>
</div>
{{-- FIX: Tombol Tambah Rule - warna solid purple --}}
<a href="{{ route('admin.rule-basis.create') }}"
style="background: linear-gradient(to right, #22c55e, #16a34a); color: white;"
class="flex items-center px-5 py-3 font-bold rounded-xl shadow-lg hover:shadow-xl transition-all transform hover:scale-105">
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
</svg>
Tambah Rule
</a>
</div>
</div>
<!-- Filter -->
<div class="p-6 bg-gray-50 border-b border-gray-200">
<form method="GET" action="{{ route('admin.rule-basis.index') }}" class="flex gap-4">
<div class="flex-1">
<label for="penyakit" class="block text-sm font-semibold text-gray-700 mb-2">Filter Penyakit</label>
<select name="penyakit" id="penyakit" class="w-full px-4 py-2 border border-gray-300 rounded-xl focus:ring-2 focus:ring-green-500 focus:border-green-500">
<option value="">Semua Penyakit</option> <option value="">Semua Penyakit</option>
@foreach($penyakits as $penyakit) @foreach($penyakits as $penyakit)
<option value="{{ $penyakit->id_penyakit }}" {{ request('penyakit') == $penyakit->id_penyakit ? 'selected' : '' }}> <option value="{{ $penyakit->id_penyakit }}" {{ request('penyakit') == $penyakit->id_penyakit ? 'selected' : '' }}>
{{ $penyakit->id_penyakit }} - {{ $penyakit->nama_penyakit }} {{ $penyakit->id_penyakit }} {{ $penyakit->nama_penyakit }}
</option> </option>
@endforeach @endforeach
</select> </select>
</div> </div>
<div class="flex-1"> <div class="filter-group">
<label for="gejala" class="block text-sm font-semibold text-gray-700 mb-2">Filter Gejala</label> <label class="filter-label">Filter Gejala</label>
<select name="gejala" id="gejala" class="w-full px-4 py-2 border border-gray-300 rounded-xl focus:ring-2 focus:ring-green-500 focus:border-green-500"> <select name="gejala" class="filter-select">
<option value="">Semua Gejala</option> <option value="">Semua Gejala</option>
@foreach($gejalas as $gejala) @foreach($gejalas as $gejala)
<option value="{{ $gejala->id_gejala }}" {{ request('gejala') == $gejala->id_gejala ? 'selected' : '' }}> <option value="{{ $gejala->id_gejala }}" {{ request('gejala') == $gejala->id_gejala ? 'selected' : '' }}>
{{ $gejala->id_gejala }} - {{ $gejala->nama_gejala }} {{ $gejala->id_gejala }} {{ $gejala->nama_gejala }}
</option> </option>
@endforeach @endforeach
</select> </select>
</div> </div>
<div class="flex items-end gap-2"> <div class="filter-actions">
<button type="submit" style="background-color: #22c55e; color: white;" class="px-6 py-2 font-semibold rounded-xl hover:opacity-90 transition"> <button type="submit" class="btn-filter">
<svg width="12" height="12" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.2">
<path stroke-linecap="round" stroke-linejoin="round" d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2a1 1 0 01-.293.707L13 13.414V19a1 1 0 01-.553.894l-4 2A1 1 0 017 21v-7.586L3.293 6.707A1 1 0 013 6V4z"/>
</svg>
Filter Filter
</button> </button>
@if(request('penyakit') || request('gejala')) @if(request('penyakit') || request('gejala'))
<a href="{{ route('admin.rule-basis.index') }}" class="px-6 py-2 bg-gray-300 text-gray-700 font-semibold rounded-xl hover:bg-gray-400 transition"> <a href="{{ route('admin.rule-basis.index') }}" class="btn-reset">
<svg width="12" height="12" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.2">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
</svg>
Reset Reset
</a> </a>
@endif @endif
@ -134,79 +252,66 @@ class="flex items-center px-5 py-3 font-bold rounded-xl shadow-lg hover:shadow-x
</form> </form>
</div> </div>
<!-- Table --> {{-- Table --}}
<div class="overflow-x-auto"> <div class="table-wrap anim a3">
<table class="min-w-full divide-y divide-gray-200"> <table>
<thead class="bg-gray-50"> <thead>
<tr> <tr>
<th class="px-6 py-4 text-left text-xs font-bold text-gray-600 uppercase">No</th> <th>No</th>
<th class="px-6 py-4 text-left text-xs font-bold text-gray-600 uppercase">Penyakit</th> <th>Penyakit</th>
<th class="px-6 py-4 text-left text-xs font-bold text-gray-600 uppercase">Gejala</th> <th>Gejala</th>
<th class="px-6 py-4 text-center text-xs font-bold text-gray-600 uppercase">MB</th> <th class="center">MB</th>
<th class="px-6 py-4 text-center text-xs font-bold text-gray-600 uppercase">MD</th> <th class="center">MD</th>
<th class="px-6 py-4 text-center text-xs font-bold text-gray-600 uppercase">CF</th> <th class="center">CF</th>
<th class="px-6 py-4 text-left text-xs font-bold text-gray-600 uppercase">Keterangan</th> <th>Keterangan</th>
<th class="px-6 py-4 text-center text-xs font-bold text-gray-600 uppercase">Aksi</th> <th class="center">Aksi</th>
</tr> </tr>
</thead> </thead>
<tbody class="bg-white divide-y divide-gray-200"> <tbody>
@forelse ($rules as $index => $rule) @forelse($rules as $index => $rule)
<tr class="hover:bg-gray-50 transition-colors"> <tr>
<td class="px-6 py-4 text-sm text-gray-900">{{ $rules->firstItem() + $index }}</td> <td class="td-no">{{ $rules->firstItem() + $index }}</td>
<td class="px-6 py-4">
<div class="text-sm"> <td>
<span class="px-2 py-1 bg-red-100 text-red-800 rounded-full text-xs font-bold"> <div class="id-pill">{{ $rule->id_penyakit }}</div>
{{ $rule->id_penyakit }} <div class="cell-name">{{ $rule->penyakit->nama_penyakit ?? '-' }}</div>
</span>
<p class="mt-1 font-semibold text-gray-900">{{ $rule->penyakit->nama_penyakit ?? '-' }}</p>
</div>
</td> </td>
<td class="px-6 py-4">
<div class="text-sm"> <td>
<span class="px-2 py-1 bg-green-100 text-green-800 rounded-full text-xs font-bold"> <div class="id-pill">{{ $rule->id_gejala }}</div>
{{ $rule->id_gejala }} <div class="cell-sub">{{ $rule->gejala->nama_gejala ?? '-' }}</div>
</span>
<p class="mt-1 text-gray-700">{{ $rule->gejala->nama_gejala ?? '-' }}</p>
</div>
</td> </td>
<td class="px-6 py-4 text-center">
<span class="px-3 py-1 bg-blue-100 text-blue-800 rounded-lg text-sm font-bold"> <td style="text-align:center;">
{{ number_format($rule->mb, 2) }} <span class="num-badge">{{ number_format($rule->mb, 2) }}</span>
</td>
<td style="text-align:center;">
<span class="num-badge">{{ number_format($rule->md, 2) }}</span>
</td>
<td style="text-align:center;">
@php $cf = $rule->cf_pakar; @endphp
<span class="num-badge {{ $cf >= 0.7 ? 'cf-high' : ($cf >= 0.4 ? 'cf-mid' : 'cf-low') }}">
{{ number_format($cf, 2) }}
</span> </span>
</td> </td>
<td class="px-6 py-4 text-center">
<span class="px-3 py-1 bg-orange-100 text-orange-800 rounded-lg text-sm font-bold"> <td class="td-keterangan">{{ Str::limit($rule->keterangan ?? '-', 50) }}</td>
{{ number_format($rule->md, 2) }}
</span> <td>
</td> <div class="actions">
<td class="px-6 py-4 text-center"> <a href="{{ route('admin.rule-basis.edit', $rule->id_rule) }}" class="btn-edit">
<span class="px-3 py-1 bg-purple-100 text-purple-800 rounded-lg text-sm font-bold"> <svg width="12" height="12" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.2">
{{ number_format($rule->cf_pakar, 2) }} <path stroke-linecap="round" stroke-linejoin="round" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
</span>
</td>
<td class="px-6 py-4 text-sm text-gray-600 max-w-xs truncate">
{{ $rule->keterangan ?? '-' }}
</td>
<td class="px-6 py-4 text-center">
<div class="flex justify-center space-x-2">
{{-- FIX: Gunakan id_rule eksplisit untuk route model binding --}}
<a href="{{ route('admin.rule-basis.edit', $rule->id_rule) }}"
class="inline-flex items-center px-3 py-2 bg-blue-500 text-white text-xs font-semibold rounded-lg hover:bg-blue-600 transition">
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path>
</svg> </svg>
Edit Edit
</a> </a>
{{-- FIX: Form delete dengan id_rule eksplisit --}} <form action="{{ route('admin.rule-basis.destroy', $rule->id_rule) }}" method="POST"
<form action="{{ route('admin.rule-basis.destroy', $rule->id_rule) }}" onsubmit="return confirm('Yakin ingin menghapus rule ini?')" style="display:contents;">
method="POST"
onsubmit="return confirm('Yakin ingin menghapus rule ini?')"
style="display: inline;">
@csrf @csrf
@method('DELETE') @method('DELETE')
<button type="submit" class="inline-flex items-center px-3 py-2 bg-red-500 text-white text-xs font-semibold rounded-lg hover:bg-red-600 transition"> <button type="submit" class="btn-del">
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg width="12" height="12" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.2">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path> <path stroke-linecap="round" stroke-linejoin="round" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
</svg> </svg>
Hapus Hapus
</button> </button>
@ -216,13 +321,13 @@ class="inline-flex items-center px-3 py-2 bg-blue-500 text-white text-xs font-se
</tr> </tr>
@empty @empty
<tr> <tr>
<td colspan="8" class="px-6 py-12 text-center"> <td colspan="8">
<div class="text-gray-400"> <div class="empty-state">
<svg class="w-16 h-16 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="empty-icon" fill="none" stroke="#2d7a4f" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01"/>
</svg> </svg>
<p class="text-xl font-semibold mb-2">Belum ada rule basis</p> <h4>Belum ada rule basis</h4>
<p class="text-sm">Klik "Tambah Rule" untuk menambahkan aturan diagnosa</p> <p>Klik <strong>Tambah Rule</strong> untuk menambahkan aturan diagnosa.</p>
</div> </div>
</td> </td>
</tr> </tr>
@ -231,9 +336,13 @@ class="inline-flex items-center px-3 py-2 bg-blue-500 text-white text-xs font-se
</table> </table>
</div> </div>
<!-- Pagination --> {{-- Pagination --}}
<div class="px-6 py-4 border-t border-gray-200"> @if($rules->hasPages())
{{ $rules->links() }} <div class="pagination-wrap">
</div> {{ $rules->links() }}
</div>
@endif
</div> </div>
</div>
@endsection @endsection

View File

@ -102,15 +102,12 @@ class="sidebar-transition bg-gradient-to-b from-gray-900 via-gray-800 to-gray-90
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div x-show="sidebarOpen" class="flex items-center space-x-3"> <div x-show="sidebarOpen" class="flex items-center space-x-3">
<div class="logo-float"> <div class="logo-float">
<div class="w-10 h-10 bg-gradient-to-br from-green-400 to-green-600 rounded-xl flex items-center justify-center shadow-lg"> <div class="w-10 h-10 rounded-xl overflow-hidden shadow-lg flex-shrink-0">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <img src="{{ asset('asset/images/ori_nobg.png') }}" class="w-full h-full object-cover" alt="Logo">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"></path>
</svg>
</div> </div>
</div> </div>
<div> <div>
<h1 class="text-lg font-bold bg-gradient-to-r from-green-400 to-green-200 bg-clip-text text-transparent">Coffee Expert</h1> <h1 class="text-lg font-bold bg-gradient-to-r from-green-400 to-green-200 bg-clip-text text-transparent">Cek Kopi</h1>
<p class="text-xs text-gray-400">Admin Panel</p>
</div> </div>
</div> </div>
<button <button
@ -253,20 +250,10 @@ class="flex items-center px-3 py-2 rounded-lg hover:bg-gray-700 {{ request()->ro
<h2 class="text-2xl font-bold text-gray-800"> <h2 class="text-2xl font-bold text-gray-800">
@yield('page-title', 'Dashboard') @yield('page-title', 'Dashboard')
</h2> </h2>
<p class="text-sm text-gray-500 mt-1">
@yield('page-subtitle', 'Sistem Pakar Diagnosa Penyakit Tanaman Kopi')
</p>
</div> </div>
<!-- User Info --> <!-- User Info -->
<div class="flex items-center space-x-4"> <div class="flex items-center space-x-4">
<!-- Notifications -->
<button class="relative p-2 text-gray-600 hover:text-gray-800 hover:bg-gray-100 rounded-xl transition-colors">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"></path>
</svg>
<span class="absolute top-1 right-1 w-2 h-2 bg-red-500 rounded-full badge-pulse"></span>
</button>
<!-- User Profile - Clickable --> <!-- User Profile - Clickable -->
<a href="{{ route('profile.edit') }}" class="flex items-center space-x-3 px-3 py-2 rounded-xl bg-gradient-to-r from-green-50 to-green-100 hover:from-green-100 hover:to-green-200 transition-all"> <a href="{{ route('profile.edit') }}" class="flex items-center space-x-3 px-3 py-2 rounded-xl bg-gradient-to-r from-green-50 to-green-100 hover:from-green-100 hover:to-green-200 transition-all">
@ -293,7 +280,7 @@ class="flex items-center px-3 py-2 rounded-lg hover:bg-gray-700 {{ request()->ro
<!-- Footer --> <!-- Footer -->
<footer class="px-8 py-6 bg-white border-t border-gray-200"> <footer class="px-8 py-6 bg-white border-t border-gray-200">
<div class="text-center text-sm text-gray-600"> <div class="text-center text-sm text-gray-600">
&copy; {{ date('Y') }} Coffee Expert System. All rights reserved. &copy; {{ date('Y') }} Cek Kopi by Evi. All rights reserved.
</div> </div>
</footer> </footer>
</div> </div>

View File

@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}"> <meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title> <title>{{ config('app.name', 'CekKopi') }}</title>
<!-- Fonts --> <!-- Fonts -->
<link rel="preconnect" href="https://fonts.bunny.net"> <link rel="preconnect" href="https://fonts.bunny.net">

View File

@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}"> <meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title> <title>{{ config('app.name', 'CekKopi') }}</title>
<!-- Fonts --> <!-- Fonts -->
<link rel="preconnect" href="https://fonts.bunny.net"> <link rel="preconnect" href="https://fonts.bunny.net">

View File

@ -69,23 +69,19 @@ class="sidebar-transition sidebar-bg text-white fixed h-full z-30 flex flex-col
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div x-show="sidebarOpen" class="flex items-center space-x-3"> <div x-show="sidebarOpen" class="flex items-center space-x-3">
<div class="logo-float"> <div class="logo-float">
<div class="w-10 h-10 bg-gradient-to-br from-yellow-400 to-amber-600 rounded-xl flex items-center justify-center shadow-lg"> <div class="w-10 h-10 rounded-xl overflow-hidden shadow-lg flex-shrink-0">
<svg class="w-6 h-6 text-white crown-glow" fill="currentColor" viewBox="0 0 24 24"> <img src="{{ asset('asset/images/ori_nobg.png') }}" class="w-full h-full object-cover" alt="Logo">
<path d="M2 19l2-8 4 4 4-8 4 8 4-4 2 8H2z"/>
</svg>
</div> </div>
</div> </div>
<div> <div>
<h1 class="text-lg font-bold bg-gradient-to-r from-yellow-400 to-amber-200 bg-clip-text text-transparent">Coffee Expert</h1> <h1 class="text-lg font-bold bg-gradient-to-r from-green-400 to-green-200 bg-clip-text text-transparent">Cek Kopi</h1>
<p class="text-xs text-purple-300/70">Super Admin Panel</p> <p class="text-xs text-purple-300/70">Super Admin</p>
</div> </div>
</div> </div>
<!-- Collapsed logo (when sidebar is closed) --> <!-- Collapsed logo (when sidebar is closed) -->
<div x-show="!sidebarOpen" class="mx-auto logo-float"> <div x-show="!sidebarOpen" class="mx-auto logo-float">
<div class="w-10 h-10 bg-gradient-to-br from-yellow-400 to-amber-600 rounded-xl flex items-center justify-center shadow-lg"> <div class="w-10 h-10 rounded-xl overflow-hidden shadow-lg flex-shrink-0">
<svg class="w-6 h-6 text-white crown-glow" fill="currentColor" viewBox="0 0 24 24"> <img src="{{ asset('asset/images/ori_nobg.png') }}" class="w-full h-full object-cover" alt="Logo">
<path d="M2 19l2-8 4 4 4-8 4 8 4-4 2 8H2z"/>
</svg>
</div> </div>
</div> </div>
<button x-show="sidebarOpen" @click="sidebarOpen = !sidebarOpen" class="p-2 rounded-lg hover:bg-green-800/30 transition-colors"> <button x-show="sidebarOpen" @click="sidebarOpen = !sidebarOpen" class="p-2 rounded-lg hover:bg-green-800/30 transition-colors">
@ -106,10 +102,10 @@ class="sidebar-transition sidebar-bg text-white fixed h-full z-30 flex flex-col
<!-- Dashboard --> <!-- Dashboard -->
<a href="{{ route('super-admin.dashboard') }}" <a href="{{ route('super-admin.dashboard') }}"
class="flex items-center px-4 py-3 rounded-xl hover:bg-green-800/30 {{ request()->routeIs('super-admin.dashboard') ? 'bg-green-800/40 ring-1 ring-green-500/30' : '' }} group"> class="flex items-center px-4 py-3 rounded-xl hover:bg-green-800/30 {{ request()->routeIs('super-admin.dashboard') ? 'bg-green-700/50 ring-1 ring-green-400/60' : '' }} group">
<div class="flex items-center flex-1"> <div class="flex items-center flex-1">
<div class="w-10 h-10 flex items-center justify-center rounded-lg bg-blue-500/20 group-hover:bg-blue-500/30 transition-colors"> <div class="w-10 h-10 flex items-center justify-center rounded-lg bg-green-500/20 group-hover:bg-green-500/30 transition-colors">
<svg class="w-5 h-5 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-5 h-5 text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"></path>
</svg> </svg>
</div> </div>
@ -145,13 +141,8 @@ class="flex items-center px-4 py-3 rounded-xl hover:bg-green-800/30 {{ request()
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div> <div>
<h2 class="text-2xl font-bold text-gray-800">@yield('page-title', 'Dashboard')</h2> <h2 class="text-2xl font-bold text-gray-800">@yield('page-title', 'Dashboard')</h2>
<p class="text-sm text-gray-500 mt-1">@yield('page-subtitle', 'Sistem Pakar Diagnosa Penyakit Tanaman Kopi')</p>
</div> </div>
<div class="flex items-center space-x-4"> <div class="flex items-center space-x-4">
<!-- Super Admin Badge -->
<span class="px-3 py-1 rounded-full text-xs font-bold bg-gradient-to-r from-yellow-400 to-amber-500 text-white shadow badge-pulse">
SUPER ADMIN
</span>
<!-- Profile --> <!-- Profile -->
<a href="{{ route('profile.edit') }}" class="flex items-center space-x-3 px-3 py-2 rounded-xl bg-gradient-to-r from-green-50 to-green-100 hover:from-green-100 hover:to-green-200 transition-all"> <a href="{{ route('profile.edit') }}" class="flex items-center space-x-3 px-3 py-2 rounded-xl bg-gradient-to-r from-green-50 to-green-100 hover:from-green-100 hover:to-green-200 transition-all">
<div class="w-10 h-10 rounded-full bg-gradient-to-br from-green-500 to-green-700 flex items-center justify-center text-white font-bold shadow-lg"> <div class="w-10 h-10 rounded-full bg-gradient-to-br from-green-500 to-green-700 flex items-center justify-center text-white font-bold shadow-lg">

View File

@ -61,15 +61,12 @@ class="sidebar-transition bg-gradient-to-b from-gray-900 via-gray-800 to-gray-90
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div x-show="sidebarOpen" class="flex items-center space-x-3"> <div x-show="sidebarOpen" class="flex items-center space-x-3">
<div class="logo-float"> <div class="logo-float">
<div class="w-10 h-10 bg-gradient-to-br from-green-400 to-green-600 rounded-xl flex items-center justify-center shadow-lg"> <div class="w-10 h-10 rounded-xl overflow-hidden shadow-lg flex-shrink-0">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <img src="{{ asset('asset/images/ori_nobg.png') }}" class="w-full h-full object-cover" alt="Logo">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"></path>
</svg>
</div> </div>
</div> </div>
<div> <div>
<h1 class="text-lg font-bold bg-gradient-to-r from-green-400 to-green-200 bg-clip-text text-transparent">Coffee Expert</h1> <h1 class="text-lg font-bold bg-gradient-to-r from-green-400 to-green-200 bg-clip-text text-transparent">Cek Kopi</h1>
<p class="text-xs text-gray-400">Sistem Pakar Kopi</p>
</div> </div>
</div> </div>
<button @click="sidebarOpen = !sidebarOpen" class="p-2 rounded-lg hover:bg-gray-700 transition-colors"> <button @click="sidebarOpen = !sidebarOpen" class="p-2 rounded-lg hover:bg-gray-700 transition-colors">
@ -189,7 +186,6 @@ class="flex items-center px-3 py-2 rounded-lg hover:bg-gray-700 {{ request()->ro
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div> <div>
<h2 class="text-2xl font-bold text-gray-800">@yield('page-title', 'Dashboard')</h2> <h2 class="text-2xl font-bold text-gray-800">@yield('page-title', 'Dashboard')</h2>
<p class="text-sm text-gray-500 mt-1">@yield('page-subtitle', 'Sistem Pakar Diagnosa Penyakit Tanaman Kopi')</p>
</div> </div>
<div class="flex items-center space-x-4"> <div class="flex items-center space-x-4">
<!-- Profile --> <!-- Profile -->
@ -217,7 +213,7 @@ class="flex items-center px-3 py-2 rounded-lg hover:bg-gray-700 {{ request()->ro
<!-- Footer --> <!-- Footer -->
<footer class="px-8 py-6 bg-white border-t border-gray-200"> <footer class="px-8 py-6 bg-white border-t border-gray-200">
<div class="text-center text-sm text-gray-600"> <div class="text-center text-sm text-gray-600">
&copy; {{ date('Y') }} Coffee Expert System. All rights reserved. &copy; {{ date('Y') }} Cek Kopi by Evi. All rights reserved.
</div> </div>
</footer> </footer>
</div> </div>

View File

@ -1,232 +1,336 @@
@extends(auth()->user()->role === 'admin' || auth()->user()->role === 'super_admin' ? 'layouts.superadmin-app' : 'layouts.user-app') @extends(
auth()->user()->role === 'super_admin' ? 'layouts.superadmin-app' :
(auth()->user()->role === 'admin' ? 'layouts.admin-app' : 'layouts.user-app')
)
@section('page-title', 'Profile Settings') @section('page-title', 'Profile Settings')
@section('page-subtitle', 'Kelola informasi profil Anda') @section('page-subtitle', 'Kelola informasi profil Anda')
@section('content') @push('styles')
<!-- Profile Information Card --> <link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<div class="bg-white rounded-2xl shadow-lg mb-6"> <style>
<div class="p-8"> :root {
<div class="flex items-center mb-6"> --green-deep: #1a4d2e;
<div class="bg-gradient-to-r from-green-500 to-green-600 rounded-xl p-3 mr-4"> --green-mid: #2d7a4f;
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> --green-bright:#4ade80;
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"></path> --bg-base: #f0f5f1;
</svg> --bg-card: #ffffff;
</div> --text-primary:#0f1f14;
<div> --text-muted: #6b7f72;
<h3 class="text-xl font-bold text-gray-800">Profile Information</h3> --shadow: 0 4px 24px rgba(29,77,46,.08), 0 1px 4px rgba(29,77,46,.05);
<p class="text-sm text-gray-600">Update your account's profile information and email address</p> --radius: 20px;
</div> --input-border:#d1d5db;
</div> --input-focus: #2d7a4f;
}
body, .profile-root { font-family: 'Plus Jakarta Sans', sans-serif; }
@if (session('status') === 'profile-updated') @keyframes fadeUp {
<div class="mb-6 bg-green-100 border-l-4 border-green-500 text-green-700 p-4 rounded-lg flex items-center"> from { opacity:0; transform:translateY(12px); }
<svg class="w-6 h-6 mr-3" fill="currentColor" viewBox="0 0 20 20"> to { opacity:1; transform:translateY(0); }
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/> }
.anim { animation: fadeUp .5s cubic-bezier(.22,1,.36,1) both; }
.a1 { animation-delay:.04s; }
.a2 { animation-delay:.12s; }
.a3 { animation-delay:.20s; }
/* ── card ── */
.profile-card {
background: var(--bg-card);
border-radius: var(--radius);
border: 1.5px solid rgba(29,77,46,.07);
box-shadow: var(--shadow);
overflow: hidden;
margin-bottom: 1.25rem;
}
.profile-card.danger {
border-color: #fecaca;
}
/* ── card header ── */
.card-hdr {
display: flex; align-items: center; gap: .65rem;
padding: 1.1rem 1.75rem;
border-bottom: 1.5px solid rgba(29,77,46,.07);
}
.card-hdr.danger-hdr { border-bottom-color: #fecaca; }
.card-hdr-icon {
width: 34px; height: 34px; border-radius: 10px; flex-shrink: 0;
display: flex; align-items: center; justify-content: center;
}
.icon-green { background: #dcfce7; }
.icon-slate { background: #f1f5f9; }
.icon-red { background: #fee2e2; }
.card-hdr-title { font-size: .92rem; font-weight: 700; color: var(--text-primary); letter-spacing: -.01em; }
.card-hdr-sub { font-size: .73rem; color: var(--text-muted); margin-top: 1px; }
/* ── form body ── */
.card-body { padding: 1.5rem 1.75rem; }
/* ── section title ── */
.form-section-title {
display: flex; align-items: center; gap: .5rem;
font-size: .72rem; font-weight: 700; text-transform: uppercase;
letter-spacing: .08em; color: var(--text-muted);
margin-bottom: 1.1rem; padding-bottom: .55rem;
border-bottom: 1.5px solid rgba(29,77,46,.07);
}
.section-bar { width: 3px; height: 13px; border-radius: 2px; flex-shrink: 0; background: linear-gradient(180deg, var(--green-mid), var(--green-bright)); }
.section-bar.red { background: linear-gradient(180deg, #ef4444, #f87171); }
/* ── alert ── */
.alert {
display: flex; align-items: center; gap: .65rem;
padding: .8rem 1rem; margin-bottom: 1.25rem;
border-radius: 12px; font-size: .82rem; font-weight: 600;
}
.alert-success { background: #f0fdf4; border: 1.5px solid #bbf7d0; color: #166534; }
.alert svg { flex-shrink: 0; }
/* ── form fields ── */
.field { margin-bottom: 1.1rem; }
.field:last-of-type { margin-bottom: 0; }
.form-label { display: block; font-size: .8rem; font-weight: 700; color: var(--text-primary); margin-bottom: .4rem; }
.form-input {
width: 100%; padding: .68rem 1rem;
border: 1.5px solid var(--input-border); border-radius: 12px;
font-size: .85rem; font-family: 'Plus Jakarta Sans', sans-serif;
color: var(--text-primary); background: #fafafa; outline: none;
transition: border-color .18s, box-shadow .18s, background .18s;
}
.form-input:focus {
border-color: var(--input-focus); background: #fff;
box-shadow: 0 0 0 3px rgba(45,122,79,.1);
}
.form-input.input-slate:focus {
border-color: #64748b;
box-shadow: 0 0 0 3px rgba(100,116,139,.1);
}
.form-error { font-size: .72rem; color: #ef4444; margin-top: .3rem; }
.form-hint { font-size: .72rem; color: var(--text-muted); margin-top: .3rem; }
/* ── verify email notice ── */
.verify-notice {
margin-top: .55rem; padding: .65rem .9rem;
background: #fefce8; border: 1px solid #fde68a; border-radius: 10px;
font-size: .75rem; color: #a16207;
}
.verify-notice button { background: none; border: none; cursor: pointer; color: #ca8a04; font-weight: 700; text-decoration: underline; font-size: .75rem; font-family: 'Plus Jakarta Sans', sans-serif; }
/* ── buttons ── */
.btn-submit {
display: inline-flex; align-items: center; gap: .45rem;
padding: .65rem 1.35rem;
background: linear-gradient(135deg, #2d7a4f, #16a34a);
color: #fff; font-size: .83rem; font-weight: 700;
border-radius: 12px; border: none; cursor: pointer;
box-shadow: 0 4px 14px rgba(22,163,74,.25);
transition: all .18s; font-family: 'Plus Jakarta Sans', sans-serif;
}
.btn-submit:hover { transform: translateY(-1px); box-shadow: 0 6px 20px rgba(22,163,74,.35); }
.btn-submit-slate {
display: inline-flex; align-items: center; gap: .45rem;
padding: .65rem 1.35rem;
background: #0f172a;
color: #fff; font-size: .83rem; font-weight: 700;
border-radius: 12px; border: none; cursor: pointer;
box-shadow: 0 4px 14px rgba(15,23,42,.15);
transition: all .18s; font-family: 'Plus Jakarta Sans', sans-serif;
}
.btn-submit-slate:hover { background: #1e293b; transform: translateY(-1px); }
.btn-danger {
display: inline-flex; align-items: center; gap: .45rem;
padding: .65rem 1.35rem;
background: #fff5f5; color: #dc2626;
border: 1.5px solid #fecaca;
font-size: .83rem; font-weight: 700;
border-radius: 12px; cursor: pointer;
transition: all .18s; font-family: 'Plus Jakarta Sans', sans-serif;
}
.btn-danger:hover { background: #fee2e2; border-color: #dc2626; }
/* ── danger section ── */
.danger-desc {
font-size: .82rem; color: var(--text-muted);
line-height: 1.6; margin-bottom: 1.25rem;
padding: .8rem 1rem; background: #fff5f5;
border-radius: 10px; border: 1px solid #fecaca;
}
</style>
@endpush
@section('content')
<div class="profile-root">
{{-- ── Profile Information ── --}}
<div class="profile-card anim a1">
<div class="card-hdr">
<div class="card-hdr-icon icon-green">
<svg width="16" height="16" fill="none" stroke="#2d7a4f" viewBox="0 0 24 24" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
</svg>
</div>
<div>
<div class="card-hdr-title">Profile Information</div>
<div class="card-hdr-sub">Perbarui informasi profil dan alamat email akun Anda</div>
</div>
</div>
<div class="card-body">
@if(session('status') === 'profile-updated')
<div class="alert alert-success">
<svg width="15" height="15" fill="none" stroke="#16a34a" viewBox="0 0 24 24" stroke-width="2.2">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg> </svg>
<span class="font-semibold">Profile updated successfully!</span> Profile berhasil diperbarui!
</div> </div>
@endif @endif
<form method="post" action="{{ route('profile.update') }}" class="space-y-6"> <div class="form-section-title">
<div class="section-bar"></div>
Informasi Akun
</div>
<form method="post" action="{{ route('profile.update') }}">
@csrf @csrf
@method('patch') @method('patch')
<!-- Username --> <div class="field">
<div> <label for="username" class="form-label">Username</label>
<label for="username" class="block text-sm font-semibold text-gray-700 mb-2">Username</label> <input type="text" id="username" name="username" value="{{ old('username', $user->username) }}" class="form-input" required>
<input @error('username') <p class="form-error">{{ $message }}</p> @enderror
type="text"
id="username"
name="username"
value="{{ old('username', $user->username) }}"
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-green-500 focus:border-green-500 transition"
required
>
@error('username')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
@enderror
</div> </div>
<!-- Nama --> <div class="field">
<div> <label for="nama" class="form-label">Nama Lengkap</label>
<label for="nama" class="block text-sm font-semibold text-gray-700 mb-2">Nama Lengkap</label> <input type="text" id="nama" name="nama" value="{{ old('nama', $user->nama) }}" class="form-input" required>
<input @error('nama') <p class="form-error">{{ $message }}</p> @enderror
type="text"
id="nama"
name="nama"
value="{{ old('nama', $user->nama) }}"
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-green-500 focus:border-green-500 transition"
required
>
@error('nama')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
@enderror
</div> </div>
<!-- Email --> <div class="field">
<div> <label for="email" class="form-label">Email</label>
<label for="email" class="block text-sm font-semibold text-gray-700 mb-2">Email</label> <input type="email" id="email" name="email" value="{{ old('email', $user->email) }}" class="form-input" required>
<input @error('email') <p class="form-error">{{ $message }}</p> @enderror
type="email" @if($user instanceof \Illuminate\Contracts\Auth\MustVerifyEmail && !$user->hasVerifiedEmail())
id="email" <div class="verify-notice">
name="email" Alamat email Anda belum diverifikasi.
value="{{ old('email', $user->email) }}" <button form="send-verification">Kirim ulang email verifikasi.</button>
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-green-500 focus:border-green-500 transition"
required
>
@error('email')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
@enderror
@if ($user instanceof \Illuminate\Contracts\Auth\MustVerifyEmail && ! $user->hasVerifiedEmail())
<div class="mt-3 p-3 bg-yellow-50 border border-yellow-200 rounded-lg">
<p class="text-sm text-yellow-800">
Your email address is unverified.
<button form="send-verification" class="underline text-sm text-yellow-600 hover:text-yellow-900">
Click here to re-send the verification email.
</button>
</p>
</div> </div>
@endif @endif
</div> </div>
<!-- Nomor HP --> <div class="field" style="margin-bottom:1.5rem;">
<div> <label for="no_hp" class="form-label">Nomor HP</label>
<label for="no_hp" class="block text-sm font-semibold text-gray-700 mb-2">Nomor HP</label> <input type="text" id="no_hp" name="no_hp" value="{{ old('no_hp', $user->no_hp) }}" class="form-input" placeholder="08123456789">
<input @error('no_hp') <p class="form-error">{{ $message }}</p> @enderror
type="text"
id="no_hp"
name="no_hp"
value="{{ old('no_hp', $user->no_hp) }}"
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-green-500 focus:border-green-500 transition"
placeholder="08123456789"
>
@error('no_hp')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
@enderror
</div> </div>
<!-- Submit Button --> <button type="submit" class="btn-submit">
<div class="flex items-center gap-4 pt-4"> <svg width="13" height="13" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.2">
<button type="submit" class="px-6 py-3 bg-gradient-to-r from-green-500 to-green-600 text-white font-bold rounded-xl hover:from-green-600 hover:to-green-700 transition-all shadow-lg hover:shadow-xl transform hover:scale-105"> <path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/>
Save Changes </svg>
</button> Simpan Perubahan
</div> </button>
</form> </form>
</div> </div>
</div> </div>
<!-- Update Password Card --> {{-- ── Update Password ── --}}
<div class="bg-white rounded-2xl shadow-lg mb-6"> <div class="profile-card anim a2">
<div class="p-8"> <div class="card-hdr">
<div class="flex items-center mb-6"> <div class="card-hdr-icon icon-slate">
<div class="bg-gradient-to-r from-blue-500 to-blue-600 rounded-xl p-3 mr-4"> <svg width="16" height="16" fill="none" stroke="#475569" viewBox="0 0 24 24" stroke-width="2">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"></path> </svg>
</svg>
</div>
<div>
<h3 class="text-xl font-bold text-gray-800">Update Password</h3>
<p class="text-sm text-gray-600">Ensure your account is using a long, random password to stay secure</p>
</div>
</div> </div>
<div>
<div class="card-hdr-title">Update Password</div>
<div class="card-hdr-sub">Pastikan akun Anda menggunakan kata sandi yang panjang dan acak</div>
</div>
</div>
<div class="card-body">
@if (session('status') === 'password-updated') @if(session('status') === 'password-updated')
<div class="mb-6 bg-green-100 border-l-4 border-green-500 text-green-700 p-4 rounded-lg flex items-center"> <div class="alert alert-success">
<svg class="w-6 h-6 mr-3" fill="currentColor" viewBox="0 0 20 20"> <svg width="15" height="15" fill="none" stroke="#16a34a" viewBox="0 0 24 24" stroke-width="2.2">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/> <path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg> </svg>
<span class="font-semibold">Password updated successfully!</span> Password berhasil diperbarui!
</div> </div>
@endif @endif
<form method="post" action="{{ route('password.update') }}" class="space-y-6"> <div class="form-section-title">
<div class="section-bar" style="background:linear-gradient(180deg,#475569,#94a3b8);"></div>
Ganti Password
</div>
<form method="post" action="{{ route('password.update') }}">
@csrf @csrf
@method('put') @method('put')
<!-- Current Password --> <div class="field">
<div> <label for="current_password" class="form-label">Password Saat Ini</label>
<label for="current_password" class="block text-sm font-semibold text-gray-700 mb-2">Current Password</label> <input type="password" id="current_password" name="current_password" class="form-input input-slate" autocomplete="current-password">
<input @error('current_password', 'updatePassword') <p class="form-error">{{ $message }}</p> @enderror
type="password"
id="current_password"
name="current_password"
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
autocomplete="current-password"
>
@error('current_password', 'updatePassword')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
@enderror
</div> </div>
<!-- New Password --> <div class="field">
<div> <label for="password" class="form-label">Password Baru</label>
<label for="password" class="block text-sm font-semibold text-gray-700 mb-2">New Password</label> <input type="password" id="password" name="password" class="form-input input-slate" autocomplete="new-password">
<input @error('password', 'updatePassword') <p class="form-error">{{ $message }}</p> @enderror
type="password"
id="password"
name="password"
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
autocomplete="new-password"
>
@error('password', 'updatePassword')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
@enderror
</div> </div>
<!-- Confirm Password --> <div class="field" style="margin-bottom:1.5rem;">
<div> <label for="password_confirmation" class="form-label">Konfirmasi Password</label>
<label for="password_confirmation" class="block text-sm font-semibold text-gray-700 mb-2">Confirm Password</label> <input type="password" id="password_confirmation" name="password_confirmation" class="form-input input-slate" autocomplete="new-password">
<input @error('password_confirmation', 'updatePassword') <p class="form-error">{{ $message }}</p> @enderror
type="password"
id="password_confirmation"
name="password_confirmation"
class="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
autocomplete="new-password"
>
@error('password_confirmation', 'updatePassword')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
@enderror
</div> </div>
<!-- Submit Button --> <button type="submit" class="btn-submit-slate">
<div class="flex items-center gap-4 pt-4"> <svg width="13" height="13" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.2">
<button type="submit" class="px-6 py-3 bg-gradient-to-r from-blue-500 to-blue-600 text-white font-bold rounded-xl hover:from-blue-600 hover:to-blue-700 transition-all shadow-lg hover:shadow-xl transform hover:scale-105"> <path stroke-linecap="round" stroke-linejoin="round" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/>
Update Password </svg>
</button> Update Password
</div> </button>
</form> </form>
</div> </div>
</div> </div>
<!-- Delete Account Card --> {{-- ── Delete Account ── --}}
<div class="bg-white rounded-2xl shadow-lg border-2 border-red-200"> <div class="profile-card danger anim a3">
<div class="p-8"> <div class="card-hdr danger-hdr">
<div class="flex items-center mb-6"> <div class="card-hdr-icon icon-red">
<div class="bg-gradient-to-r from-red-500 to-red-600 rounded-xl p-3 mr-4"> <svg width="16" height="16" fill="none" stroke="#dc2626" viewBox="0 0 24 24" stroke-width="2">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path> </svg>
</svg>
</div>
<div>
<h3 class="text-xl font-bold text-gray-800">Delete Account</h3>
<p class="text-sm text-gray-600">Once your account is deleted, all of its resources and data will be permanently deleted</p>
</div>
</div> </div>
<div>
<button <div class="card-hdr-title" style="color:#dc2626;">Hapus Akun</div>
type="button" <div class="card-hdr-sub">Tindakan ini tidak dapat dibatalkan</div>
onclick="if(confirm('Are you sure you want to delete your account? This action cannot be undone.')) { document.getElementById('delete-account-form').submit(); }" </div>
class="px-6 py-3 bg-gradient-to-r from-red-500 to-red-600 text-white font-bold rounded-xl hover:from-red-600 hover:to-red-700 transition-all shadow-lg hover:shadow-xl" </div>
> <div class="card-body">
Delete Account <div class="form-section-title">
<div class="section-bar red"></div>
Zona Berbahaya
</div>
<div class="danger-desc">
Setelah akun dihapus, semua data dan resource yang terkait akan dihapus secara permanen. Pastikan Anda telah mengunduh semua data yang diperlukan sebelum melanjutkan.
</div>
<button type="button" class="btn-danger"
onclick="if(confirm('Yakin ingin menghapus akun? Tindakan ini tidak dapat dibatalkan.')) { document.getElementById('delete-account-form').submit(); }">
<svg width="13" height="13" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.2">
<path stroke-linecap="round" stroke-linejoin="round" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
</svg>
Hapus Akun
</button> </button>
<form id="delete-account-form" method="post" action="{{ route('profile.destroy') }}" class="hidden"> <form id="delete-account-form" method="post" action="{{ route('profile.destroy') }}" class="hidden">
@csrf @csrf
@method('delete') @method('delete')
</form> </form>
</div> </div>
</div> </div>
</div>
@endsection @endsection

View File

@ -25,7 +25,6 @@
<p class="text-green-100 text-lg mt-1">{{ Auth::user()->nama }}</p> <p class="text-green-100 text-lg mt-1">{{ Auth::user()->nama }}</p>
</div> </div>
</div> </div>
<p class="text-green-50 text-base">Sistem Pakar Diagnosa Tanaman Kopi</p>
<div class="mt-4 flex items-center space-x-4"> <div class="mt-4 flex items-center space-x-4">
<div class="flex items-center bg-white bg-opacity-20 rounded-full px-4 py-2"> <div class="flex items-center bg-white bg-opacity-20 rounded-full px-4 py-2">
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20"> <svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20">

View File

@ -538,7 +538,7 @@
<div class="space-y-5 sidebar-sticky"> <div class="space-y-5 sidebar-sticky">
{{-- Info Artikel --}} {{-- Info Artikel --}}
<div class="sidebar-card"> <!-- <div class="sidebar-card">
<h3> <h3>
<span class="sidebar-icon" style="background:#e3f2fd"> <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"> <svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" fill="#1565c0" viewBox="0 0 16 16">
@ -560,7 +560,7 @@
<div class="info-row"> <div class="info-row">
<span class="lbl">Sub-bab</span> <span class="lbl">Sub-bab</span>
<span class="val blue">{{ $artikel->subBab->count() }} sub-bab</span> <span class="val blue">{{ $artikel->subBab->count() }} sub-bab</span>
</div> </div> -->
@if($artikel->file_pdf) @if($artikel->file_pdf)
<a href="{{ Storage::url($artikel->file_pdf) }}" target="_blank" class="btn-pdf"> <a href="{{ Storage::url($artikel->file_pdf) }}" target="_blank" class="btn-pdf">

View File

@ -1,211 +1,354 @@
@extends('layouts.user-app') @extends('layouts.user-app')
@section('page-title', 'Dashboard') @section('page-title', 'Dashboard')
@section('page-subtitle', 'Selamat datang di Coffee Expert System')
@push('styles')
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
:root {
--green-deep: #1a4d2e;
--green-mid: #2d7a4f;
--green-bright: #4ade80;
--green-light: #bbf7d0;
--bg-base: #f0f5f1;
--bg-card: #ffffff;
--text-primary: #0f1f14;
--text-muted: #6b7f72;
--shadow-card: 0 4px 24px rgba(29,77,46,0.08), 0 1px 4px rgba(29,77,46,0.05);
}
body, .dashboard-root {
font-family: 'Plus Jakarta Sans', sans-serif;
background: var(--bg-base);
}
/* ── Animations ── */
@keyframes fadeUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.anim { animation: fadeUp .6s cubic-bezier(.22,1,.36,1) both; }
.anim-1 { animation-delay: .04s; }
.anim-2 { animation-delay: .13s; }
.anim-3 { animation-delay: .22s; }
.anim-4 { animation-delay: .31s; }
/* ── Welcome Banner ── */
.banner {
position: relative;
background: linear-gradient(130deg, #1a4d2e 0%, #2d7a4f 60%, #38a169 100%);
border-radius: 24px;
padding: 2rem 2.25rem 1.9rem;
overflow: hidden;
box-shadow: 0 10px 40px rgba(26,77,46,.32);
color: #fff;
}
/* subtle grid texture */
.banner::before {
content: '';
position: absolute; inset: 0;
background-image: linear-gradient(rgba(255,255,255,.04) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,255,255,.04) 1px, transparent 1px);
background-size: 32px 32px;
pointer-events: none;
}
/* glow orb */
.banner::after {
content: '';
position: absolute;
top: -80px; right: -60px;
width: 280px; height: 280px;
border-radius: 50%;
background: radial-gradient(circle, rgba(74,222,128,.20) 0%, transparent 70%);
pointer-events: none;
}
.banner-inner { position: relative; z-index: 1; }
.banner-clock {
font-family: 'DM Mono', monospace;
font-size: .7rem;
letter-spacing: .06em;
color: rgba(255,255,255,.5);
margin-bottom: .6rem;
}
.banner-title {
font-size: 1.75rem;
font-weight: 800;
letter-spacing: -.03em;
line-height: 1.15;
}
.banner-sub {
font-size: .82rem;
color: #a7f3d0;
margin-top: .4rem;
font-weight: 500;
line-height: 1.5;
}
.banner-actions { display: flex; gap: .75rem; margin-top: 1.4rem; flex-wrap: wrap; }
.btn-white {
display: inline-flex; align-items: center; gap: .45rem;
padding: .6rem 1.3rem;
background: #fff;
color: var(--green-deep);
font-weight: 700; font-size: .8rem;
border-radius: 50px;
text-decoration: none;
transition: all .2s;
box-shadow: 0 2px 10px rgba(0,0,0,.14);
}
.btn-white:hover { background: #dcfce7; transform: translateY(-2px); }
.btn-ghost {
display: inline-flex; align-items: center; gap: .45rem;
padding: .6rem 1.3rem;
background: rgba(255,255,255,.13);
border: 1.5px solid rgba(255,255,255,.28);
color: #fff;
font-weight: 700; font-size: .8rem;
border-radius: 50px;
text-decoration: none;
transition: all .2s;
}
.btn-ghost:hover { background: rgba(255,255,255,.22); transform: translateY(-2px); }
/* ── Stat Card ── */
.stat-card {
background: var(--bg-card);
border-radius: 24px;
padding: 1.75rem 1.75rem 1.5rem;
box-shadow: var(--shadow-card);
border: 1.5px solid rgba(29,77,46,.07);
display: flex;
flex-direction: column;
justify-content: space-between;
position: relative;
overflow: hidden;
transition: transform .2s, box-shadow .2s;
min-width: 195px;
}
.stat-card:hover { transform: translateY(-4px); box-shadow: 0 12px 36px rgba(29,77,46,.14); }
/* bottom accent line */
.stat-card::after {
content: '';
position: absolute;
bottom: 0; left: 0; right: 0;
height: 3px;
background: linear-gradient(90deg, var(--green-mid), var(--green-bright));
border-radius: 0 0 24px 24px;
}
.stat-label {
font-size: .68rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: .1em;
color: var(--text-muted);
}
.stat-value {
font-size: 3.2rem;
font-weight: 800;
color: var(--text-primary);
letter-spacing: -.05em;
line-height: 1;
margin-top: .55rem;
}
.stat-sub {
font-size: .72rem;
color: var(--text-muted);
margin-top: .35rem;
font-weight: 500;
}
.stat-icon-wrap {
width: 50px; height: 50px;
border-radius: 14px;
background: linear-gradient(135deg, #dcfce7, #bbf7d0);
display: flex; align-items: center; justify-content: center;
align-self: flex-end;
margin-top: 1rem;
flex-shrink: 0;
}
/* ── Chart Cards ── */
.chart-card {
background: var(--bg-card);
border-radius: 24px;
padding: 1.75rem;
box-shadow: var(--shadow-card);
border: 1.5px solid rgba(29,77,46,.07);
transition: transform .2s, box-shadow .2s;
}
.chart-card:hover { transform: translateY(-3px); box-shadow: 0 10px 32px rgba(29,77,46,.12); }
.chart-heading {
display: flex; align-items: center; gap: .6rem;
font-size: .92rem; font-weight: 700;
color: var(--text-primary);
letter-spacing: -.01em;
margin-bottom: 1.25rem;
}
.chart-heading-bar {
width: 4px; height: 18px; border-radius: 4px; flex-shrink: 0;
background: linear-gradient(180deg, var(--green-mid), var(--green-bright));
}
/* ── Layout Grids ── */
.top-row {
display: grid;
grid-template-columns: 1fr auto;
gap: 1.25rem;
align-items: stretch;
margin-bottom: 1.25rem;
}
.charts-row {
display: grid;
grid-template-columns: 3fr 2fr;
gap: 1.25rem;
}
@media (max-width: 767px) {
.top-row { grid-template-columns: 1fr; }
}
@media (max-width: 1023px) {
.charts-row { grid-template-columns: 1fr; }
}
/* ── Empty State ── */
.empty-state {
display: flex; flex-direction: column; align-items: center; justify-content: center;
height: 200px; color: var(--text-muted); gap: .75rem;
}
.empty-state svg { opacity: .3; }
.empty-state p { font-size: .82rem; font-weight: 500; }
</style>
@endpush
@section('content') @section('content')
<div class="dashboard-root">
<!-- Welcome Banner --> <!-- ── Row 1: Banner + Stat Card ── -->
<div class="bg-gradient-to-r from-green-600 to-green-400 rounded-2xl p-6 mb-8 text-white shadow-lg"> <div class="top-row anim anim-1">
<div class="flex items-center justify-between">
<!-- Welcome Banner -->
<div class="banner">
<div class="banner-inner">
<p class="banner-clock" id="realtime-clock"></p>
<h2 class="banner-title">Halo, {{ Auth::user()->nama }}! 👋</h2>
<p class="banner-sub">Selamat datang kembali di Cek Kopi.<br>Apa yang ingin kamu lakukan hari ini?</p>
<div class="banner-actions">
<a href="{{ route('user.diagnosa.index') }}" class="btn-white">
<svg width="13" height="13" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/></svg>
Mulai Diagnosa
</a>
<a href="{{ route('user.artikel.budidaya') }}" class="btn-ghost">
<svg width="13" height="13" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"/></svg>
Baca Artikel
</a>
</div>
</div>
</div>
<!-- Total Diagnosa Card -->
<div class="stat-card anim anim-2">
<div> <div>
<h2 class="text-2xl font-bold mb-1">Halo, {{ Auth::user()->nama }}!</h2> <p class="stat-label">Total Diagnosa</p>
<p class="text-green-100 text-sm">Selamat datang kembali di sistem pakar kopi. Apa yang ingin kamu lakukan hari ini?</p> <p class="stat-value">{{ $totalDiagnosa }}</p>
<p id="realtime-clock" class="text-green-200 text-xs mt-2 font-medium"></p> <p class="stat-sub">Sepanjang waktu</p>
</div>
<div class="hidden md:block">
<svg class="w-20 h-20 text-green-200 opacity-50" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"></path>
</svg>
</div> </div>
</div> </div>
<div class="flex space-x-3 mt-4">
<a href="{{ route('user.diagnosa.index') }}" class="px-4 py-2 bg-white text-green-700 font-bold rounded-xl text-sm hover:bg-green-50 transition shadow">
Mulai Diagnosa
</a>
<a href="{{ route('user.artikel.budidaya') }}" class="px-4 py-2 bg-green-700 text-white font-bold rounded-xl text-sm hover:bg-green-800 transition">
Baca Artikel
</a>
</div>
</div> </div>
<!-- Stats Cards --> <!-- ── Row 2: Charts side by side ── -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8"> <div class="charts-row">
<!-- Total Diagnosa -->
<div class="bg-white rounded-2xl shadow-lg p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-sm text-gray-500 font-medium">Total Diagnosa</p>
<p class="text-3xl font-bold text-gray-800 mt-1">{{ $totalDiagnosa }}</p>
<p class="text-xs text-gray-400 mt-1">Sepanjang waktu</p>
</div>
<div class="w-14 h-14 bg-blue-100 rounded-xl flex items-center justify-center">
<svg class="w-7 h-7 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path>
</svg>
</div>
</div>
</div>
<!-- Diagnosa Bulan Ini -->
<div class="bg-white rounded-2xl shadow-lg p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-sm text-gray-500 font-medium">Diagnosa Bulan Ini</p>
<p class="text-3xl font-bold text-gray-800 mt-1">{{ $diagnosabulanIni }}</p>
<p class="text-xs text-gray-400 mt-1">{{ now()->format('F Y') }}</p>
</div>
<div class="w-14 h-14 bg-green-100 rounded-xl flex items-center justify-center">
<svg class="w-7 h-7 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
</svg>
</div>
</div>
</div>
<!-- Diagnosa Terakhir -->
<div class="bg-white rounded-2xl shadow-lg p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-sm text-gray-500 font-medium">Diagnosa Terakhir</p>
@if($riwayatTerbaru->first())
<p class="text-sm font-bold text-gray-800 mt-1">{{ $riwayatTerbaru->first()->penyakit->nama_penyakit ?? '-' }}</p>
<p class="text-xs text-gray-400 mt-1">{{ $riwayatTerbaru->first()->tanggal->format('d M Y') }}</p>
@else
<p class="text-sm font-bold text-gray-800 mt-1">Belum ada</p>
<p class="text-xs text-gray-400 mt-1">-</p>
@endif
</div>
<div class="w-14 h-14 bg-yellow-100 rounded-xl flex items-center justify-center">
<svg class="w-7 h-7 text-yellow-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
</div>
</div>
</div>
<!-- Chart & Statistik -->
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-8">
<!-- Line Chart --> <!-- Line Chart -->
<div class="lg:col-span-2 bg-white rounded-2xl shadow-lg p-6"> <div class="chart-card anim anim-3">
<h3 class="text-lg font-bold text-gray-800 mb-4">Aktivitas Diagnosa (6 Bulan Terakhir)</h3> <div class="chart-heading">
<div style="height: 250px;"> <div class="chart-heading-bar"></div>
Aktivitas Diagnosa <span style="color:var(--text-muted);font-weight:500;">(6 Bulan Terakhir)</span>
</div>
<div style="height: 240px;">
<canvas id="lineChart"></canvas> <canvas id="lineChart"></canvas>
</div> </div>
</div> </div>
<!-- Pie Chart --> <!-- Doughnut Chart -->
<div class="bg-white rounded-2xl shadow-lg p-6"> <div class="chart-card anim anim-4">
<h3 class="text-lg font-bold text-gray-800 mb-4">Distribusi Penyakit</h3> <div class="chart-heading">
<div class="chart-heading-bar"></div>
Distribusi Penyakit
</div>
@if($statistikPenyakit->count() > 0) @if($statistikPenyakit->count() > 0)
<div style="height: 250px;"> <div style="height: 240px;">
<canvas id="pieChart"></canvas> <canvas id="pieChart"></canvas>
</div> </div>
@else @else
<div class="flex flex-col items-center justify-center h-40 text-gray-400"> <div class="empty-state">
<svg class="w-12 h-12 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg width="48" height="48" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
</svg> </svg>
<p class="text-sm">Belum ada data</p> <p>Belum ada data diagnosa</p>
</div>
@endif
</div>
</div>
<!-- Tabel Statistik & Riwayat Terbaru -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- Statistik Penyakit -->
<div class="bg-white rounded-2xl shadow-lg p-6">
<h3 class="text-lg font-bold text-gray-800 mb-4">Statistik Penyakit Terdiagnosa</h3>
@if($statistikPenyakit->count() > 0)
<div class="space-y-3">
@foreach($statistikPenyakit as $stat)
<div class="flex items-center justify-between">
<div class="flex items-center space-x-3">
<div class="w-3 h-3 rounded-full bg-green-500"></div>
<span class="text-sm font-medium text-gray-700">{{ $stat->penyakit->nama_penyakit ?? $stat->penyakit_final }}</span>
</div>
<div class="flex items-center space-x-2">
<div class="w-24 bg-gray-200 rounded-full h-2">
<div class="bg-green-500 h-2 rounded-full" style="width: {{ $totalDiagnosa > 0 ? ($stat->total / $totalDiagnosa * 100) : 0 }}%"></div>
</div>
<span class="text-sm font-bold text-gray-800">{{ $stat->total }}x</span>
</div>
</div>
@endforeach
</div>
@else
<div class="text-center text-gray-400 py-8">
<p class="text-sm">Belum ada data statistik</p>
</div> </div>
@endif @endif
</div> </div>
<!-- Riwayat Terbaru -->
<div class="bg-white rounded-2xl shadow-lg p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-bold text-gray-800">Riwayat Terbaru</h3>
<a href="{{ route('user.diagnosa.riwayat') }}" class="text-xs text-green-600 font-semibold hover:underline">Lihat Semua</a>
</div>
@forelse($riwayatTerbaru as $riwayat)
<div class="flex items-center justify-between py-3 border-b border-gray-100 last:border-0">
<div>
<p class="text-sm font-semibold text-gray-800">{{ $riwayat->penyakit->nama_penyakit ?? '-' }}</p>
<p class="text-xs text-gray-400">{{ $riwayat->tanggal->format('d M Y, H:i') }}</p>
</div>
<div class="text-right">
<span class="px-2 py-1 text-xs font-bold rounded-full
{{ $riwayat->cf_tertinggi >= 0.8 ? 'bg-red-100 text-red-700' : ($riwayat->cf_tertinggi >= 0.5 ? 'bg-yellow-100 text-yellow-700' : 'bg-green-100 text-green-700') }}">
{{ round($riwayat->cf_tertinggi * 100, 1) }}%
</span>
<a href="{{ route('user.diagnosa.hasil', $riwayat->id_diagnosis) }}" class="block text-xs text-blue-500 hover:underline mt-1">Detail</a>
</div>
</div>
@empty
<div class="text-center text-gray-400 py-8">
<p class="text-sm">Belum ada riwayat diagnosa</p>
<a href="{{ route('user.diagnosa.index') }}" class="text-green-600 text-sm font-semibold hover:underline">Mulai diagnosa sekarang</a>
</div>
@endforelse
</div>
</div> </div>
</div>
@endsection @endsection
@push('scripts') @push('scripts')
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script> <script>
// Line Chart /* ── Line Chart ── */
const lineCtx = document.getElementById('lineChart').getContext('2d'); const lineCtx = document.getElementById('lineChart').getContext('2d');
const lineGrad = lineCtx.createLinearGradient(0, 0, 0, 240);
lineGrad.addColorStop(0, 'rgba(45,122,79,.20)');
lineGrad.addColorStop(1, 'rgba(45,122,79,0)');
new Chart(lineCtx, { new Chart(lineCtx, {
type: 'line', type: 'line',
data: { data: {
labels: {!! json_encode(array_column($chartData, 'bulan')) !!}, labels: {!! json_encode(array_column($chartData, 'bulan')) !!},
datasets: [{ datasets: [{
label: 'Jumlah Diagnosa', label: 'Diagnosa',
data: {!! json_encode(array_column($chartData, 'total')) !!}, data: {!! json_encode(array_column($chartData, 'total')) !!},
borderColor: '#5FA357', borderColor: '#2d7a4f',
backgroundColor: 'rgba(95, 163, 87, 0.1)', backgroundColor: lineGrad,
borderWidth: 3, borderWidth: 2.5,
fill: true, fill: true,
tension: 0.4, tension: 0.42,
pointBackgroundColor: '#5FA357', pointBackgroundColor: '#fff',
pointBorderColor: '#2d7a4f',
pointBorderWidth: 2.5,
pointRadius: 5, pointRadius: 5,
pointHoverRadius: 7,
}] }]
}, },
options: { options: {
responsive: true, responsive: true,
maintainAspectRatio: false, maintainAspectRatio: false,
plugins: { legend: { display: false } }, plugins: {
legend: { display: false },
tooltip: {
backgroundColor: '#1a4d2e',
titleFont: { family: 'Plus Jakarta Sans', weight: '700', size: 12 },
bodyFont: { family: 'Plus Jakarta Sans', size: 12 },
padding: 12, cornerRadius: 10,
}
},
scales: { scales: {
y: { beginAtZero: true, ticks: { stepSize: 1 } } x: {
grid: { display: false },
ticks: { font: { family: 'Plus Jakarta Sans', size: 11 }, color: '#6b7f72' },
border: { display: false }
},
y: {
beginAtZero: true,
ticks: { stepSize: 1, font: { family: 'Plus Jakarta Sans', size: 11 }, color: '#6b7f72' },
grid: { color: 'rgba(0,0,0,.05)' },
border: { display: false }
}
} }
} }
}); });
// Pie Chart /* ── Doughnut Chart ── */
@if($statistikPenyakit->count() > 0) @if($statistikPenyakit->count() > 0)
const pieCtx = document.getElementById('pieChart').getContext('2d'); const pieCtx = document.getElementById('pieChart').getContext('2d');
new Chart(pieCtx, { new Chart(pieCtx, {
@ -214,27 +357,43 @@
labels: {!! json_encode($statistikPenyakit->map(fn($s) => $s->penyakit->nama_penyakit ?? $s->penyakit_final)) !!}, labels: {!! json_encode($statistikPenyakit->map(fn($s) => $s->penyakit->nama_penyakit ?? $s->penyakit_final)) !!},
datasets: [{ datasets: [{
data: {!! json_encode($statistikPenyakit->pluck('total')) !!}, data: {!! json_encode($statistikPenyakit->pluck('total')) !!},
backgroundColor: ['#5FA357', '#C1FA70', '#3B82F6', '#F59E0B', '#EF4444'], backgroundColor: ['#2d7a4f', '#4ade80', '#0d9488', '#f0b429', '#f87171'],
hoverBackgroundColor: ['#1a4d2e', '#22c55e', '#0f766e', '#d97706', '#ef4444'],
borderWidth: 0, borderWidth: 0,
hoverOffset: 8,
}] }]
}, },
options: { options: {
responsive: true, responsive: true,
maintainAspectRatio: false, maintainAspectRatio: false,
cutout: '70%',
plugins: { plugins: {
legend: { position: 'bottom', labels: { font: { size: 11 } } } legend: {
position: 'bottom',
labels: {
font: { family: 'Plus Jakarta Sans', size: 11, weight: '600' },
color: '#0f1f14',
padding: 14,
usePointStyle: true,
pointStyleWidth: 8,
}
},
tooltip: {
backgroundColor: '#1a4d2e',
titleFont: { family: 'Plus Jakarta Sans', weight: '700', size: 12 },
bodyFont: { family: 'Plus Jakarta Sans', size: 12 },
padding: 12, cornerRadius: 10,
}
} }
} }
}); });
@endif @endif
// Real time clock
/* ── Real-time clock ── */
function updateClock() { function updateClock() {
const now = new Date(); const now = new Date();
const options = { const opts = { weekday:'long', year:'numeric', month:'long', day:'numeric', hour:'2-digit', minute:'2-digit', second:'2-digit' };
weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', document.getElementById('realtime-clock').textContent = now.toLocaleDateString('id-ID', opts);
hour: '2-digit', minute: '2-digit', second: '2-digit'
};
document.getElementById('realtime-clock').textContent = now.toLocaleDateString('id-ID', options);
} }
updateClock(); updateClock();
setInterval(updateClock, 1000); setInterval(updateClock, 1000);

View File

@ -1,249 +1,428 @@
@extends('layouts.user-app') @extends('layouts.user-app')
@section('page-title', 'Hasil Diagnosa') @section('page-title', 'Hasil Diagnosa')
@section('page-subtitle', 'Hasil analisis penyakit tanaman kopi kamu')
@push('styles')
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
:root {
--green-deep: #1a4d2e;
--green-mid: #2d7a4f;
--green-bright:#4ade80;
--bg-base: #f0f5f1;
--bg-card: #ffffff;
--text-primary:#0f1f14;
--text-muted: #6b7f72;
--shadow: 0 4px 24px rgba(29,77,46,.08), 0 1px 4px rgba(29,77,46,.05);
--radius: 20px;
}
body, .hasil-root { font-family: 'Plus Jakarta Sans', sans-serif; background: var(--bg-base); }
@keyframes fadeUp {
from { opacity:0; transform:translateY(14px); }
to { opacity:1; transform:translateY(0); }
}
.a1 { animation: fadeUp .5s cubic-bezier(.22,1,.36,1) .04s both; }
.a2 { animation: fadeUp .5s cubic-bezier(.22,1,.36,1) .12s both; }
.a3 { animation: fadeUp .5s cubic-bezier(.22,1,.36,1) .20s both; }
.a4 { animation: fadeUp .5s cubic-bezier(.22,1,.36,1) .28s both; }
/* ─── Page header ─── */
.page-hdr {
display:flex; align-items:center; justify-content:space-between;
margin-bottom:1.5rem; flex-wrap:wrap; gap:.75rem;
}
.page-hdr-title { font-size:1.5rem; font-weight:800; color:var(--text-primary); letter-spacing:-.03em; }
.btn-dl {
display:inline-flex; align-items:center; gap:.5rem;
padding:.55rem 1.2rem;
background:rgba(255,255,255,.15); border:1.5px solid rgba(255,255,255,.35);
color:#fff; font-size:.8rem; font-weight:700;
border-radius:50px; text-decoration:none;
transition:all .2s;
}
.btn-dl:hover { background:rgba(255,255,255,.25); border-color:rgba(255,255,255,.6); transform:translateY(-1px); }
/* ─── Disease banner ─── */
.banner {
background: linear-gradient(130deg, #1a4d2e 0%, #2d7a4f 58%, #38a169 100%);
border-radius: var(--radius); padding:1.75rem 2rem;
color:#fff; position:relative; overflow:hidden;
margin-bottom:1.25rem;
box-shadow:0 8px 32px rgba(26,77,46,.28);
}
.banner::before {
content:''; position:absolute; inset:0;
background-image:
linear-gradient(rgba(255,255,255,.04) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,255,255,.04) 1px, transparent 1px);
background-size:28px 28px; pointer-events:none;
}
.banner::after {
content:''; position:absolute; top:-80px; right:-60px;
width:240px; height:240px; border-radius:50%;
background:radial-gradient(circle, rgba(74,222,128,.18) 0%, transparent 70%);
pointer-events:none;
}
.banner-in { position:relative; z-index:1; }
.banner-toprow { display:flex; align-items:flex-start; justify-content:space-between; gap:1rem; flex-wrap:wrap; margin-bottom:.9rem; }
.pill {
display:inline-flex; align-items:center; gap:.35rem;
padding:.28rem .85rem; border-radius:50px;
font-size:.68rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
}
.pill-detected { background:rgba(255,255,255,.15); border:1px solid rgba(255,255,255,.25); color:#fff; }
.pill-danger-st { background:#dc2626; color:#fff; }
.pill-danger-t { background:#f97316; color:#fff; }
.pill-danger-s { background:#fde047; color:#713f12; }
.pill-danger-r { background:#bbf7d0; color:#14532d; }
.disease-name { font-size:1.6rem; font-weight:800; letter-spacing:-.03em; line-height:1.2; }
.disease-latin { font-style:italic; font-size:.8rem; color:rgba(255,255,255,.6); margin-top:.25rem; }
.date-meta { text-align:right; font-size:.72rem; color:rgba(255,255,255,.5); font-family:'DM Mono',monospace; flex-shrink:0; }
.date-meta small { display:block; font-size:.62rem; color:rgba(255,255,255,.3); margin-top:.35rem; }
.cf-box { background:rgba(0,0,0,.18); border-radius:14px; padding:.95rem 1.2rem; margin-top:.75rem; }
.cf-row { display:flex; align-items:center; justify-content:space-between; margin-bottom:.55rem; }
.cf-lbl { font-size:.76rem; font-weight:600; color:rgba(255,255,255,.8); }
.cf-val { font-size:2rem; font-weight:800; letter-spacing:-.04em; }
.cf-track { background:rgba(0,0,0,.25); border-radius:999px; height:10px; }
.cf-fill { background:#fff; border-radius:999px; height:10px; }
.cf-ticks { display:flex; justify-content:space-between; font-size:.63rem; color:rgba(255,255,255,.4); margin-top:.3rem; }
/* ─── Two-column layout ─── */
/* Wireframe: left = narrow (label column), right = wide (content) */
.main-grid {
display:grid;
grid-template-columns: 220px 1fr;
gap:1.25rem;
align-items:start;
}
@media (max-width:900px) { .main-grid { grid-template-columns:1fr; } }
/* ─── Card ─── */
.card {
background:var(--bg-card); border-radius:var(--radius);
border:1.5px solid rgba(29,77,46,.07);
box-shadow:var(--shadow); overflow:hidden;
transition:transform .2s, box-shadow .2s;
}
.card:hover { transform:translateY(-2px); box-shadow:0 8px 28px rgba(29,77,46,.12); }
.card-hdr {
display:flex; align-items:center; gap:.6rem;
padding:.9rem 1.2rem;
border-bottom:1px solid rgba(29,77,46,.07);
}
.card-hdr-icon {
width:30px; height:30px; border-radius:8px; flex-shrink:0;
display:flex; align-items:center; justify-content:center;
}
.card-hdr-title { font-size:.85rem; font-weight:700; color:var(--text-primary); letter-spacing:-.01em; }
.card-body { padding:1.1rem 1.2rem; }
/* ─── Info table rows ─── */
.info-row { display:flex; justify-content:space-between; align-items:center; padding:.55rem 0; border-bottom:1px solid rgba(29,77,46,.06); font-size:.78rem; }
.info-row:last-child { border-bottom:none; }
.info-k { color:var(--text-muted); font-weight:500; }
.info-v { font-weight:700; color:var(--text-primary); }
.info-v.green { color:#16a34a; }
.info-v.blue { color:#2563eb; }
/* ─── Gejala ─── */
.gejala-item {
display:flex; align-items:flex-start; gap:.45rem;
padding:.45rem .6rem; background:#f0fdf4;
border-radius:8px; font-size:.76rem; color:#166534;
font-weight:500; margin-bottom:.38rem;
}
.gejala-item svg { flex-shrink:0; margin-top:1px; }
/* ─── Desc ─── */
.desc-box { background:#f9fafb; border-radius:12px; padding:.9rem 1rem; font-size:.8rem; color:#4b5563; line-height:1.65; }
/* ─── Pengendalian ─── */
.ctrl-grid { display:grid; grid-template-columns:1fr 1fr; gap:.65rem; }
@media (max-width:600px) { .ctrl-grid { grid-template-columns:1fr; } }
.ctrl-card { border-radius:13px; padding:.9rem; font-size:.76rem; line-height:1.6; border:1.5px solid transparent; }
.ctrl-lbl { display:flex; align-items:center; gap:.4rem; font-size:.73rem; font-weight:700; margin-bottom:.45rem; }
.ctrl-lbl-icon { width:24px; height:24px; border-radius:6px; display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.ctrl-pencegahan { background:#eff6ff; border-color:#dbeafe; color:#1e40af; }
.ctrl-pencegahan .ctrl-lbl { color:#1e40af; } .ctrl-pencegahan .ctrl-lbl-icon { background:#dbeafe; }
.ctrl-kimia { background:#fff7ed; border-color:#fed7aa; color:#c2410c; }
.ctrl-kimia .ctrl-lbl { color:#c2410c; } .ctrl-kimia .ctrl-lbl-icon { background:#fed7aa; }
.ctrl-organik { background:#f0fdf4; border-color:#bbf7d0; color:#15803d; }
.ctrl-organik .ctrl-lbl { color:#15803d; } .ctrl-organik .ctrl-lbl-icon { background:#bbf7d0; }
.ctrl-budidaya { background:#fefce8; border-color:#fde68a; color:#a16207; }
.ctrl-budidaya .ctrl-lbl { color:#a16207; } .ctrl-budidaya .ctrl-lbl-icon { background:#fde68a; }
/* ─── Kemungkinan ─── */
.kemung-item { display:flex; align-items:center; gap:.7rem; padding:.7rem; border-radius:12px; margin-bottom:.45rem; }
.kemung-item.r1 { background:#f0fdf4; border:1.5px solid #bbf7d0; }
.kemung-item.rother{ background:#f9fafb; border:1px solid #f3f4f6; }
.rank-circle { width:26px; height:26px; border-radius:50%; font-size:.72rem; font-weight:800; display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.rc-1 { background:#16a34a; color:#fff; }
.rc-other{ background:#e5e7eb; color:#6b7280; }
.bar-track { flex:1; background:#e5e7eb; border-radius:999px; height:6px; }
.bar-fill { border-radius:999px; height:6px; }
/* ─── Action buttons ─── */
.btn-main {
display:flex; align-items:center; justify-content:center; gap:.5rem;
padding:.7rem 1rem; background:linear-gradient(135deg, #2d7a4f, #16a34a);
color:#fff; font-weight:700; font-size:.82rem; border-radius:13px;
text-decoration:none; width:100%;
box-shadow:0 4px 14px rgba(22,163,74,.3); transition:all .2s;
}
.btn-main:hover { transform:translateY(-2px); box-shadow:0 6px 20px rgba(22,163,74,.4); }
.btn-sec {
display:flex; align-items:center; justify-content:center; gap:.5rem;
padding:.7rem 1rem; background:var(--bg-card); color:var(--text-primary);
font-weight:600; font-size:.82rem; border-radius:13px;
text-decoration:none; width:100%; border:1.5px solid rgba(29,77,46,.15); transition:all .2s;
}
.btn-sec:hover { background:#f0fdf4; transform:translateY(-1px); }
/* ─── Relasi table ─── */
.relasi-wrap { overflow-x:auto; }
.relasi-table { width:100%; border-collapse:collapse; font-size:.76rem; }
.relasi-table th { padding:.6rem .8rem; text-align:left; font-weight:700; font-size:.67rem; text-transform:uppercase; letter-spacing:.06em; color:var(--text-muted); background:#f9fafb; border-bottom:1px solid #e5e7eb; }
.relasi-table th:not(:first-child) { text-align:center; }
.relasi-table td { padding:.55rem .8rem; border-bottom:1px solid #f3f4f6; color:#374151; }
.relasi-table td:not(:first-child) { text-align:center; }
.relasi-table tr:last-child td { border-bottom:none; }
.relasi-table tr:hover td { background:#f9fafb; }
.chk-yes { display:inline-flex; align-items:center; justify-content:center; width:24px; height:24px; background:#dcfce7; border-radius:50%; }
.chk-no { display:inline-flex; align-items:center; justify-content:center; width:24px; height:24px; background:#f3f4f6; border-radius:50%; }
.col-stack { display:flex; flex-direction:column; gap:1.25rem; }
</style>
@endpush
@section('content') @section('content')
<div class="hasil-root">
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6"> {{-- Disease banner --}}
<div class="banner a1">
<!-- Kolom Kiri --> <div class="banner-in">
<div class="lg:col-span-2 space-y-6"> <div class="banner-toprow">
<div>
<div class="bg-white rounded-2xl shadow-lg overflow-hidden"> <div style="display:flex;gap:.45rem;flex-wrap:wrap;margin-bottom:.7rem;">
<!-- Header --> <span class="pill pill-detected">
<div style="background: linear-gradient(135deg, #16a34a, #4ade80);" class="p-6 text-white"> <svg width="10" height="10" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
<div class="flex flex-wrap items-center justify-between gap-2 mb-3">
<div class="flex flex-wrap items-center gap-2">
<span class="px-3 py-1 text-xs font-bold uppercase tracking-wider rounded-full" style="background:rgba(0,0,0,0.2);">
Penyakit Terdeteksi Penyakit Terdeteksi
</span> </span>
@if($riwayat->penyakit?->tingkat_bahaya) @if($riwayat->penyakit?->tingkat_bahaya)
<span class="px-3 py-1 text-xs font-bold rounded-full @php
{{ $riwayat->penyakit->tingkat_bahaya === 'Sangat Tinggi' ? 'bg-red-600 text-white' : $pc = match($riwayat->penyakit->tingkat_bahaya) {
($riwayat->penyakit->tingkat_bahaya === 'Tinggi' ? 'bg-orange-500 text-white' : 'Sangat Tinggi' => 'pill-danger-st',
($riwayat->penyakit->tingkat_bahaya === 'Sedang' ? 'bg-yellow-400 text-yellow-900' : 'bg-green-200 text-green-900')) }}"> 'Tinggi' => 'pill-danger-t',
⚠️ {{ $riwayat->penyakit->tingkat_bahaya }} 'Sedang' => 'pill-danger-s',
default => 'pill-danger-r',
};
@endphp
<span class="pill {{ $pc }}">
<svg width="10" height="10" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg>
{{ $riwayat->penyakit->tingkat_bahaya }}
</span> </span>
@endif @endif
</div> </div>
<div style="display:flex;align-items:flex-end;justify-content:space-between;gap:1rem;flex-wrap:wrap;">
<div>
<div class="disease-name">{{ $riwayat->penyakit->nama_penyakit ?? 'Tidak Teridentifikasi' }}</div>
@if($riwayat->penyakit?->nama_latin)
<div class="disease-latin">{{ $riwayat->penyakit->nama_latin }}</div>
@endif
</div>
<a href="{{ route('user.riwayat.pdf', $riwayat->id_diagnosis) }}" target="_blank" class="btn-dl" style="flex-shrink:0;">
<svg width="14" height="14" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.2">
<path stroke-linecap="round" stroke-linejoin="round" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"/>
</svg>
Download PDF
</a>
</div>
</div>
<div class="date-meta">
<div>{{ $riwayat->tanggal->format('d M Y') }}</div>
<div>{{ $riwayat->tanggal->format('H:i') }} WIB</div>
<small>ID: {{ $riwayat->id_diagnosis }}</small>
</div>
</div>
<div class="cf-box">
<div class="cf-row">
<span class="cf-lbl">Tingkat Kepercayaan (Certainty Factor)</span>
<span class="cf-val">{{ round($riwayat->cf_tertinggi * 100, 1) }}%</span>
</div>
<div class="cf-track">
<div class="cf-fill" style="width:{{ round($riwayat->cf_tertinggi * 100, 1) }}%;"></div>
</div>
<div class="cf-ticks"><span>0%</span><span>50%</span><span>100%</span></div>
</div>
</div>
</div>
{{-- Tombol Download PDF --}} {{-- Main two-column grid --}}
<a href="{{ route('user.riwayat.pdf', $riwayat->id_diagnosis) }}" {{-- LEFT = info & aksi (narrow) | RIGHT = konten detail (wide) --}}
target="_blank" <div class="main-grid a2">
class="flex items-center gap-2 px-4 py-2 rounded-xl text-sm font-semibold transition-all duration-200 hover:scale-105 active:scale-95"
style="background:rgba(0,0,0,0.2); color:white; border: 1px solid rgba(255,255,255,0.3); backdrop-filter: blur(4px);" {{-- ── LEFT COLUMN ── --}}
onmouseover="this.style.background='rgba(0,0,0,0.35)'" <div class="col-stack">
onmouseout="this.style.background='rgba(0,0,0,0.2)'">
<svg xmlns="http://www.w3.org/2000/svg" class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"> {{-- Aksi --}}
<path stroke-linecap="round" stroke-linejoin="round" d="M12 10v6m0 0l-3-3m3 3l3-3M3 17V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z" /> <div class="card">
</svg> <div class="card-body" style="display:flex;flex-direction:column;gap:.65rem;">
Download PDF <a href="{{ route('user.diagnosa.index') }}" class="btn-main">
<svg width="14" height="14" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.2"><path stroke-linecap="round" stroke-linejoin="round" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/></svg>
Diagnosa Ulang
</a>
<a href="{{ route('user.diagnosa.riwayat') }}" class="btn-sec">
<svg width="14" height="14" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.2"><path stroke-linecap="round" stroke-linejoin="round" d="M10 19l-7-7m0 0l7-7m-7 7h18"/></svg>
Kembali ke Riwayat
</a> </a>
</div> </div>
<h1 class="text-2xl font-bold mb-1">{{ $riwayat->penyakit->nama_penyakit ?? 'Tidak Teridentifikasi' }}</h1>
@if($riwayat->penyakit?->nama_latin)
<p class="italic text-sm mb-4" style="color:rgba(255,255,255,0.8);">{{ $riwayat->penyakit->nama_latin }}</p>
@endif
<!-- CF Progress -->
<div class="rounded-xl p-4" style="background:rgba(0,0,0,0.15);">
<div class="flex justify-between items-center mb-3">
<span class="text-sm font-semibold" style="color:rgba(255,255,255,0.9);">Tingkat Kepercayaan</span>
<span class="text-3xl font-bold text-white">{{ round($riwayat->cf_tertinggi * 100, 1) }}%</span>
</div>
<div class="w-full rounded-full h-4" style="background:rgba(0,0,0,0.25);">
<div class="h-4 rounded-full bg-white" style="width: {{ round($riwayat->cf_tertinggi * 100, 1) }}%;"></div>
</div>
<div class="flex justify-between text-xs mt-1" style="color:rgba(255,255,255,0.6);">
<span>0%</span><span>50%</span><span>100%</span>
</div>
</div>
</div> </div>
<!-- Body -->
<div class="p-6">
@if($riwayat->penyakit?->deskripsi_singkat)
<div class="mb-6">
<h4 class="font-bold text-gray-800 mb-2 flex items-center">
<span class="w-8 h-8 bg-blue-100 rounded-lg flex items-center justify-center mr-2 text-sm">📝</span>
Deskripsi Penyakit
</h4>
<p class="text-sm text-gray-600 leading-relaxed bg-gray-50 rounded-xl p-4">{{ $riwayat->penyakit->deskripsi_singkat }}</p>
</div>
@endif
<h4 class="font-bold text-gray-800 mb-3 flex items-center">
<span class="w-8 h-8 bg-green-100 rounded-lg flex items-center justify-center mr-2 text-sm">💊</span>
Cara Pengendalian
</h4>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
@if($riwayat->penyakit?->pengendalian_pencegahan)
<div class="bg-blue-50 border border-blue-100 rounded-xl p-4 hover:shadow-md transition">
<div class="flex items-center mb-2"><span class="text-lg mr-2">🛡️</span><h5 class="font-bold text-blue-700 text-sm">Pencegahan</h5></div>
<p class="text-xs text-blue-600 leading-relaxed">{{ $riwayat->penyakit->pengendalian_pencegahan }}</p>
</div>
@endif
@if($riwayat->penyakit?->pengendalian_kimia)
<div class="bg-orange-50 border border-orange-100 rounded-xl p-4 hover:shadow-md transition">
<div class="flex items-center mb-2"><span class="text-lg mr-2">⚗️</span><h5 class="font-bold text-orange-700 text-sm">Pengendalian Kimia</h5></div>
<p class="text-xs text-orange-600 leading-relaxed">{{ $riwayat->penyakit->pengendalian_kimia }}</p>
</div>
@endif
@if($riwayat->penyakit?->pengendalian_organik)
<div class="bg-green-50 border border-green-100 rounded-xl p-4 hover:shadow-md transition">
<div class="flex items-center mb-2"><span class="text-lg mr-2">🌿</span><h5 class="font-bold text-green-700 text-sm">Pengendalian Organik</h5></div>
<p class="text-xs text-green-600 leading-relaxed">{{ $riwayat->penyakit->pengendalian_organik }}</p>
</div>
@endif
@if($riwayat->penyakit?->pengendalian_budidaya)
<div class="bg-yellow-50 border border-yellow-100 rounded-xl p-4 hover:shadow-md transition">
<div class="flex items-center mb-2"><span class="text-lg mr-2">🌱</span><h5 class="font-bold text-yellow-700 text-sm">Pengendalian Budidaya</h5></div>
<p class="text-xs text-yellow-600 leading-relaxed">{{ $riwayat->penyakit->pengendalian_budidaya }}</p>
</div>
@endif
</div>
</div>
</div> </div>
<!-- Semua Kemungkinan --> {{-- ── RIGHT COLUMN (Solusi / Detail) ── --}}
@if($riwayat->hasil_diagnosa && count($riwayat->hasil_diagnosa) > 1) <div class="col-stack a3">
<div class="bg-white rounded-2xl shadow-lg p-6">
<h3 class="text-lg font-bold text-gray-800 mb-4 flex items-center"> {{-- Cara Pengendalian (Solusi) --}}
<span class="w-8 h-8 bg-purple-100 rounded-lg flex items-center justify-center mr-2 text-sm">📊</span> @if($riwayat->penyakit?->pengendalian_pencegahan || $riwayat->penyakit?->pengendalian_kimia || $riwayat->penyakit?->pengendalian_organik || $riwayat->penyakit?->pengendalian_budidaya)
Semua Kemungkinan Penyakit <div class="card">
</h3> <div class="card-hdr">
<div class="space-y-3"> <div class="card-hdr-icon" style="background:#dcfce7;">
@foreach($riwayat->hasil_diagnosa as $index => $hasil) <svg width="15" height="15" fill="none" stroke="#16a34a" viewBox="0 0 24 24" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/></svg>
<div class="flex items-center gap-3 p-3 rounded-xl {{ $index === 0 ? 'bg-green-50 border-2 border-green-200' : 'bg-gray-50 border border-gray-100' }}"> </div>
<span class="w-7 h-7 rounded-full {{ $index === 0 ? 'bg-green-500' : 'bg-gray-300' }} text-white text-xs flex items-center justify-center font-bold flex-shrink-0">{{ $index + 1 }}</span> <span class="card-hdr-title">Solusi &amp; Cara Pengendalian</span>
<span class="text-sm font-semibold {{ $index === 0 ? 'text-green-800' : 'text-gray-600' }} flex-1 min-w-0 truncate"> </div>
{{ $hasil['nama_penyakit'] }} <div class="card-body">
@if($index === 0)<span class="ml-2 px-2 py-0.5 bg-green-500 text-white text-xs rounded-full">Terpilih</span>@endif <div class="ctrl-grid">
</span> @if($riwayat->penyakit?->pengendalian_pencegahan)
<div class="flex items-center gap-2 flex-shrink-0"> <div class="ctrl-card ctrl-pencegahan">
<div class="w-24 bg-gray-200 rounded-full h-2"> <div class="ctrl-lbl">
<div class="{{ $index === 0 ? 'bg-green-500' : 'bg-gray-400' }} h-2 rounded-full" style="width: {{ $hasil['persentase'] }}%"></div> <div class="ctrl-lbl-icon">
<svg width="12" height="12" fill="none" stroke="#1d4ed8" viewBox="0 0 24 24" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/></svg>
</div>
Pencegahan
</div>
{{ $riwayat->penyakit->pengendalian_pencegahan }}
</div> </div>
<span class="text-sm font-bold {{ $index === 0 ? 'text-green-700' : 'text-gray-500' }} w-10 text-right">{{ $hasil['persentase'] }}%</span> @endif
</div> @if($riwayat->penyakit?->pengendalian_kimia)
<div class="ctrl-card ctrl-kimia">
<div class="ctrl-lbl">
<div class="ctrl-lbl-icon">
<svg width="12" height="12" fill="none" stroke="#c2410c" viewBox="0 0 24 24" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z"/></svg>
</div>
Pengendalian Kimia
</div>
{{ $riwayat->penyakit->pengendalian_kimia }}
</div>
@endif
@if($riwayat->penyakit?->pengendalian_organik)
<div class="ctrl-card ctrl-organik">
<div class="ctrl-lbl">
<div class="ctrl-lbl-icon">
<svg width="12" height="12" fill="none" stroke="#15803d" viewBox="0 0 24 24" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M5 3v4M3 5h4M6 17v4m-2-2h4m5-16l2.286 6.857L21 12l-5.714 2.143L13 21l-2.286-6.857L5 12l5.714-2.143L13 3z"/></svg>
</div>
Pengendalian Organik
</div>
{{ $riwayat->penyakit->pengendalian_organik }}
</div>
@endif
@if($riwayat->penyakit?->pengendalian_budidaya)
<div class="ctrl-card ctrl-budidaya">
<div class="ctrl-lbl">
<div class="ctrl-lbl-icon">
<svg width="12" height="12" fill="none" stroke="#a16207" viewBox="0 0 24 24" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
</div>
Pengendalian Budidaya
</div>
{{ $riwayat->penyakit->pengendalian_budidaya }}
</div>
@endif
</div> </div>
@endforeach
</div>
</div>
@endif
</div>
<!-- Tabel Relasi Gejala per Penyakit -->
@if($relasiGejala->count() > 0)
<div class="bg-white rounded-2xl shadow-lg p-6">
<h3 class="text-lg 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>
Relasi Gejala & Penyakit
</h3>
<div class="overflow-x-auto rounded-xl border border-gray-200">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th class="px-4 py-3 text-left text-xs font-bold text-gray-600 uppercase">Gejala</th>
@foreach($riwayat->hasil_diagnosa as $hasil)
<th class="px-4 py-3 text-center text-xs font-bold text-gray-600 uppercase">
{{ $hasil['nama_penyakit'] }}
<div class="text-green-600 font-bold normal-case">{{ $hasil['persentase'] }}%</div>
</th>
@endforeach
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
@foreach($gejalaInput as $gejala)
<tr class="hover:bg-gray-50">
<td class="px-4 py-3 text-xs text-gray-700 font-medium max-w-xs">{{ $gejala->nama_gejala }}</td>
@foreach($riwayat->hasil_diagnosa as $hasil)
<td class="px-4 py-3 text-center">
@if(isset($relasiGejala[$hasil['id_penyakit']]) &&
$relasiGejala[$hasil['id_penyakit']]->contains('id_gejala', $gejala->id_gejala))
<span class="inline-flex items-center justify-center w-7 h-7 bg-green-100 rounded-full">
<svg class="w-4 h-4 text-green-600" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
</svg>
</span>
@else
<span class="inline-flex items-center justify-center w-7 h-7 bg-gray-100 rounded-full">
<svg class="w-4 h-4 text-gray-300" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"/>
</svg>
</span>
@endif
</td>
@endforeach
</tr>
@endforeach
</tbody>
</table>
</div>
<p class="text-xs text-gray-400 mt-3"> = gejala terkait penyakit tersebut &nbsp;|&nbsp; = tidak terkait</p>
</div>
@endif
<!-- Kolom Kanan -->
<div class="space-y-6">
<!-- Info Diagnosa -->
<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>
Info Diagnosa
</h3>
<div class="space-y-2">
<div class="flex justify-between items-center 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">{{ $riwayat->tanggal->format('d M Y') }}</span>
</div>
<div class="flex justify-between items-center py-2 border-b border-gray-100">
<span class="text-xs text-gray-500">Waktu</span>
<span class="text-xs font-semibold text-gray-800">{{ $riwayat->tanggal->format('H:i') }} WIB</span>
</div>
<div class="flex justify-between items-center py-2 border-b border-gray-100">
<span class="text-xs text-gray-500">Jumlah Gejala</span>
<span class="text-xs font-bold text-blue-600">{{ count($riwayat->gejala_input) }} gejala</span>
</div>
<div class="flex justify-between items-center py-2">
<span class="text-xs text-gray-500">CF Tertinggi</span>
<span class="text-xs font-bold text-green-600">{{ round($riwayat->cf_tertinggi * 100, 1) }}%</span>
</div>
</div>
</div>
<!-- Gejala -->
<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>
Gejala Dipilih
</h3>
<div class="space-y-2 max-h-64 overflow-y-auto">
@foreach($gejalaInput as $gejala)
<div class="flex items-start space-x-2 p-2 bg-green-50 rounded-lg">
<svg class="w-4 h-4 text-green-500 flex-shrink-0 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
</svg>
<span class="text-xs text-gray-700 leading-relaxed">{{ $gejala->nama_gejala }}</span>
</div> </div>
@endforeach </div>
</div> @endif
</div>
{{-- Semua kemungkinan --}}
@if($riwayat->hasil_diagnosa && count($riwayat->hasil_diagnosa) > 1)
<div class="card">
<div class="card-hdr">
<div class="card-hdr-icon" style="background:#ede9fe;">
<svg width="15" height="15" fill="none" stroke="#7c3aed" viewBox="0 0 24 24" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/></svg>
</div>
<span class="card-hdr-title">Semua Kemungkinan Penyakit</span>
</div>
<div class="card-body">
@foreach($riwayat->hasil_diagnosa as $i => $hasil)
<div class="kemung-item {{ $i === 0 ? 'r1' : 'rother' }}">
<span class="rank-circle {{ $i === 0 ? 'rc-1' : 'rc-other' }}">{{ $i+1 }}</span>
<span style="flex:1;font-size:.8rem;font-weight:{{ $i===0?'700':'500' }};color:{{ $i===0?'#166534':'#374151' }};overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">
{{ $hasil['nama_penyakit'] }}
</span>
<div class="bar-track" style="max-width:90px;">
<div class="bar-fill" style="width:{{ $hasil['persentase'] }}%;background:{{ $i===0?'#16a34a':'#d1d5db' }};"></div>
</div>
<span style="font-size:.8rem;font-weight:800;color:{{ $i===0?'#16a34a':'#9ca3af' }};width:36px;text-align:right;flex-shrink:0;">{{ $hasil['persentase'] }}%</span>
</div>
@endforeach
</div>
</div>
@endif
{{-- Relasi gejala --}}
@if($relasiGejala->count() > 0)
<div class="card a4">
<div class="card-hdr">
<div class="card-hdr-icon" style="background:#dbeafe;">
<svg width="15" height="15" fill="none" stroke="#1d4ed8" viewBox="0 0 24 24" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M7 20l4-16m2 16l4-16M6 9h14M4 15h14"/></svg>
</div>
<span class="card-hdr-title">Relasi Gejala &amp; Penyakit</span>
</div>
<div class="relasi-wrap">
<table class="relasi-table">
<thead>
<tr>
<th style="padding-left:1.2rem;">Gejala</th>
@foreach($riwayat->hasil_diagnosa as $hasil)
<th>{{ $hasil['nama_penyakit'] }}<br><span style="color:#16a34a;text-transform:none;letter-spacing:0;font-weight:700;">{{ $hasil['persentase'] }}%</span></th>
@endforeach
</tr>
</thead>
<tbody>
@foreach($gejalaInput as $gejala)
<tr>
<td style="padding-left:1.2rem;font-weight:500;">{{ $gejala->nama_gejala }}</td>
@foreach($riwayat->hasil_diagnosa as $hasil)
<td>
@if(isset($relasiGejala[$hasil['id_penyakit']]) && $relasiGejala[$hasil['id_penyakit']]->contains('id_gejala', $gejala->id_gejala))
<span class="chk-yes">
<svg width="11" height="11" fill="none" stroke="#16a34a" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg>
</span>
@else
<span class="chk-no">
<svg width="10" height="10" fill="none" stroke="#d1d5db" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/></svg>
</span>
@endif
</td>
@endforeach
</tr>
@endforeach
</tbody>
</table>
<p style="font-size:.68rem;color:#9ca3af;padding:.65rem 1.2rem;border-top:1px solid #f3f4f6;">
Centang = gejala terkait &nbsp;|&nbsp; Silang = tidak terkait
</p>
</div>
</div>
@endif
<!-- Aksi -->
<div class="bg-white rounded-2xl shadow-lg p-6 space-y-3">
<a href="{{ route('user.diagnosa.index') }}" class="w-full flex items-center justify-center gap-2 px-4 py-3 bg-gradient-to-r from-green-500 to-green-600 text-white font-bold rounded-xl hover:from-green-600 hover:to-green-700 transition shadow text-sm">
Diagnosa Ulang
</a>
<a href="{{ route('user.diagnosa.riwayat') }}" 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 Riwayat
</a>
</div> </div>
</div> </div>
</div>
</div>
@endsection @endsection

View File

@ -6,101 +6,114 @@
@section('content') @section('content')
@if(session('error')) @if(session('error'))
<div class="mb-6 bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded-lg flex items-center"> <div class="mb-6 bg-red-50 border border-red-200 text-red-700 p-4 rounded-2xl flex items-center gap-3">
<svg class="w-6 h-6 mr-3" fill="currentColor" viewBox="0 0 20 20"> <svg class="w-5 h-5 shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/> <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/>
</svg> </svg>
<span class="font-semibold">{{ session('error') }}</span> <span class="font-semibold text-sm">{{ session('error') }}</span>
</div> </div>
@endif @endif
<form action="{{ route('user.diagnosa.proses') }}" method="POST" id="form-diagnosa"> <form action="{{ route('user.diagnosa.proses') }}" method="POST" id="form-diagnosa">
@csrf @csrf
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6"> <div class="bg-white rounded-2xl shadow-sm border border-gray-100 overflow-hidden">
<!-- Daftar Gejala --> <!-- Header Bar -->
<div class="lg:col-span-2"> <div class="px-6 py-4 border-b border-gray-100" style="display:flex; align-items:center; justify-content:space-between; gap:1rem;">
<div class="bg-white rounded-2xl shadow-lg p-6"> <div style="display:flex; align-items:center; gap:0.75rem;">
<div class="mb-6"> <div class="bg-green-100 rounded-xl p-2">
<div class="flex items-center mb-4"> <svg class="w-5 h-5 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<div class="bg-gradient-to-r from-green-500 to-green-600 rounded-xl p-3 mr-4"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"/>
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> </svg>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path>
</svg>
</div>
<div>
<h3 class="text-lg font-bold text-gray-800">Pilih Gejala</h3>
<p class="text-sm text-gray-500">Centang gejala yang sesuai dengan kondisi tanaman</p>
</div>
</div>
<!-- Search -->
<input type="text" id="search-gejala" placeholder="🔍 Cari gejala yang dialami tanaman kopi kamu..."
class="w-full px-4 py-3 border border-gray-300 rounded-xl text-sm focus:ring-2 focus:ring-green-500 focus:border-transparent">
</div> </div>
<div>
<!-- Gejala List --> <div class="text-base font-bold text-gray-800">Daftar Gejala</div>
<div class="space-y-3 max-h-[500px] overflow-y-auto pr-2" id="gejala-list"> <div class="text-xs text-gray-400">Centang semua gejala yang sesuai kondisi tanaman</div>
@foreach($gejalas as $index => $gejala)
<label for="gejala_{{ $gejala->id_gejala }}"
class="gejala-item flex items-center p-4 border-2 border-gray-200 rounded-xl cursor-pointer hover:border-green-400 hover:bg-green-50 transition-all group"
data-nama="{{ strtolower($gejala->nama_gejala) }}">
<input type="checkbox" name="gejala[]" value="{{ $gejala->id_gejala }}"
id="gejala_{{ $gejala->id_gejala }}"
class="gejala-checkbox w-5 h-5 text-green-600 rounded focus:ring-green-500 mr-4"
onchange="updateSelected()">
<div class="flex-1">
<span class="text-sm font-semibold text-gray-700 group-hover:text-green-700">
{{ $gejala->nama_gejala }}
</span>
</div>
<div class="w-6 h-6 rounded-full border-2 border-gray-300 group-hover:border-green-400 flex items-center justify-center checkmark hidden">
<svg class="w-4 h-4 text-green-600" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
</svg>
</div>
</label>
@endforeach
</div> </div>
</div>
@error('gejala') <div style="display:flex; align-items:center; gap:0.5rem; background:#f0fdf4; border:1px solid #bbf7d0; border-radius:0.75rem; padding:0.4rem 0.9rem; white-space:nowrap;">
<p class="text-red-500 text-sm mt-3">{{ $message }}</p> <svg class="w-4 h-4 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@enderror <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
</svg>
<span id="selected-count" class="text-sm font-bold text-green-700">0</span>
<span class="text-xs text-green-600">terpilih</span>
</div> </div>
</div> </div>
<!-- Panel Kanan --> <!-- Search -->
<div class="space-y-6"> <div class="px-6 py-4 border-b border-gray-100">
<div style="position:relative;">
<svg style="position:absolute; left:0.875rem; top:50%; transform:translateY(-50%); width:1rem; height:1rem; color:#9ca3af;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0"/>
</svg>
<input type="text" id="search-gejala"
placeholder="Cari gejala yang dialami tanaman kopi..."
class="w-full py-2.5 bg-gray-50 border border-gray-200 rounded-xl text-sm text-gray-700 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-green-400 focus:border-transparent"
style="padding-left:2.5rem; padding-right:1rem;">
</div>
</div>
<!-- Gejala Terpilih --> <!-- Gejala List -->
<div class="bg-white rounded-2xl shadow-lg p-6 sticky top-28"> <div class="p-6">
<h3 class="text-lg font-bold text-gray-800 mb-4">Gejala Terpilih</h3> <div id="gejala-list" style="display:flex; flex-direction:column; gap:0.5rem; max-height:520px; overflow-y:auto; padding-right:0.25rem;">
@foreach($gejalas as $gejala)
<label for="gejala_{{ $gejala->id_gejala }}"
class="gejala-item"
data-nama="{{ strtolower($gejala->nama_gejala) }}"
style="display:flex; align-items:center; gap:0.75rem; padding:0.875rem 1rem; border:2px solid #e5e7eb; border-radius:0.75rem; cursor:pointer; transition:all 0.15s;">
<div id="selected-count" class="text-3xl font-bold text-green-600 mb-1">0</div> <input type="checkbox" name="gejala[]" value="{{ $gejala->id_gejala }}"
<p class="text-sm text-gray-500 mb-4">gejala dipilih</p> id="gejala_{{ $gejala->id_gejala }}"
class="gejala-checkbox"
style="width:1rem; height:1rem; accent-color:#16a34a; flex-shrink:0;"
onchange="updateSelected()">
<div id="selected-list" class="space-y-2 max-h-64 overflow-y-auto mb-6"> <span class="gejala-label" style="font-size:0.875rem; font-weight:500; color:#374151; line-height:1.4;">
<p class="text-sm text-gray-400 italic" id="empty-msg">Belum ada gejala dipilih</p> {{ $gejala->nama_gejala }}
</div> </span>
</label>
@endforeach
</div>
@error('gejala')
<p style="color:#ef4444; font-size:0.875rem; margin-top:0.75rem; display:flex; align-items:center; gap:0.375rem;">
<svg style="width:1rem; height:1rem; flex-shrink:0;" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"/>
</svg>
{{ $message }}
</p>
@enderror
</div>
<!-- Footer Action Bar -->
<div style="padding:1rem 1.5rem; background:#f9fafb; border-top:1px solid #f3f4f6; display:flex; align-items:center; justify-content:space-between; gap:0.75rem; flex-wrap:wrap;">
<div style="display:flex; align-items:center; gap:0.5rem; font-size:0.75rem; color:#6b7280;">
<svg style="width:1rem; height:1rem; color:#22c55e; flex-shrink:0;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
Pilih semua gejala yang terlihat untuk hasil yang lebih akurat
</div>
<div style="display:flex; align-items:center; gap:0.75rem;">
<button type="button" onclick="resetGejala()" <button type="button" onclick="resetGejala()"
class="w-full mb-3 px-4 py-2 border border-gray-300 text-gray-600 font-semibold rounded-xl hover:bg-gray-50 transition text-sm"> style="display:flex; align-items:center; gap:0.5rem; padding:0.625rem 1rem; border:1px solid #d1d5db; color:#4b5563; font-weight:600; border-radius:0.75rem; background:white; cursor:pointer; font-size:0.875rem; transition:all 0.15s;">
Reset Pilihan <svg style="width:1rem; height:1rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
</svg>
Reset
</button> </button>
<button type="submit" <button type="submit"
class="w-full px-4 py-3 bg-gradient-to-r from-green-500 to-green-600 text-white font-bold rounded-xl hover:from-green-600 hover:to-green-700 transition shadow-lg text-sm"> style="display:flex; align-items:center; gap:0.5rem; padding:0.625rem 1.5rem; background:#16a34a; color:white; font-weight:700; border-radius:0.75rem; border:none; cursor:pointer; font-size:0.875rem; transition:background 0.15s; box-shadow:0 1px 3px rgba(0,0,0,0.12);">
<svg style="width:1rem; height:1rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2m-3 7l2 2 4-4"/>
</svg>
Diagnosa Sekarang Diagnosa Sekarang
</button> </button>
<!-- Info -->
<div class="mt-4 p-3 bg-green-50 rounded-xl">
<p class="text-xs text-green-700">
💡 Pilih semua gejala yang kamu amati pada tanaman untuk hasil diagnosa yang lebih akurat.
</p>
</div>
</div> </div>
</div> </div>
</div> </div>
</form> </form>
@ -108,60 +121,29 @@ class="w-full px-4 py-3 bg-gradient-to-r from-green-500 to-green-600 text-white
@push('scripts') @push('scripts')
<script> <script>
const gejalaData = {};
function updateSelected() { function updateSelected() {
const checkboxes = document.querySelectorAll('.gejala-checkbox:checked'); const checkboxes = document.querySelectorAll('.gejala-checkbox:checked');
const count = checkboxes.length; const count = checkboxes.length;
document.getElementById('selected-count').textContent = count; document.getElementById('selected-count').textContent = count;
const list = document.getElementById('selected-list');
const emptyMsg = document.getElementById('empty-msg');
if (count === 0) {
list.innerHTML = '<p class="text-sm text-gray-400 italic" id="empty-msg">Belum ada gejala dipilih</p>';
return;
}
list.innerHTML = '';
checkboxes.forEach(cb => {
const label = document.querySelector(`label[for="${cb.id}"] .flex-1 span`);
const nama = label ? label.textContent.trim() : cb.value;
list.innerHTML += `
<div class="flex items-center justify-between bg-green-50 px-3 py-2 rounded-lg">
<span class="text-xs font-medium text-green-800">${nama}</span>
<button type="button" onclick="removeGejala('${cb.id}')" class="text-green-500 hover:text-red-500 ml-2"></button>
</div>`;
});
// Update label styling
document.querySelectorAll('.gejala-item').forEach(label => { document.querySelectorAll('.gejala-item').forEach(label => {
const cb = label.querySelector('.gejala-checkbox'); const cb = label.querySelector('.gejala-checkbox');
if (cb.checked) { if (cb.checked) {
label.classList.add('border-green-500', 'bg-green-50'); label.style.borderColor = '#16a34a';
label.classList.remove('border-gray-200'); label.style.backgroundColor = '#f0fdf4';
} else { } else {
label.classList.remove('border-green-500', 'bg-green-50'); label.style.borderColor = '#e5e7eb';
label.classList.add('border-gray-200'); label.style.backgroundColor = '';
} }
}); });
} }
function removeGejala(id) {
const cb = document.getElementById(id);
if (cb) {
cb.checked = false;
updateSelected();
}
}
function resetGejala() { function resetGejala() {
document.querySelectorAll('.gejala-checkbox').forEach(cb => cb.checked = false); document.querySelectorAll('.gejala-checkbox').forEach(cb => cb.checked = false);
updateSelected(); updateSelected();
} }
// Search gejala document.getElementById('search-gejala').addEventListener('input', function () {
document.getElementById('search-gejala').addEventListener('input', function() {
const keyword = this.value.toLowerCase(); const keyword = this.value.toLowerCase();
document.querySelectorAll('.gejala-item').forEach(item => { document.querySelectorAll('.gejala-item').forEach(item => {
const nama = item.getAttribute('data-nama'); const nama = item.getAttribute('data-nama');

View File

@ -5,215 +5,256 @@
<title>Hasil Diagnosa - {{ $riwayat->id_diagnosis }}</title> <title>Hasil Diagnosa - {{ $riwayat->id_diagnosis }}</title>
<style> <style>
* { margin: 0; padding: 0; box-sizing: border-box; } * { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'DejaVu Sans', sans-serif; font-size: 12px; color: #1f2937; background: #ffffff; line-height: 1.5; } body {
font-family: 'DejaVu Sans', sans-serif;
font-size: 11.5px;
color: #1f2937;
background: #ffffff;
line-height: 1.5;
}
.header { background: #16a34a; color: white; padding: 24px 30px; } /* ── HEADER ── */
.badge { display: inline-block; padding: 3px 10px; border-radius: 999px; font-size: 9px; font-weight: bold; text-transform: uppercase; letter-spacing: 0.5px; background: #15803d; color: white; } .header { background: #1a4d2e; color: white; padding: 22px 28px 18px; }
.badge-danger-sangat-tinggi { background: #dc2626; color: white; } .header-top { width: 100%; border-collapse: collapse; margin-bottom: 12px; }
.badge-danger-tinggi { background: #f97316; color: white; } .header-top td { vertical-align: top; }
.badge-danger-sedang { background: #facc15; color: #713f12; }
.badge-danger-rendah { background: #bbf7d0; color: #14532d; }
.nama-latin { font-style: italic; font-size: 11px; color: #bbf7d0; }
.tanggal-box { text-align: right; font-size: 10px; color: #bbf7d0; }
.cf-box { background: #15803d; border-radius: 10px; padding: 12px 16px; margin-top: 12px; } .badge {
.cf-bar-bg { background: #166534; border-radius: 999px; height: 10px; width: 100%; } display: inline-block; padding: 2px 9px; border-radius: 999px;
.cf-bar-fill { background: white; border-radius: 999px; height: 10px; } font-size: 8.5px; font-weight: bold; text-transform: uppercase;
letter-spacing: 0.5px; background: rgba(255,255,255,0.15);
border: 1px solid rgba(255,255,255,0.25); color: white;
margin-right: 4px; margin-bottom: 4px;
}
.badge-st { background: #dc2626; border-color: #dc2626; color: #fff; }
.badge-t { background: #f97316; border-color: #f97316; color: #fff; }
.badge-s { background: #fde047; border-color: #fde047; color: #713f12; }
.badge-r { background: #bbf7d0; border-color: #bbf7d0; color: #14532d; }
.content { padding: 20px 30px; } .disease-name { font-size: 19px; font-weight: bold; color: #fff; margin: 8px 0 2px; }
.section { margin-bottom: 20px; } .disease-latin { font-style: italic; font-size: 10px; color: rgba(255,255,255,0.6); }
.section-title { font-size: 12px; font-weight: bold; color: #374151; margin-bottom: 10px; padding-bottom: 6px; border-bottom: 2px solid #d1fae5; } .meta-date { text-align: right; font-size: 9.5px; color: rgba(255,255,255,0.55); }
.meta-id { font-size: 8px; color: rgba(255,255,255,0.3); margin-top: 4px; }
.info-grid { width: 100%; border-collapse: collapse; } .cf-box { background: rgba(0,0,0,0.22); border-radius: 9px; padding: 10px 14px; }
.info-grid td { padding: 6px 10px; font-size: 11px; border-bottom: 1px solid #f3f4f6; } .cf-inner { width: 100%; border-collapse: collapse; margin-bottom: 5px; }
.info-grid td:first-child { color: #6b7280; width: 35%; } .cf-label { font-size: 10px; color: rgba(255,255,255,0.75); }
.info-grid td:last-child { font-weight: 600; color: #111827; } .cf-value { font-size: 20px; font-weight: bold; color: #fff; text-align: right; }
.cf-track { background: rgba(0,0,0,0.3); border-radius: 999px; height: 8px; width: 100%; }
.cf-fill { background: #ffffff; border-radius: 999px; height: 8px; }
.cf-ticks { width: 100%; border-collapse: collapse; margin-top: 2px; }
.cf-ticks td { font-size: 8px; color: rgba(255,255,255,0.35); }
.deskripsi-box { background: #f9fafb; border-radius: 8px; padding: 12px; font-size: 11px; color: #4b5563; line-height: 1.6; } /* ── CONTENT ── */
.content { padding: 18px 28px; }
.pengendalian-grid { width: 100%; border-collapse: separate; border-spacing: 6px; } /* two-col layout */
.pengendalian-grid td { vertical-align: top; width: 50%; padding: 10px; border-radius: 8px; font-size: 10px; line-height: 1.5; } .two-col { width: 100%; border-collapse: separate; border-spacing: 10px 0; }
.p-pencegahan { background: #eff6ff; color: #1d4ed8; } .two-col td { vertical-align: top; }
.p-kimia { background: #fff7ed; color: #c2410c; } .col-left { width: 38%; }
.p-organik { background: #f0fdf4; color: #15803d; } .col-right { width: 62%; }
.p-budidaya { background: #fefce8; color: #a16207; }
.pengendalian-label { font-weight: bold; font-size: 10px; margin-bottom: 4px; }
.gejala-item { background: #f0fdf4; border: 1px solid #bbf7d0; border-radius: 6px; padding: 4px 10px; font-size: 10px; color: #166534; margin-bottom: 4px; display: block; } /* section wrapper */
.section { margin-bottom: 14px; }
.kemungkinan-table { width: 100%; border-collapse: collapse; } .section-title {
.kemungkinan-table thead tr { background: #f3f4f6; } font-size: 10px; font-weight: bold; text-transform: uppercase;
.kemungkinan-table th { padding: 7px 10px; text-align: left; font-size: 10px; font-weight: bold; color: #6b7280; text-transform: uppercase; } letter-spacing: 0.07em; color: #374151;
.kemungkinan-table td { padding: 8px 10px; font-size: 11px; border-bottom: 1px solid #f3f4f6; vertical-align: middle; } padding-bottom: 5px; margin-bottom: 8px;
.rank-badge { display: inline-block; width: 22px; height: 22px; border-radius: 50%; text-align: center; line-height: 22px; font-size: 10px; font-weight: bold; color: white; } border-bottom: 2px solid #d1fae5;
display: flex; align-items: center; gap: 5px;
}
.section-title-bar {
display: inline-block; width: 3px; height: 12px;
background: #2d7a4f; border-radius: 2px;
margin-right: 4px; vertical-align: middle;
}
/* info grid */
.info-table { width: 100%; border-collapse: collapse; }
.info-table tr td { padding: 5px 6px; font-size: 10.5px; border-bottom: 1px solid #f3f4f6; }
.info-table tr:last-child td { border-bottom: none; }
.info-table td:first-child { color: #6b7280; width: 42%; }
.info-table td:last-child { font-weight: 600; color: #111827; }
.val-green { color: #16a34a !important; }
.val-blue { color: #2563eb !important; }
/* desc */
.desc-box { background: #f9fafb; border-radius: 7px; padding: 10px; font-size: 10.5px; color: #4b5563; line-height: 1.6; }
/* gejala */
.gejala-item {
display: block; background: #f0fdf4; border: 1px solid #bbf7d0;
border-radius: 5px; padding: 3px 8px 3px 6px;
font-size: 10px; color: #166534; margin-bottom: 3px;
}
.gejala-check { color: #16a34a; font-weight: bold; margin-right: 3px; }
/* pengendalian */
.ctrl-table { width: 100%; border-collapse: separate; border-spacing: 5px; }
.ctrl-table td { vertical-align: top; width: 50%; padding: 9px 10px; border-radius: 7px; font-size: 10px; line-height: 1.55; }
.ctrl-label { font-weight: bold; font-size: 9.5px; margin-bottom: 4px; }
.ctrl-pencegahan { background: #eff6ff; color: #1e40af; }
.ctrl-kimia { background: #fff7ed; color: #c2410c; }
.ctrl-organik { background: #f0fdf4; color: #15803d; }
.ctrl-budidaya { background: #fefce8; color: #a16207; }
/* kemungkinan */
.kemung-table { width: 100%; border-collapse: collapse; }
.kemung-table thead tr { background: #f3f4f6; }
.kemung-table th { padding: 6px 8px; text-align: left; font-size: 9px; font-weight: bold; color: #6b7280; text-transform: uppercase; }
.kemung-table td { padding: 7px 8px; font-size: 10.5px; border-bottom: 1px solid #f3f4f6; vertical-align: middle; }
.kemung-table tr:last-child td { border-bottom: none; }
.rank-circle { display: inline-block; width: 20px; height: 20px; border-radius: 50%; text-align: center; line-height: 20px; font-size: 9px; font-weight: bold; color: white; }
.rank-1 { background: #16a34a; } .rank-1 { background: #16a34a; }
.rank-other { background: #9ca3af; } .rank-other { background: #9ca3af; }
.mini-bar-bg { background: #e5e7eb; border-radius: 999px; height: 6px; width: 100%; } .mini-track { background: #e5e7eb; border-radius: 999px; height: 5px; width: 100%; }
.mini-bar-fill{ border-radius: 999px; height: 6px; } .mini-fill { border-radius: 999px; height: 5px; }
.relasi-table { width: 100%; border-collapse: collapse; font-size: 10px; } /* relasi */
.relasi-table th { background: #f9fafb; padding: 7px 8px; font-size: 9px; font-weight: bold; color: #6b7280; border: 1px solid #e5e7eb; text-align: center; } .relasi-table { width: 100%; border-collapse: collapse; font-size: 9.5px; }
.relasi-table th { background: #f9fafb; padding: 6px 7px; font-size: 8.5px; font-weight: bold; color: #6b7280; border: 1px solid #e5e7eb; text-align: center; }
.relasi-table th:first-child { text-align: left; } .relasi-table th:first-child { text-align: left; }
.relasi-table td { padding: 6px 8px; border: 1px solid #f3f4f6; text-align: center; } .relasi-table td { padding: 5px 7px; border: 1px solid #f3f4f6; text-align: center; }
.relasi-table td:first-child { text-align: left; } .relasi-table td:first-child { text-align: left; }
.relasi-table tr:nth-child(even) { background: #f9fafb; } .relasi-table tr:nth-child(even) { background: #f9fafb; }
.check-yes { color: #16a34a; font-weight: bold; font-size: 13px; } .check-yes { color: #16a34a; font-weight: bold; font-size: 12px; }
.check-no { color: #d1d5db; font-size: 13px; } .check-no { color: #d1d5db; font-size: 12px; }
.two-col { width: 100%; border-collapse: separate; border-spacing: 12px; } /* ── FOOTER ── */
.two-col td { vertical-align: top; width: 50%; } .footer { margin-top: 20px; background: #f0fdf4; border-top: 2px solid #d1fae5; }
.footer-table { width: 100%; border-collapse: collapse; }
.footer-table td { padding: 10px 28px; font-size: 8.5px; vertical-align: middle; }
.footer-note { color: #6b7280; font-style: italic; }
.footer-id { color: #16a34a; font-weight: bold; text-align: right; }
</style> </style>
</head> </head>
<body> <body>
{{-- HEADER --}} {{-- ── HEADER ── --}}
<div class="header"> <div class="header">
<table style="width:100%; border-collapse:collapse;"> <table class="header-top">
<tr> <tr>
<td style="vertical-align:top;"> <td>
<div style="margin-bottom:8px;"> {{-- Badges --}}
<span class="badge">&#x1F52C; Penyakit Terdeteksi</span> <span class="badge">Penyakit Terdeteksi</span>
@if($riwayat->penyakit?->tingkat_bahaya) @if($riwayat->penyakit?->tingkat_bahaya)
@php @php
$badgeClass = match($riwayat->penyakit->tingkat_bahaya) { $bc = match($riwayat->penyakit->tingkat_bahaya) {
'Sangat Tinggi' => 'badge-danger-sangat-tinggi', 'Sangat Tinggi' => 'badge-st',
'Tinggi' => 'badge-danger-tinggi', 'Tinggi' => 'badge-t',
'Sedang' => 'badge-danger-sedang', 'Sedang' => 'badge-s',
default => 'badge-danger-rendah', default => 'badge-r',
}; };
@endphp @endphp
&nbsp;<span class="badge {{ $badgeClass }}">&#x26A0; {{ $riwayat->penyakit->tingkat_bahaya }}</span> <span class="badge {{ $bc }}">{{ $riwayat->penyakit->tingkat_bahaya }}</span>
@endif @endif
</div>
<div style="font-size:20px; font-weight:bold; color:white; margin-bottom:2px;"> <div class="disease-name">{{ $riwayat->penyakit->nama_penyakit ?? 'Tidak Teridentifikasi' }}</div>
{{ $riwayat->penyakit->nama_penyakit ?? 'Tidak Teridentifikasi' }}
</div>
@if($riwayat->penyakit?->nama_latin) @if($riwayat->penyakit?->nama_latin)
<div class="nama-latin">{{ $riwayat->penyakit->nama_latin }}</div> <div class="disease-latin">{{ $riwayat->penyakit->nama_latin }}</div>
@endif @endif
</td> </td>
<td style="vertical-align:top; text-align:right;"> <td style="text-align:right; vertical-align:top;">
<div class="tanggal-box"> <div class="meta-date">
<div>{{ $riwayat->tanggal->format('d M Y') }}</div> {{ $riwayat->tanggal->format('d M Y') }}<br>
<div>{{ $riwayat->tanggal->format('H:i') }} WIB</div> {{ $riwayat->tanggal->format('H:i') }} WIB
<div style="margin-top:4px; font-size:9px; color:#bbf7d0;">ID: {{ $riwayat->id_diagnosis }}</div>
</div> </div>
<div class="meta-id">ID: {{ $riwayat->id_diagnosis }}</div>
</td> </td>
</tr> </tr>
</table> </table>
{{-- CF bar --}}
<div class="cf-box"> <div class="cf-box">
<table style="width:100%; border-collapse:collapse; margin-bottom:6px;"> <table class="cf-inner">
<tr> <tr>
<td style="font-size:11px; color:#bbf7d0;">Tingkat Kepercayaan</td> <td class="cf-label">Tingkat Kepercayaan (Certainty Factor)</td>
<td style="font-size:22px; font-weight:bold; color:white; text-align:right;">{{ round($riwayat->cf_tertinggi * 100, 1) }}%</td> <td class="cf-value">{{ round($riwayat->cf_tertinggi * 100, 1) }}%</td>
</tr> </tr>
</table> </table>
<div class="cf-bar-bg"> <div class="cf-track">
<div class="cf-bar-fill" style="width: {{ round($riwayat->cf_tertinggi * 100, 1) }}%;"></div> <div class="cf-fill" style="width:{{ round($riwayat->cf_tertinggi * 100, 1) }}%;"></div>
</div> </div>
<table style="width:100%; border-collapse:collapse; margin-top:3px;"> <table class="cf-ticks">
<tr> <tr>
<td style="font-size:9px; color:#bbf7d0;">0%</td> <td>0%</td>
<td style="font-size:9px; color:#bbf7d0; text-align:center;">50%</td> <td style="text-align:center;">50%</td>
<td style="font-size:9px; color:#bbf7d0; text-align:right;">100%</td> <td style="text-align:right;">100%</td>
</tr> </tr>
</table> </table>
</div> </div>
</div> </div>
{{-- CONTENT --}} {{-- ── CONTENT ── --}}
<div class="content"> <div class="content">
<table class="two-col"> {{-- Solusi / Pengendalian --}}
<tr>
<td>
<div class="section">
<div class="section-title">Info Diagnosa</div>
<table class="info-grid">
<tr><td>Tanggal</td><td>{{ $riwayat->tanggal->format('d F Y') }}</td></tr>
<tr><td>Waktu</td><td>{{ $riwayat->tanggal->format('H:i') }} WIB</td></tr>
<tr><td>Jumlah Gejala</td><td style="color:#2563eb;">{{ count($riwayat->gejala_input) }} gejala</td></tr>
<tr><td>CF Tertinggi</td><td style="color:#16a34a;">{{ round($riwayat->cf_tertinggi * 100, 1) }}%</td></tr>
<tr><td>Tingkat Bahaya</td><td>{{ $riwayat->penyakit?->tingkat_bahaya ?? '-' }}</td></tr>
</table>
</div>
</td>
<td>
<div class="section">
<div class="section-title">Gejala Dipilih</div>
@foreach($gejalaInput as $gejala)
<span class="gejala-item">&#x2713; {{ $gejala->nama_gejala }}</span>
@endforeach
</div>
</td>
</tr>
</table>
@if($riwayat->penyakit?->deskripsi_singkat)
<div class="section">
<div class="section-title">Deskripsi Penyakit</div>
<div class="deskripsi-box">{{ $riwayat->penyakit->deskripsi_singkat }}</div>
</div>
@endif
@if($riwayat->penyakit?->pengendalian_pencegahan || $riwayat->penyakit?->pengendalian_kimia || $riwayat->penyakit?->pengendalian_organik || $riwayat->penyakit?->pengendalian_budidaya) @if($riwayat->penyakit?->pengendalian_pencegahan || $riwayat->penyakit?->pengendalian_kimia || $riwayat->penyakit?->pengendalian_organik || $riwayat->penyakit?->pengendalian_budidaya)
<div class="section"> <div class="section">
<div class="section-title">Cara Pengendalian</div> <div class="section-title"><span class="section-title-bar"></span>Solusi &amp; Cara Pengendalian</div>
<table class="pengendalian-grid"> <table class="ctrl-table">
<tr> <tr>
@if($riwayat->penyakit?->pengendalian_pencegahan) @if($riwayat->penyakit?->pengendalian_pencegahan)
<td class="p-pencegahan"> <td class="ctrl-pencegahan">
<div class="pengendalian-label">Pencegahan</div> <div class="ctrl-label">Pencegahan</div>
{{ $riwayat->penyakit->pengendalian_pencegahan }} {{ $riwayat->penyakit->pengendalian_pencegahan }}
</td> </td>
@else
<td></td>
@endif @endif
@if($riwayat->penyakit?->pengendalian_kimia) @if($riwayat->penyakit?->pengendalian_kimia)
<td class="p-kimia"> <td class="ctrl-kimia">
<div class="pengendalian-label">Pengendalian Kimia</div> <div class="ctrl-label">Pengendalian Kimia</div>
{{ $riwayat->penyakit->pengendalian_kimia }} {{ $riwayat->penyakit->pengendalian_kimia }}
</td> </td>
@else
<td></td>
@endif @endif
</tr> </tr>
<tr> <tr>
@if($riwayat->penyakit?->pengendalian_organik) @if($riwayat->penyakit?->pengendalian_organik)
<td class="p-organik"> <td class="ctrl-organik">
<div class="pengendalian-label">Pengendalian Organik</div> <div class="ctrl-label">Pengendalian Organik</div>
{{ $riwayat->penyakit->pengendalian_organik }} {{ $riwayat->penyakit->pengendalian_organik }}
</td> </td>
@else
<td></td>
@endif @endif
@if($riwayat->penyakit?->pengendalian_budidaya) @if($riwayat->penyakit?->pengendalian_budidaya)
<td class="p-budidaya"> <td class="ctrl-budidaya">
<div class="pengendalian-label">Pengendalian Budidaya</div> <div class="ctrl-label">Pengendalian Budidaya</div>
{{ $riwayat->penyakit->pengendalian_budidaya }} {{ $riwayat->penyakit->pengendalian_budidaya }}
</td> </td>
@else
<td></td>
@endif @endif
</tr> </tr>
</table> </table>
</div> </div>
@endif @endif
{{-- Semua Kemungkinan Penyakit --}}
@if($riwayat->hasil_diagnosa && count($riwayat->hasil_diagnosa) > 1) @if($riwayat->hasil_diagnosa && count($riwayat->hasil_diagnosa) > 1)
<div class="section"> <div class="section">
<div class="section-title">Semua Kemungkinan Penyakit</div> <div class="section-title"><span class="section-title-bar"></span>Semua Kemungkinan Penyakit</div>
<table class="kemungkinan-table"> <table class="kemung-table">
<thead> <thead>
<tr> <tr>
<th style="width:40px;">#</th> <th style="width:32px;">#</th>
<th>Nama Penyakit</th> <th>Nama Penyakit</th>
<th style="width:60px; text-align:right;">CF</th> <th style="width:52px; text-align:right;">Akurasi</th>
<th style="width:120px;">Grafik</th> <th style="width:110px;">Grafik</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@foreach($riwayat->hasil_diagnosa as $index => $hasil) @foreach($riwayat->hasil_diagnosa as $index => $hasil)
<tr> <tr>
<td><span class="rank-badge {{ $index === 0 ? 'rank-1' : 'rank-other' }}">{{ $index + 1 }}</span></td> <td><span class="rank-circle {{ $index === 0 ? 'rank-1' : 'rank-other' }}">{{ $index + 1 }}</span></td>
<td style="{{ $index === 0 ? 'font-weight:bold; color:#166534;' : 'color:#374151;' }}">{{ $hasil['nama_penyakit'] }}</td> <td style="{{ $index === 0 ? 'font-weight:bold; color:#166534;' : 'color:#374151;' }}">{{ $hasil['nama_penyakit'] }}</td>
<td style="text-align:right; font-weight:bold; color:{{ $index === 0 ? '#16a34a' : '#6b7280' }};">{{ $hasil['persentase'] }}%</td> <td style="text-align:right; font-weight:bold; color:{{ $index === 0 ? '#16a34a' : '#6b7280' }};">{{ $hasil['persentase'] }}%</td>
<td> <td>
<div class="mini-bar-bg"> <div class="mini-track">
<div class="mini-bar-fill" style="width:{{ $hasil['persentase'] }}%; background:{{ $index === 0 ? '#16a34a' : '#9ca3af' }};"></div> <div class="mini-fill" style="width:{{ $hasil['persentase'] }}%; background:{{ $index === 0 ? '#16a34a' : '#9ca3af' }};"></div>
</div> </div>
</td> </td>
</tr> </tr>
@ -223,9 +264,10 @@
</div> </div>
@endif @endif
{{-- Relasi Gejala --}}
@if($relasiGejala->count() > 0) @if($relasiGejala->count() > 0)
<div class="section"> <div class="section">
<div class="section-title">Relasi Gejala &amp; Penyakit</div> <div class="section-title"><span class="section-title-bar"></span>Relasi Gejala &amp; Penyakit</div>
<table class="relasi-table"> <table class="relasi-table">
<thead> <thead>
<tr> <tr>
@ -256,25 +298,27 @@
@endforeach @endforeach
</tbody> </tbody>
</table> </table>
<p style="font-size:9px; color:#9ca3af; margin-top:6px;">&#x2713; = gejala terkait penyakit tersebut &nbsp;|&nbsp; &#x2717; = tidak terkait</p> <p style="font-size:8px; color:#9ca3af; margin-top:5px;">&#x2713; = gejala terkait penyakit &nbsp;|&nbsp; &#x2717; = tidak terkait</p>
</div> </div>
@endif @endif
</div> </div>
{{-- FOOTER --}} {{-- ── FOOTER ── --}}
<table style="width:100%; border-collapse:collapse; margin-top:24px; background:#f0fdf4; border-top:2px solid #d1fae5;"> <div class="footer">
<tr> <table class="footer-table">
<td style="padding:12px 30px; font-size:9px; color:#6b7280; font-style:italic; vertical-align:middle;"> <tr>
Dokumen ini digenerate otomatis oleh sistem pakar diagnosa penyakit tanaman kopi.<br> <td class="footer-note">
Hasil diagnosa bersifat prediktif. Konsultasikan dengan ahli pertanian untuk penanganan lebih lanjut. Dokumen ini digenerate otomatis oleh sistem pakar diagnosa penyakit tanaman kopi.<br>
</td> Hasil diagnosa bersifat prediktif. Konsultasikan dengan ahli pertanian untuk penanganan lebih lanjut.
<td style="padding:12px 30px; font-size:9px; color:#16a34a; font-weight:bold; text-align:right; vertical-align:middle;"> </td>
ID: {{ $riwayat->id_diagnosis }}<br> <td class="footer-id">
{{ now()->format('d/m/Y H:i') }} ID: {{ $riwayat->id_diagnosis }}<br>
</td> {{ now()->format('d/m/Y H:i') }}
</tr> </td>
</table> </tr>
</table>
</div>
</body> </body>
</html> </html>

View File

@ -5,112 +5,139 @@
@section('content') @section('content')
<div class="bg-white rounded-2xl shadow-lg"> @if(session('success'))
<div class="p-8"> <div style="margin-bottom:1.5rem; background:#f0fdf4; border:1px solid #bbf7d0; color:#15803d; padding:1rem 1.25rem; border-radius:0.75rem; display:flex; align-items:center; gap:0.75rem;">
<div class="flex items-center justify-between mb-6"> <svg style="width:1.25rem; height:1.25rem; flex-shrink:0;" fill="currentColor" viewBox="0 0 20 20">
<div class="flex items-center"> <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
<div class="bg-gradient-to-r from-green-500 to-green-600 rounded-xl p-3 mr-4"> </svg>
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <span style="font-weight:600; font-size:0.875rem;">{{ session('success') }}</span>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
<h3 class="text-xl font-bold text-gray-800">Riwayat Diagnosa</h3>
</div>
<a href="{{ route('user.diagnosa.index') }}"
class="flex items-center px-5 py-3 bg-gradient-to-r from-green-500 to-green-600 text-white font-bold rounded-xl hover:from-green-600 hover:to-green-700 transition shadow-lg text-sm">
+ Diagnosa Baru
</a>
</div>
<div class="overflow-x-auto rounded-xl border border-gray-200">
@if(session('success'))
<div class="mb-6 bg-green-100 border-l-4 border-green-500 text-green-700 p-4 rounded-lg">
{{ session('success') }}
</div>
@endif
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th class="px-6 py-4 text-left text-xs font-bold text-gray-600 uppercase">No</th>
<th class="px-6 py-4 text-left text-xs font-bold text-gray-600 uppercase">Tanggal</th>
<th class="px-6 py-4 text-left text-xs font-bold text-gray-600 uppercase">Penyakit</th>
<th class="px-6 py-4 text-left text-xs font-bold text-gray-600 uppercase">Gejala</th>
<th class="px-6 py-4 text-left text-xs font-bold text-gray-600 uppercase">CF</th>
<th class="px-6 py-4 text-center text-xs font-bold text-gray-600 uppercase">Aksi</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
@forelse($riwayats as $index => $riwayat)
<tr class="hover:bg-gray-50 transition-colors">
<td class="px-6 py-4 text-sm">{{ $riwayats->firstItem() + $index }}</td>
<td class="px-6 py-4 text-sm text-gray-600">{{ $riwayat->tanggal->format('d M Y, H:i') }}</td>
<td class="px-6 py-4">
<span class="text-sm font-semibold text-gray-800">
{{ $riwayat->penyakit->nama_penyakit ?? '-' }}
</span>
</td>
<td class="px-6 py-4">
<span class="px-2 py-1 text-xs font-bold rounded-full bg-blue-100 text-blue-700">
{{ count($riwayat->gejala_input) }} gejala
</span>
</td>
<td class="px-6 py-4">
<span class="px-2 py-1 text-xs font-bold rounded-full
{{ $riwayat->cf_tertinggi >= 0.8 ? 'bg-red-100 text-red-700' :
($riwayat->cf_tertinggi >= 0.5 ? 'bg-yellow-100 text-yellow-700' : 'bg-green-100 text-green-700') }}">
{{ round($riwayat->cf_tertinggi * 100, 1) }}%
</span>
</td>
<td class="px-6 py-4 text-center">
<div class="flex items-center justify-center space-x-2">
{{-- Lihat Detail --}}
<a href="{{ route('user.diagnosa.hasil', $riwayat->id_diagnosis) }}"
class="inline-flex items-center px-3 py-2 bg-green-500 text-white text-xs font-semibold rounded-lg hover:bg-green-600 transition">
Lihat Detail
</a>
{{-- Download PDF --}}
<a href="{{ route('user.riwayat.pdf', $riwayat->id_diagnosis) }}"
target="_blank"
class="inline-flex items-center gap-1 px-3 py-2 bg-blue-500 text-white text-xs font-semibold rounded-lg hover:bg-blue-600 transition">
<svg xmlns="http://www.w3.org/2000/svg" class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 10v6m0 0l-3-3m3 3l3-3M3 17V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z" />
</svg>
PDF
</a>
{{-- Hapus --}}
<form action="{{ route('user.diagnosa.destroy', $riwayat->id_diagnosis) }}" method="POST"
onsubmit="return confirm('Yakin ingin menghapus riwayat ini?')">
@csrf
@method('DELETE')
<button type="submit"
class="inline-flex items-center px-3 py-2 bg-red-500 text-white text-xs font-semibold rounded-lg hover:bg-red-600 transition">
Hapus
</button>
</form>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="6" class="px-6 py-12 text-center text-gray-400">
<svg class="w-16 h-16 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path>
</svg>
<p class="text-xl font-semibold mb-2">Belum ada riwayat diagnosa</p>
<a href="{{ route('user.diagnosa.index') }}" class="text-green-600 font-semibold hover:underline">
Mulai diagnosa sekarang
</a>
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="mt-6">{{ $riwayats->links() }}</div>
</div> </div>
@endif
<div style="background:white; border-radius:1.25rem; box-shadow:0 1px 4px rgba(0,0,0,0.07); border:1px solid #f0fdf4; overflow:hidden;">
{{-- Header --}}
<div style="padding:1.25rem 1.5rem; border-bottom:1px solid #f3f4f6; display:flex; align-items:center; justify-content:space-between; gap:1rem; flex-wrap:wrap;">
<div style="display:flex; align-items:center; gap:0.75rem;">
<div style="width:2.5rem; height:2.5rem; background:#dcfce7; border-radius:0.75rem; display:flex; align-items:center; justify-content:center; flex-shrink:0;">
<svg style="width:1.25rem; height:1.25rem; color:#16a34a;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</div>
<div>
<div style="font-size:0.9rem; font-weight:700; color:#111827;">Riwayat Diagnosa</div>
<div style="font-size:0.75rem; color:#9ca3af;">Histori diagnosa penyakit tanaman kopi kamu</div>
</div>
</div>
<a href="{{ route('user.diagnosa.index') }}"
style="display:inline-flex; align-items:center; gap:0.5rem; padding:0.625rem 1.25rem; background:#16a34a; color:white; font-weight:700; font-size:0.875rem; border-radius:0.75rem; text-decoration:none; white-space:nowrap;">
<svg style="width:1rem; height:1rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"/>
</svg>
Diagnosa Baru
</a>
</div>
{{-- Table --}}
<div style="overflow-x:auto;">
<table style="width:100%; border-collapse:collapse; font-size:0.875rem;">
<thead>
<tr style="background:#f9fafb;">
<th style="padding:0.875rem 1.25rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6;">No</th>
<th style="padding:0.875rem 1.25rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6;">Tanggal</th>
<th style="padding:0.875rem 1.25rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6;">Penyakit</th>
<th style="padding:0.875rem 1.25rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6;">Gejala</th>
<th style="padding:0.875rem 1.25rem; text-align:left; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6;">CF</th>
<th style="padding:0.875rem 1.25rem; text-align:center; font-size:0.7rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.05em; border-bottom:1px solid #f3f4f6;">Aksi</th>
</tr>
</thead>
<tbody>
@forelse($riwayats as $index => $riwayat)
<tr style="border-bottom:1px solid #f9fafb;" onmouseover="this.style.background='#f9fafb'" onmouseout="this.style.background=''">
<td style="padding:1rem 1.25rem; color:#6b7280;">{{ $riwayats->firstItem() + $index }}</td>
<td style="padding:1rem 1.25rem; color:#6b7280;">{{ $riwayat->tanggal->format('d M Y, H:i') }}</td>
<td style="padding:1rem 1.25rem; font-weight:600; color:#111827;">
{{ $riwayat->penyakit->nama_penyakit ?? '-' }}
</td>
<td style="padding:1rem 1.25rem;">
<span style="padding:0.25rem 0.75rem; font-size:0.7rem; font-weight:700; border-radius:9999px; background:#f0fdf4; color:#166534; border:1px solid #bbf7d0;">
{{ count($riwayat->gejala_input) }} gejala
</span>
</td>
<td style="padding:1rem 1.25rem;">
@php $cf = $riwayat->cf_tertinggi; @endphp
@if($cf >= 0.8)
<span style="padding:0.25rem 0.75rem; font-size:0.7rem; font-weight:700; border-radius:9999px; background:#14532d; color:white;">
{{ round($cf * 100, 1) }}%
</span>
@elseif($cf >= 0.5)
<span style="padding:0.25rem 0.75rem; font-size:0.7rem; font-weight:700; border-radius:9999px; background:#dcfce7; color:#15803d; border:1px solid #bbf7d0;">
{{ round($cf * 100, 1) }}%
</span>
@else
<span style="padding:0.25rem 0.75rem; font-size:0.7rem; font-weight:700; border-radius:9999px; background:#f3f4f6; color:#6b7280;">
{{ round($cf * 100, 1) }}%
</span>
@endif
</td>
<td style="padding:1rem 1.25rem; text-align:center;">
<div style="display:inline-flex; align-items:center; gap:0.5rem;">
{{-- Lihat Detail --}}
<a href="{{ route('user.diagnosa.hasil', $riwayat->id_diagnosis) }}"
style="display:inline-flex; align-items:center; gap:0.375rem; padding:0.4rem 0.875rem; background:#f0fdf4; color:#16a34a; font-size:0.75rem; font-weight:600; border-radius:0.5rem; border:1px solid #bbf7d0; text-decoration:none;">
<svg style="width:0.875rem; height:0.875rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"/>
</svg>
Detail
</a>
{{-- Download PDF --}}
<a href="{{ route('user.riwayat.pdf', $riwayat->id_diagnosis) }}" target="_blank"
style="display:inline-flex; align-items:center; gap:0.375rem; padding:0.4rem 0.875rem; background:#f9fafb; color:#374151; font-size:0.75rem; font-weight:600; border-radius:0.5rem; border:1px solid #e5e7eb; text-decoration:none;">
<svg style="width:0.875rem; height:0.875rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3M3 17V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z"/>
</svg>
PDF
</a>
{{-- Hapus --}}
<form action="{{ route('user.diagnosa.destroy', $riwayat->id_diagnosis) }}" method="POST"
onsubmit="return confirm('Yakin ingin menghapus riwayat ini?')" style="display:inline;">
@csrf
@method('DELETE')
<button type="submit"
style="display:inline-flex; align-items:center; gap:0.375rem; padding:0.4rem 0.875rem; background:#fef2f2; color:#dc2626; font-size:0.75rem; font-weight:600; border-radius:0.5rem; border:1px solid #fecaca; cursor:pointer;">
<svg style="width:0.875rem; height:0.875rem;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
</svg>
Hapus
</button>
</form>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="6" style="padding:3rem; text-align:center; color:#9ca3af;">
<svg style="width:3rem; height:3rem; margin:0 auto 1rem; color:#d1fae5;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/>
</svg>
<p style="font-size:1rem; font-weight:600; color:#374151; margin-bottom:0.5rem;">Belum ada riwayat diagnosa</p>
<a href="{{ route('user.diagnosa.index') }}" style="font-size:0.875rem; color:#16a34a; font-weight:600; text-decoration:none;">
Mulai diagnosa sekarang
</a>
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div style="padding:1rem 1.5rem; border-top:1px solid #f3f4f6;">
{{ $riwayats->links() }}
</div>
</div> </div>
@endsection @endsection

View File

@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sistem Pakar Kopi - Deteksi Penyakit Tanaman Kopi</title> <title>CekKopi - Deteksi Penyakit Tanaman Kopi</title>
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@700;900&family=DM+Sans:wght@300;400;500;600&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@700;900&family=DM+Sans:wght@300;400;500;600&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
@ -42,7 +42,7 @@
} }
.brand-icon { .brand-icon {
width: 36px; height: 36px; border-radius: 10px; width: 36px; height: 36px; border-radius: 10px;
background: linear-gradient(135deg, var(--green-600), var(--green-900)); background: white;
display: flex; align-items: center; justify-content: center; display: flex; align-items: center; justify-content: center;
} }
.brand-icon i { color: white; font-size: 18px; } .brand-icon i { color: white; font-size: 18px; }
@ -350,8 +350,10 @@
<nav class="navbar navbar-expand-lg fixed-top"> <nav class="navbar navbar-expand-lg fixed-top">
<div class="container"> <div class="container">
<a class="navbar-brand" href="#"> <a class="navbar-brand" href="#">
<div class="brand-icon"><i class="bi bi-flower1"></i></div> <div class="brand-icon overflow-hidden p-1">
Sistem Pakar Kopi <img src="{{ asset('asset/images/v2_nobg.png') }}" style="width:100%;height:100%;object-fit:contain;" alt="Logo">
</div>
Cek Kopi
</a> </a>
<button class="navbar-toggler border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navMenu"> <button class="navbar-toggler border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navMenu">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
@ -664,7 +666,7 @@
<!-- KONTAK --> <!-- KONTAK -->
<section id="kontak"> <section id="kontak">
<div class="container"> <div class="container">
<div class="row g-5 align-items-start"> <div class="row g-5 align-items-center">
<div class="col-lg-5 reveal"> <div class="col-lg-5 reveal">
<span class="section-label">Hubungi Kami</span> <span class="section-label">Hubungi Kami</span>
<h2 class="section-title">Ada Pertanyaan?</h2> <h2 class="section-title">Ada Pertanyaan?</h2>
@ -674,7 +676,7 @@
<div class="contact-icon-box"><i class="bi bi-envelope"></i></div> <div class="contact-icon-box"><i class="bi bi-envelope"></i></div>
<div> <div>
<div class="contact-info-title">Email</div> <div class="contact-info-title">Email</div>
<p class="contact-info-text">sistempakar.kopi@gmail.com</p> <p class="contact-info-text">cekkopiyuk@gmail.com</p>
</div> </div>
</div> </div>
<div class="d-flex align-items-start gap-3"> <div class="d-flex align-items-start gap-3">
@ -684,42 +686,44 @@
<p class="contact-info-text">Indonesia</p> <p class="contact-info-text">Indonesia</p>
</div> </div>
</div> </div>
<div class="d-flex align-items-start gap-3">
<div class="contact-icon-box"><i class="bi bi-clock"></i></div>
<div>
<div class="contact-info-title">Jam Layanan</div>
<p class="contact-info-text">Senin - Jumat, 08.00 - 17.00 WIB</p>
</div>
</div>
</div> </div>
</div> </div>
<div class="col-lg-7 reveal"> <div class="col-lg-7 reveal">
<div class="contact-form-card"> <div class="contact-form-card">
<h5 style="font-size:18px;font-weight:700;color:var(--green-900);margin-bottom:24px;">Kirim Pesan</h5> <h5 style="font-size:18px;font-weight:700;color:var(--green-900);margin-bottom:24px;">Kirim Pesan</h5>
<div class="row g-3"> <form action="{{ route('contact.send') }}" method="POST">
<div class="col-md-6"> @csrf
<label class="form-label">Nama Lengkap</label> @if(session('success'))
<input type="text" class="form-control" placeholder="Masukkan nama kamu..."> <div style="padding:12px;background:#dcfce7;color:#166534;border-radius:8px;margin-bottom:16px;font-size:14px;font-weight:600;">
</div> {{ session('success') }}
<div class="col-md-6"> </div>
<label class="form-label">Email</label> @endif
<input type="email" class="form-control" placeholder="email@contoh.com"> <div class="row g-3">
</div> <div class="col-md-6">
<div class="col-12"> <label class="form-label">Nama Lengkap</label>
<label class="form-label">Subjek</label> <input type="text" name="nama" class="form-control" placeholder="Masukkan nama kamu...">
<input type="text" class="form-control" placeholder="Subjek pesan..."> </div>
</div> <div class="col-md-6">
<div class="col-12"> <label class="form-label">Email</label>
<label class="form-label">Pesan</label> <input type="email" name="email" class="form-control" placeholder="email@contoh.com">
<textarea class="form-control" rows="4" placeholder="Tulis pesanmu di sini..."></textarea> </div>
</div> <div class="col-12">
<div class="col-12"> <label class="form-label">Subjek</label>
<button class="btn-submit">Kirim Pesan</button> <input type="text" name="subjek" class="form-control" placeholder="Subjek pesan...">
</div>
<div class="col-12">
<label class="form-label">Pesan</label>
<textarea name="pesan" class="form-control" rows="4" placeholder="Tulis pesanmu di sini..."></textarea>
</div>
<div class="col-12">
<button type="submit" class="btn-submit">Kirim Pesan</button>
</div>
</div>
</form>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
</div> </div>
</section> </section>
@ -729,8 +733,10 @@
<div class="row g-5"> <div class="row g-5">
<div class="col-lg-4"> <div class="col-lg-4">
<div class="footer-brand"> <div class="footer-brand">
<div class="brand-icon"><i class="bi bi-flower1" style="color:white;font-size:18px;"></i></div> <div class="brand-icon overflow-hidden p-1">
Sistem Pakar Kopi <img src="{{ asset('asset/images/v2_nobg.png') }}" style="width:100%;height:100%;object-fit:contain;" alt="Logo">
</div>
Cek Kopi
</div> </div>
<p class="footer-desc">Platform cerdas untuk mendeteksi penyakit tanaman kopi dan memberikan solusi pengendalian yang tepat bagi petani Indonesia.</p> <p class="footer-desc">Platform cerdas untuk mendeteksi penyakit tanaman kopi dan memberikan solusi pengendalian yang tepat bagi petani Indonesia.</p>
</div> </div>
@ -763,7 +769,7 @@
</div> </div>
</div> </div>
<div class="footer-bottom"> <div class="footer-bottom">
<p>© 2026 Sistem Pakar Kopi. Hak cipta dilindungi.</p> <p>© 2026 Cek Kopi by Evi. All rights reserved.</p>
</div> </div>
</div> </div>
</footer> </footer>

View File

@ -87,4 +87,6 @@
Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy'); Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
}); });
// Sending Email dari landing page
Route::post('/contact', [App\Http\Controllers\ContactController::class, 'send'])->name('contact.send');
require __DIR__.'/auth.php'; require __DIR__.'/auth.php';