UI biar lebih bagus ajasi

This commit is contained in:
adindacintya 2026-06-07 21:08:02 +07:00
parent 6822647fa5
commit c0d803fe21
40 changed files with 1098 additions and 1020 deletions

View File

@ -0,0 +1,70 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use App\Models\User; // Pastikan ini ditambahkan di atas
class AuthController extends Controller
{
// --- FITUR LOGIN ---
public function index()
{
return view('login');
}
public function authenticate(Request $request)
{
$credentials = $request->validate([
'email' => 'required|email',
'password' => 'required'
]);
if (Auth::attempt($credentials)) {
$request->session()->regenerate();
return redirect()->intended('/dashboard');
}
return back()->with('error', 'Email atau Password salah!');
}
// --- FITUR LOGOUT ---
public function logout(Request $request)
{
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/');
}
// --- FITUR REGISTRASI ---
public function register()
{
return view('register');
}
public function store(Request $request)
{
// 1. Validasi data yang diinput
$validatedData = $request->validate([
'name' => 'required|max:255',
'email' => 'required|email|unique:users', // Cek agar email tidak ganda
'password' => 'required|min:5|confirmed' // Harus ada konfirmasi password
]);
// 2. Acak/enkripsi password sebelum disimpan ke database
$validatedData['password'] = Hash::make($validatedData['password']);
// 3. Masukkan data ke tabel users
$user = User::create($validatedData);
// 4. Langsung login-kan otomatis setelah berhasil daftar
Auth::login($user);
// 5. Lempar ke dashboard
return redirect('/dashboard')->with('success', 'Registrasi berhasil! Selamat datang di Rice Leaf AI.');
}
}

View File

@ -5,6 +5,7 @@
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Auth; // <-- WAJIB TAMBAH INI
use App\Models\Prediksi;
use Barryvdh\DomPDF\Facade\Pdf;
@ -29,69 +30,43 @@ public function prediksi(Request $request)
}
$namaFile = time() . '.' . $gambar->getClientOriginalExtension();
$gambar->move($uploadPath, $namaFile);
$pathGambar = $uploadPath . DIRECTORY_SEPARATOR . $namaFile;
try {
$response = Http::timeout(60)
->attach(
'gambar',
file_get_contents($pathGambar),
$namaFile
)
->attach('gambar', file_get_contents($pathGambar), $namaFile)
->post('http://127.0.0.1:5000/prediksi');
if (!$response->successful()) {
Log::error('Server prediksi gagal', [
'body' => $response->body()
]);
return back()->with([
'error' => 'Tidak dapat memproses prediksi.'
]);
Log::error('Server prediksi gagal', ['body' => $response->body()]);
return back()->with('error', 'Tidak dapat memproses prediksi.');
}
$hasil = $response->json();
$allPredictions = $hasil['all_predictions'] ?? [];
$deskripsi = '';
$solusi = '';
if ($hasil['penyakit'] == 'Blast') {
$deskripsi = 'Blast adalah penyakit daun padi akibat jamur Pyricularia oryzae yang menyebabkan bercak berbentuk belah ketupat.';
$solusi = 'Gunakan fungisida, kurangi kelembaban lahan, dan gunakan varietas tahan penyakit.';
}
elseif ($hasil['penyakit'] == 'Blight') {
$deskripsi = 'Blight merupakan penyakit hawar daun bakteri yang menyebabkan daun menguning dan mengering.';
$solusi = 'Gunakan benih sehat, lakukan sanitasi lahan, dan gunakan bakterisida.';
}
elseif ($hasil['penyakit'] == 'Tungro') {
$deskripsi = 'Tungro adalah penyakit virus pada tanaman padi yang ditularkan oleh wereng hijau.';
$solusi = 'Kendalikan wereng hijau dan gunakan varietas tahan tungro.';
}
elseif ($hasil['penyakit'] == 'Healthy') {
$deskripsi = 'Daun padi dalam kondisi sehat dan tidak terdeteksi penyakit.';
$solusi = 'Pertahankan pola tanam dan perawatan yang baik.';
}
// Logika deskripsi tetap sama
$deskripsi = ''; $solusi = '';
if ($hasil['penyakit'] == 'Blast') {
$deskripsi = 'Blast adalah penyakit daun padi akibat jamur Pyricularia oryzae.';
$solusi = 'Gunakan fungisida dan varietas tahan.';
} elseif ($hasil['penyakit'] == 'Blight') {
$deskripsi = 'Blight merupakan hawar daun bakteri.';
$solusi = 'Gunakan benih sehat dan sanitasi lahan.';
} elseif ($hasil['penyakit'] == 'Tungro') {
$deskripsi = 'Tungro adalah penyakit virus.';
$solusi = 'Kendalikan wereng hijau.';
} elseif ($hasil['penyakit'] == 'Healthy') {
$deskripsi = 'Kondisi tanaman sehat.';
$solusi = 'Pertahankan perawatan yang baik.';
}
// SIMPAN DATA DENGAN USER_ID
Prediksi::create([
'gambar' => $namaFile,
'penyakit' => $hasil['penyakit'],
'confidence' => $hasil['confidence']
'confidence' => $hasil['confidence'],
'user_id' => Auth::id(), // <-- INI YANG MEMBUAT PRIVAT
]);
return back()->with([
@ -101,104 +76,76 @@ public function prediksi(Request $request)
'confidence' => $hasil['confidence'] ?? 0,
'deskripsi' => $deskripsi,
'solusi' => $solusi,
'allPredictions' => $allPredictions,
'allPredictions' => $hasil['all_predictions'] ?? [],
]);
} catch (\Exception $e) {
Log::error(
'Prediksi request error: ' . $e->getMessage()
);
return back()->with([
'error' => 'Terjadi kesalahan saat menghubungi server prediksi.'
]);
Log::error('Prediksi request error: ' . $e->getMessage());
return back()->with('error', 'Terjadi kesalahan server.');
}
}
// ===== RIWAYAT =====
public function riwayat(Request $request)
{
// FILTER BERDASARKAN USER_ID
$query = Prediksi::where('user_id', Auth::id());
public function riwayat(Request $request)
{
$query = Prediksi::query();
if ($request->filled('search')) {
$query->where('penyakit', 'like', '%' . $request->search . '%');
}
if ($request->filled('search')) {
$query->where('penyakit', 'like', '%' . $request->search . '%');
if ($request->filled('filter')) {
$query->where('penyakit', $request->filter);
}
$data = $query->latest()->get();
return view('riwayat', compact('data'));
}
if ($request->filled('filter')) {
$query->where('penyakit', $request->filter);
}
$data = $query->latest()->get();
return view('riwayat', compact('data'));
}
// ===== DASHBOARD =====
public function dashboard()
{
$totalPrediksi = Prediksi::count();
// FILTER BERDASARKAN USER_ID
$userId = Auth::id();
$blast = Prediksi::where('penyakit', 'Blast')->count();
$totalPrediksi = Prediksi::where('user_id', $userId)->count();
$blast = Prediksi::where('user_id', $userId)->where('penyakit', 'Blast')->count();
$blight = Prediksi::where('user_id', $userId)->where('penyakit', 'Blight')->count();
$healthy = Prediksi::where('user_id', $userId)->where('penyakit', 'Healthy')->count();
$tungro = Prediksi::where('user_id', $userId)->where('penyakit', 'Tungro')->count();
$terbaru = Prediksi::where('user_id', $userId)->latest()->take(3)->get();
$blight = Prediksi::where('penyakit', 'Blight')->count();
$healthy = Prediksi::where('penyakit', 'Healthy')->count();
$tungro = Prediksi::where('penyakit', 'Tungro')->count();
$terbaru = Prediksi::latest()->take(5)->get();
return view('dashboard', compact(
'totalPrediksi',
'blast',
'blight',
'healthy',
'tungro',
'terbaru'
));
return view('dashboard', compact('totalPrediksi', 'blast', 'blight', 'healthy', 'tungro', 'terbaru'));
}
public function exportPdf()
{
$data = Prediksi::latest()->get();
{
$data = Prediksi::where('user_id', Auth::id())->latest()->get();
$pdf = Pdf::loadView('pdf.laporan', compact('data'));
return $pdf->download('laporan-prediksi.pdf');
}
$pdf = Pdf::loadView(
'pdf.laporan',
compact('data')
);
return $pdf->download(
'laporan-prediksi.pdf'
);
}
public function hapus($id)
{
$data = Prediksi::findOrFail($id);
{
// Tambahkan cek user_id agar user tidak bisa hapus data orang lain via URL
$data = Prediksi::where('id', $id)->where('user_id', Auth::id())->firstOrFail();
$path = public_path('uploads/' . $data->gambar);
if (file_exists($path)) {
unlink($path);
}
$data->delete();
return redirect()->back()->with(
'success',
'Data berhasil dihapus'
);
$path = public_path('uploads/' . $data->gambar);
if (file_exists($path)) {
unlink($path);
}
$data->delete();
return redirect()->back()->with('success', 'Data berhasil dihapus');
}
public function statistik()
{
return response()->json([
'blast' => Prediksi::where('penyakit', 'Blast')->count(),
'blight' => Prediksi::where('penyakit', 'Blight')->count(),
'healthy' => Prediksi::where('penyakit', 'Healthy')->count(),
'tungro' => Prediksi::where('penyakit', 'Tungro')->count(),
]);
}
}
{
$userId = Auth::id();
return response()->json([
'blast' => Prediksi::where('user_id', $userId)->where('penyakit', 'Blast')->count(),
'blight' => Prediksi::where('user_id', $userId)->where('penyakit', 'Blight')->count(),
'healthy' => Prediksi::where('user_id', $userId)->where('penyakit', 'Healthy')->count(),
'tungro' => Prediksi::where('user_id', $userId)->where('penyakit', 'Tungro')->count(),
]);
}
}

View File

@ -9,6 +9,7 @@ class Prediksi extends Model
protected $fillable = [
'gambar',
'penyakit',
'confidence'
'confidence',
'user_id'
];
}
}

View File

@ -0,0 +1,24 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('prediksis', function (Blueprint $table) {
// Kita tambah user_id agar tiap prediksi punya pemilik
$table->foreignId('user_id')->nullable()->constrained('users')->onDelete('cascade');
});
}
public function down(): void
{
Schema::table('prediksis', function (Blueprint $table) {
$table->dropForeign(['user_id']);
$table->dropColumn('user_id');
});
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

View File

@ -1,209 +1,84 @@
<!DOCTYPE html>
<html>
<head>
<title>Dashboard</title>
@extends('layouts.main')
<script src="https://cdn.tailwindcss.com"></script>
</head>
@section('title', 'Dashboard - Rice Leaf AI')
<body class="bg-green-50">
<div class="p-10">
<h1 class="text-4xl font-bold text-green-700 mb-8">
Dashboard Klasifikasi Daun Padi
</h1>
<!-- Statistik -->
<div class="grid md:grid-cols-5 gap-6 mb-10">
<div class="bg-white p-6 rounded-xl shadow">
<h2 class="text-gray-500">Total Prediksi</h2>
<p class="text-4xl font-bold text-green-700 mt-2">
{{ $totalPrediksi }}
</p>
</div>
<div class="bg-white p-6 rounded-xl shadow">
<h2 class="text-gray-500">Blast</h2>
<p class="text-4xl font-bold text-red-600 mt-2">
{{ $blast }}
</p>
</div>
<div class="bg-white p-6 rounded-xl shadow">
<h2 class="text-gray-500">Blight</h2>
<p class="text-4xl font-bold text-yellow-600 mt-2">
{{ $blight }}
</p>
</div>
<div class="bg-white p-6 rounded-xl shadow">
<h2 class="text-gray-500">Healthy</h2>
<p class="text-4xl font-bold text-green-600 mt-2">
{{ $healthy }}
</p>
</div>
<div class="bg-white p-6 rounded-xl shadow">
<h2 class="text-gray-500">Tungro</h2>
<p class="text-4xl font-bold text-orange-600 mt-2">
{{ $tungro }}
</p>
</div>
@section('content')
<div class="max-w-7xl mx-auto px-6 py-10">
<div class="mb-10">
<h1 class="text-3xl font-extrabold text-gray-800">Dashboard Overview</h1>
<p class="text-gray-500 mt-2">Ringkasan data klasifikasi dan performa model Artificial Intelligence.</p>
</div>
<!-- Evaluasi Model -->
<div class="grid md:grid-cols-4 gap-6 mb-10">
<div class="bg-white p-6 rounded-2xl shadow">
<h2 class="text-gray-500 mb-2">Accuracy</h2>
<p class="text-4xl font-bold text-green-600">
96%
</p>
<div class="grid grid-cols-2 md:grid-cols-5 gap-6 mb-10">
@foreach(['Total Prediksi' => [$totalPrediksi, 'blue'], 'Blast' => [$blast, 'red'], 'Blight' => [$blight, 'yellow'], 'Healthy' => [$healthy, 'green'], 'Tungro' => [$tungro, 'orange']] as $label => $data)
<div class="bg-white p-6 rounded-2xl shadow-sm border border-gray-100 hover:shadow-md transition-shadow group relative overflow-hidden">
<div class="absolute -right-6 -top-6 bg-{{$data[1]}}-50 w-20 h-20 rounded-full"></div>
<h2 class="text-sm font-semibold text-gray-400 uppercase tracking-wider relative z-10">{{ $label }}</h2>
<p class="text-4xl font-extrabold text-{{$data[1]}}-500 mt-2 relative z-10">{{ $data[0] }}</p>
</div>
<div class="bg-white p-6 rounded-2xl shadow">
<h2 class="text-gray-500 mb-2">Precision</h2>
<p class="text-4xl font-bold text-blue-600">
95%
</p>
</div>
<div class="bg-white p-6 rounded-2xl shadow">
<h2 class="text-gray-500 mb-2">Recall</h2>
<p class="text-4xl font-bold text-yellow-500">
94%
</p>
</div>
<div class="bg-white p-6 rounded-2xl shadow">
<h2 class="text-gray-500 mb-2">F1-Score</h2>
<p class="text-4xl font-bold text-red-500">
95%
</p>
</div>
@endforeach
</div>
<!-- Chart -->
<div class="bg-white p-6 rounded-xl shadow mb-10">
<h2 class="text-2xl font-bold mb-6 text-green-700">
Statistik Penyakit
</h2>
<canvas id="chartPenyakit"></canvas>
<div class="grid lg:grid-cols-2 gap-10 mb-10">
<div class="bg-white p-8 rounded-3xl shadow-sm border border-gray-100">
<h2 class="text-xl font-bold text-gray-800 mb-6">Statistik Penyakit</h2>
<div class="h-64"><canvas id="chartPenyakit"></canvas></div>
</div>
<div class="bg-white p-8 rounded-3xl shadow-sm border border-gray-100">
<h2 class="text-xl font-bold text-gray-800 mb-6">Confusion Matrix</h2>
<div class="bg-gray-50 p-4 rounded-2xl border border-dashed border-gray-200">
<img src="https://miro.medium.com/v2/resize:fit:1200/1*Z54JgbS4DUwWSknhDCvNTQ.png" class="rounded-xl w-full">
</div>
</div>
</div>
<!-- Confusion Matrix -->
<div class="bg-white p-8 rounded-3xl shadow mb-10">
<h2 class="text-3xl font-bold text-green-700 mb-6">
Confusion Matrix
</h2>
<img src="https://miro.medium.com/v2/resize:fit:1200/1*Z54JgbS4DUwWSknhDCvNTQ.png"
class="rounded-2xl shadow-lg mx-auto">
<div class="mt-10">
<div class="flex justify-between items-center mb-6">
<h3 class="text-xl font-bold text-gray-800">Prediksi Terbaru</h3>
<a href="/riwayat" class="text-sm font-semibold text-green-600 hover:text-green-700">Lihat Semua </a>
</div>
<div class="bg-white rounded-2xl shadow-sm border border-gray-100 overflow-hidden">
<table class="w-full text-left border-collapse">
<thead class="bg-gray-50 text-gray-400 text-xs uppercase tracking-wider">
<tr>
<th class="px-6 py-4 font-semibold">Gambar</th>
<th class="px-6 py-4 font-semibold">Hasil Diagnosa</th>
<th class="px-6 py-4 font-semibold">Confidence</th>
<th class="px-6 py-4 font-semibold text-right">Tanggal</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-100">
@foreach($terbaru as $item)
<tr class="hover:bg-gray-50 transition-colors">
<td class="px-6 py-4"><img src="{{ asset('uploads/' . $item->gambar) }}" class="w-12 h-12 rounded-lg object-cover shadow-sm"></td>
<td class="px-6 py-4 font-bold text-gray-700">{{ $item->penyakit }}</td>
<td class="px-6 py-4"><span class="bg-green-50 text-green-600 px-3 py-1 rounded-lg text-sm font-bold">{{ $item->confidence }}%</span></td>
<td class="px-6 py-4 text-right text-gray-500 text-sm">{{ $item->created_at->format('d M Y, H:i') }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
<!-- Tabel -->
<div class="bg-white p-6 rounded-xl shadow">
<h2 class="text-2xl font-bold mb-6 text-green-700">
Prediksi Terbaru
</h2>
<table class="w-full">
<thead>
<tr class="bg-green-600 text-white">
<th class="p-3">Gambar</th>
<th class="p-3">Penyakit</th>
<th class="p-3">Confidence</th>
<th class="p-3">Tanggal</th>
</tr>
</thead>
<tbody>
@foreach($terbaru as $item)
<tr class="border-b text-center">
<td class="p-3">
<img src="{{ asset('uploads/' . $item->gambar) }}"
class="w-20 h-20 object-cover rounded mx-auto">
</td>
<td class="p-3 font-semibold">
{{ $item->penyakit }}
</td>
<td class="p-3">
{{ $item->confidence }}%
</td>
<td class="p-3">
{{ $item->created_at }}
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endsection
@push('scripts')
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
const ctx = document.getElementById('chartPenyakit');
new Chart(ctx, {
type: 'bar',
data: {
labels: ['Blast', 'Blight', 'Healthy', 'Tungro'],
datasets: [{
label: 'Jumlah Data',
data: [
{{ $blast }},
{{ $blight }},
{{ $healthy }},
{{ $tungro }}
],
borderWidth: 1
}]
},
options: {
responsive: true
}
});
new Chart(document.getElementById('chartPenyakit'), {
type: 'bar',
data: {
labels: ['Blast', 'Blight', 'Healthy', 'Tungro'],
datasets: [{
data: [{{ $blast }}, {{ $blight }}, {{ $healthy }}, {{ $tungro }}],
backgroundColor: ['#ef4444', '#eab308', '#22c55e', '#f97316'],
borderRadius: 6
}]
},
options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false } } }
});
</script>
</body>
</html>
@endpush

View File

@ -0,0 +1,95 @@
<!DOCTYPE html>
<html lang="en" class="scroll-smooth overflow-y-scroll">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@yield('title', 'Rice Leaf AI')</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
<script src="https://cdn.tailwindcss.com"></script>
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<script>
tailwind.config = {
theme: {
extend: {
fontFamily: { sans: ['Poppins', 'sans-serif'] },
}
}
}
</script>
@stack('styles')
</head>
<body class="bg-gray-50 font-sans text-gray-800 min-h-screen flex flex-col pt-[80px]">
<nav class="fixed top-0 left-0 right-0 w-full z-50 transition-all duration-300" x-data="{ open: false }">
<div class="max-w-6xl mx-auto px-4 py-3">
<div class="bg-white/70 backdrop-blur-xl border border-white/50 shadow-[0_8px_30px_rgb(0,0,0,0.04)] rounded-2xl px-6 h-[64px] flex items-center justify-between">
<a href="/" class="flex items-center gap-2">
<span class="text-lg font-extrabold text-gray-800">RiceLeaf<span class="text-green-600">AI</span></span>
</a>
<button @click="open = !open" class="md:hidden text-gray-600 focus:outline-none">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path x-show="!open" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7"></path>
<path x-show="open" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</button>
<div class="hidden md:flex items-center gap-1">
@php $menus = [['name' => 'Home', 'url' => '/'], ['name' => 'Dashboard', 'url' => '/dashboard'], ['name' => 'Riwayat', 'url' => '/riwayat'], ['name' => 'Informasi Penyakit', 'url' => '/penyakit']]; @endphp
@foreach($menus as $menu)
@if($menu['name'] === 'Home' || Auth::check())
<a href="{{ $menu['url'] }}" class="px-4 py-2 text-sm font-semibold rounded-xl transition-all {{ Request::is(ltrim($menu['url'], '/')) || (Request::is('/') && $menu['url'] == '/') ? 'bg-green-600 text-white' : 'text-gray-600 hover:bg-green-50' }}">
{{ $menu['name'] }}
</a>
@endif
@endforeach
</div>
<div class="hidden md:flex">
@auth
<form action="/logout" method="POST">@csrf <button type="submit" class="text-sm font-bold text-red-500">Logout</button></form>
@else
<a href="/login" class="bg-gray-900 text-white px-5 py-2 rounded-xl text-sm font-bold">Login</a>
@endauth
</div>
</div>
<div x-show="open"
x-transition:enter="transition ease-out duration-200"
x-transition:enter-start="opacity-0 -translate-y-4"
x-transition:enter-end="opacity-100 translate-y-0"
class="md:hidden mt-2 mx-4 bg-white/90 backdrop-blur-xl border border-gray-100 rounded-2xl p-4 shadow-xl">
<div class="flex flex-col gap-2">
@foreach($menus as $menu)
@if($menu['name'] === 'Home' || Auth::check())
<a href="{{ $menu['url'] }}" class="px-4 py-3 rounded-xl font-semibold {{ Request::is(ltrim($menu['url'], '/')) ? 'bg-green-600 text-white' : 'text-gray-600' }}">
{{ $menu['name'] }}
</a>
@endif
@endforeach
@auth
<form action="/logout" method="POST">@csrf <button type="submit" class="w-full text-left px-4 py-3 font-semibold text-red-600">Logout</button></form>
@else
<a href="/login" class="px-4 py-3 font-semibold text-gray-800">Login</a>
@endauth
</div>
</div>
</nav>
<main class="flex-grow w-full relative">
@yield('content')
</main>
<footer class="py-10 text-center text-gray-400 text-sm">
Sistem Klasifikasi Penyakit Daun Padi &copy; 2026
</footer>
@stack('scripts')
</body>
</html>

View File

@ -0,0 +1,57 @@
@extends('layouts.main')
@section('title', 'Login - Rice Leaf AI')
@section('content')
<div class="flex items-center justify-center min-h-[calc(100vh-76px)] px-6 py-12 relative overflow-hidden">
<!-- Latar Belakang Dekoratif -->
<div class="absolute top-10 left-10 w-64 h-64 bg-green-200 rounded-full blur-3xl opacity-30 animate-pulse-slow"></div>
<div class="absolute bottom-10 right-10 w-64 h-64 bg-blue-200 rounded-full blur-3xl opacity-30 animate-pulse-slow" style="animation-delay: 1s;"></div>
<div class="bg-white p-10 rounded-[2.5rem] shadow-2xl border border-gray-100 w-full max-w-md relative z-10 animate-fade-in-up">
<div class="text-center mb-8">
<div class="bg-green-50 w-16 h-16 rounded-2xl flex items-center justify-center mx-auto mb-4">
<svg class="w-8 h-8 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><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>
</div>
<h2 class="text-3xl font-extrabold text-gray-800">Selamat Datang</h2>
<p class="text-gray-500 mt-2 text-sm">Silakan login untuk mengakses sistem prediksi dan kelola data.</p>
</div>
@if(session('error'))
<div class="bg-red-50 border border-red-200 text-red-600 px-4 py-3 rounded-xl mb-6 text-sm font-medium flex items-center gap-2">
<svg class="w-5 h-5 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
{{ session('error') }}
</div>
@endif
<form action="/login" method="POST">
@csrf
<div class="mb-5">
<label for="email" class="block text-sm font-semibold text-gray-700 mb-2">Alamat Email</label>
<input type="email" name="email" id="email" required autofocus
class="w-full px-5 py-3 bg-gray-50 border border-gray-200 rounded-xl focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all outline-none text-gray-700"
placeholder="user@riceleaf.ai">
</div>
<div class="mb-8">
<label for="password" class="block text-sm font-semibold text-gray-700 mb-2">Password</label>
<input type="password" name="password" id="password" required
class="w-full px-5 py-3 bg-gray-50 border border-gray-200 rounded-xl focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all outline-none text-gray-700"
placeholder="••••••••">
</div>
<button type="submit" class="w-full bg-gradient-to-r from-green-600 to-green-500 hover:from-green-700 hover:to-green-600 text-white py-3.5 rounded-xl text-lg font-bold shadow-lg hover:shadow-xl hover:-translate-y-0.5 transition-all duration-300">
Masuk Sistem
</button>
</form>
<p class="text-center mt-6 text-sm text-gray-600 font-medium">
Belum punya akun?
<a href="/register" class="text-green-600 hover:text-green-700 hover:underline font-bold transition-all">Daftar di sini</a>
</p>
</div>
</div>
@endsection

View File

@ -1,124 +1,219 @@
<!DOCTYPE html>
<html>
<head>
<title>Informasi Penyakit Daun Padi</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
@extends('layouts.main')
<body class="bg-green-50">
@section('title', 'Informasi Penyakit Daun Padi - Rice Leaf AI')
<nav class="bg-green-700 text-white p-4">
<div class="max-w-7xl mx-auto flex justify-between">
<h1 class="font-bold text-2xl">
Rice Leaf AI
@section('content')
<div class="max-w-7xl mx-auto px-6 py-12 flex-grow">
<div class="text-center mb-16 animate-[fadeInUp_0.8s_ease-out_forwards]">
<span class="bg-green-100 text-green-700 px-4 py-1.5 rounded-full text-sm font-semibold mb-4 inline-block shadow-sm border border-green-200">
📚 Ensiklopedia Botani
</span>
<h1 class="text-4xl md:text-5xl font-extrabold text-gray-800 mb-4">
Informasi Penyakit Daun Padi
</h1>
<div class="space-x-3">
<a href="/" class="hover:underline">Beranda</a>
<a href="/dashboard" class="hover:underline">Dashboard</a>
<a href="/riwayat" class="hover:underline">Riwayat</a>
</div>
<p class="text-gray-500 max-w-2xl mx-auto text-lg">
Kenali lebih dalam berbagai jenis penyakit, penyebab, gejala, serta cara pengendalian yang tepat untuk menjaga kualitas panen Anda.
</p>
</div>
</nav>
<div class="max-w-7xl mx-auto p-10">
<div class="grid md:grid-cols-2 gap-10">
<h1 class="text-5xl font-bold text-center text-green-700 mb-12">
Informasi Penyakit Daun Padi
</h1>
<div class="group bg-white rounded-[2rem] shadow-lg hover:shadow-2xl border border-gray-100 overflow-hidden hover:-translate-y-2 transition-all duration-500 flex flex-col">
<div class="relative overflow-hidden h-64 shrink-0">
<img src="https://www.irri.org/sites/default/files/styles/large/public/blast-rice.jpg"
class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700">
<div class="absolute inset-0 bg-gradient-to-t from-black/50 to-transparent"></div>
<div class="absolute bottom-6 left-6">
<span class="bg-red-500/90 backdrop-blur text-white px-3 py-1 rounded-lg text-xs font-bold uppercase tracking-wider mb-2 inline-block">Fungi</span>
<h2 class="text-4xl font-extrabold text-white drop-shadow-md">
Blast
</h2>
</div>
</div>
<div class="grid md:grid-cols-2 gap-8">
<div class="p-8 flex-grow">
<div class="grid gap-4 h-full">
<div class="bg-red-50/50 p-4 rounded-2xl border border-red-100">
<h3 class="font-bold text-red-700 flex items-center gap-2 mb-2">
<span class="text-xl">🦠</span> Penyebab
</h3>
<p class="text-gray-700 text-sm">Jamur <i class="font-semibold">Pyricularia oryzae</i></p>
</div>
<!-- Blast -->
<div class="bg-white p-8 rounded-3xl shadow-lg">
<h2 class="text-3xl font-bold text-red-600 mb-4">
Blast
</h2>
<div class="bg-blue-50/50 p-4 rounded-2xl border border-blue-100">
<h3 class="font-bold text-blue-700 flex items-center gap-2 mb-2">
<span class="text-xl">🔍</span> Gejala
</h3>
<ul class="list-none text-gray-700 text-sm space-y-1">
<li class="flex items-center gap-2"><span class="w-1.5 h-1.5 bg-blue-400 rounded-full"></span> Bercak berbentuk belah ketupat</li>
<li class="flex items-center gap-2"><span class="w-1.5 h-1.5 bg-blue-400 rounded-full"></span> Warna abu-abu kecoklatan</li>
<li class="flex items-center gap-2"><span class="w-1.5 h-1.5 bg-blue-400 rounded-full"></span> Daun mengering dari ujung</li>
</ul>
</div>
<p class="mb-4">
Penyakit yang disebabkan oleh jamur
<b>Pyricularia oryzae</b>.
</p>
<div class="grid grid-cols-2 gap-4">
<div class="bg-yellow-50/50 p-4 rounded-2xl border border-yellow-100">
<h3 class="font-bold text-yellow-700 flex items-center gap-2 mb-2 text-sm">
<span>⚠️</span> Dampak
</h3>
<p class="text-gray-700 text-xs leading-relaxed">Menurunkan hasil panen secara signifikan.</p>
</div>
<p class="mb-4">
Gejala:
</p>
<ul class="list-disc ml-5">
<li>Bercak berbentuk belah ketupat</li>
<li>Warna coklat keabu-abuan</li>
<li>Daun mengering</li>
</ul>
<p class="mt-4">
Solusi:
Gunakan fungisida dan varietas tahan penyakit.
</p>
<div class="bg-green-50/50 p-4 rounded-2xl border border-green-100">
<h3 class="font-bold text-green-700 flex items-center gap-2 mb-2 text-sm">
<span>💊</span> Pengendalian
</h3>
<p class="text-gray-700 text-xs leading-relaxed">Gunakan fungisida dan varietas tahan penyakit.</p>
</div>
</div>
</div>
</div>
</div>
<!-- Blight -->
<div class="bg-white p-8 rounded-3xl shadow-lg">
<h2 class="text-3xl font-bold text-yellow-600 mb-4">
Blight
</h2>
<div class="group bg-white rounded-[2rem] shadow-lg hover:shadow-2xl border border-gray-100 overflow-hidden hover:-translate-y-2 transition-all duration-500 flex flex-col">
<div class="relative overflow-hidden h-64 shrink-0">
<img src="https://www.knowledgebank.irri.org/images/stories/xbacterial-blight.jpg.pagespeed.ic.y.jpg"
class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700">
<div class="absolute inset-0 bg-gradient-to-t from-black/50 to-transparent"></div>
<div class="absolute bottom-6 left-6">
<span class="bg-yellow-500/90 backdrop-blur text-white px-3 py-1 rounded-lg text-xs font-bold uppercase tracking-wider mb-2 inline-block">Bakteri</span>
<h2 class="text-4xl font-extrabold text-white drop-shadow-md">
Blight
</h2>
</div>
</div>
<p class="mb-4">
Penyakit bakteri yang menyebabkan hawar daun.
</p>
<div class="p-8 flex-grow">
<div class="grid gap-4 h-full">
<div class="bg-red-50/50 p-4 rounded-2xl border border-red-100">
<h3 class="font-bold text-red-700 flex items-center gap-2 mb-2">
<span class="text-xl">🦠</span> Penyebab
</h3>
<p class="text-gray-700 text-sm">Bakteri <i class="font-semibold">Xanthomonas oryzae</i></p>
</div>
<ul class="list-disc ml-5">
<li>Daun menguning</li>
<li>Tepi daun mengering</li>
<li>Pertumbuhan terganggu</li>
</ul>
<div class="bg-blue-50/50 p-4 rounded-2xl border border-blue-100">
<h3 class="font-bold text-blue-700 flex items-center gap-2 mb-2">
<span class="text-xl">🔍</span> Gejala
</h3>
<ul class="list-none text-gray-700 text-sm space-y-1">
<li class="flex items-center gap-2"><span class="w-1.5 h-1.5 bg-blue-400 rounded-full"></span> Daun menguning secara masif</li>
<li class="flex items-center gap-2"><span class="w-1.5 h-1.5 bg-blue-400 rounded-full"></span> Tepi daun mengering cepat</li>
<li class="flex items-center gap-2"><span class="w-1.5 h-1.5 bg-blue-400 rounded-full"></span> Pertumbuhan tanaman terhambat</li>
</ul>
</div>
<p class="mt-4">
Solusi:
Gunakan benih sehat dan sanitasi lahan.
</p>
<div class="grid grid-cols-2 gap-4">
<div class="bg-yellow-50/50 p-4 rounded-2xl border border-yellow-100">
<h3 class="font-bold text-yellow-700 flex items-center gap-2 mb-2 text-sm">
<span>⚠️</span> Dampak
</h3>
<p class="text-gray-700 text-xs leading-relaxed">Penurunan produktivitas tanaman drastis.</p>
</div>
<div class="bg-green-50/50 p-4 rounded-2xl border border-green-100">
<h3 class="font-bold text-green-700 flex items-center gap-2 mb-2 text-sm">
<span>💊</span> Pengendalian
</h3>
<p class="text-gray-700 text-xs leading-relaxed">Gunakan benih sehat dan sanitasi lahan rutin.</p>
</div>
</div>
</div>
</div>
</div>
<!-- Tungro -->
<div class="bg-white p-8 rounded-3xl shadow-lg">
<h2 class="text-3xl font-bold text-orange-500 mb-4">
Tungro
</h2>
<div class="group bg-white rounded-[2rem] shadow-lg hover:shadow-2xl border border-gray-100 overflow-hidden hover:-translate-y-2 transition-all duration-500 flex flex-col">
<div class="relative overflow-hidden h-64 shrink-0">
<img src="https://www.knowledgebank.irri.org/images/stories/tungro-rice.jpg"
class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700">
<div class="absolute inset-0 bg-gradient-to-t from-black/50 to-transparent"></div>
<div class="absolute bottom-6 left-6">
<span class="bg-orange-500/90 backdrop-blur text-white px-3 py-1 rounded-lg text-xs font-bold uppercase tracking-wider mb-2 inline-block">Virus</span>
<h2 class="text-4xl font-extrabold text-white drop-shadow-md">
Tungro
</h2>
</div>
</div>
<p class="mb-4">
Penyakit virus yang ditularkan oleh wereng hijau.
</p>
<div class="p-8 flex-grow">
<div class="grid gap-4 h-full">
<div class="bg-red-50/50 p-4 rounded-2xl border border-red-100">
<h3 class="font-bold text-red-700 flex items-center gap-2 mb-2">
<span class="text-xl">🦠</span> Penyebab
</h3>
<p class="text-gray-700 text-sm">Virus Tungro <span class="text-gray-500">(ditularkan wereng hijau)</span></p>
</div>
<ul class="list-disc ml-5">
<li>Daun menguning</li>
<li>Tanaman kerdil</li>
<li>Produksi menurun</li>
</ul>
<div class="bg-blue-50/50 p-4 rounded-2xl border border-blue-100">
<h3 class="font-bold text-blue-700 flex items-center gap-2 mb-2">
<span class="text-xl">🔍</span> Gejala
</h3>
<ul class="list-none text-gray-700 text-sm space-y-1">
<li class="flex items-center gap-2"><span class="w-1.5 h-1.5 bg-blue-400 rounded-full"></span> Daun menguning oranye terang</li>
<li class="flex items-center gap-2"><span class="w-1.5 h-1.5 bg-blue-400 rounded-full"></span> Tanaman menjadi kerdil</li>
<li class="flex items-center gap-2"><span class="w-1.5 h-1.5 bg-blue-400 rounded-full"></span> Malai tidak berkembang baik</li>
</ul>
</div>
<p class="mt-4">
Solusi:
Kendalikan populasi wereng dan gunakan varietas tahan.
</p>
<div class="grid grid-cols-2 gap-4">
<div class="bg-yellow-50/50 p-4 rounded-2xl border border-yellow-100">
<h3 class="font-bold text-yellow-700 flex items-center gap-2 mb-2 text-sm">
<span>⚠️</span> Dampak
</h3>
<p class="text-gray-700 text-xs leading-relaxed">Gagal panen jika tidak dikendalikan dini.</p>
</div>
<div class="bg-green-50/50 p-4 rounded-2xl border border-green-100">
<h3 class="font-bold text-green-700 flex items-center gap-2 mb-2 text-sm">
<span>💊</span> Pengendalian
</h3>
<p class="text-gray-700 text-xs leading-relaxed">Kendalikan wereng dan pakai varietas tahan.</p>
</div>
</div>
</div>
</div>
</div>
<!-- Healthy -->
<div class="bg-white p-8 rounded-3xl shadow-lg">
<h2 class="text-3xl font-bold text-green-600 mb-4">
Healthy
</h2>
<div class="group bg-white rounded-[2rem] shadow-lg hover:shadow-2xl border border-green-200 overflow-hidden hover:-translate-y-2 transition-all duration-500 flex flex-col relative">
<div class="absolute top-6 right-6 z-10 bg-white/90 backdrop-blur px-4 py-2 rounded-full text-green-600 font-bold shadow-md flex items-center gap-2">
<svg class="w-5 h-5" 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>
Kondisi Optimal
</div>
<p>
Daun padi sehat berwarna hijau segar,
tidak terdapat bercak ataupun gejala penyakit.
</p>
<div class="relative overflow-hidden h-64 shrink-0">
<img src="https://www.knowledgebank.irri.org/images/stories/healthy-rice.jpg"
class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700">
<div class="absolute inset-0 bg-gradient-to-t from-black/50 to-transparent"></div>
<div class="absolute bottom-6 left-6">
<span class="bg-green-500/90 backdrop-blur text-white px-3 py-1 rounded-lg text-xs font-bold uppercase tracking-wider mb-2 inline-block">Normal</span>
<h2 class="text-4xl font-extrabold text-white drop-shadow-md">
Healthy
</h2>
</div>
</div>
<p class="mt-4">
Pertahankan pemupukan dan pengairan yang baik.
</p>
<div class="p-8 flex-grow flex flex-col justify-center">
<div class="bg-green-50/50 p-6 rounded-3xl border border-green-100 mb-6">
<h3 class="font-bold text-gray-800 text-lg mb-3 flex items-center gap-2">
<span>🌿</span> Deskripsi Fisik
</h3>
<p class="text-gray-600 leading-relaxed">
Tanaman padi yang sehat memiliki daun hijau segar merata, warna yang cerah, tanpa adanya bercak, dan terbebas dari gejala penyakit atau serangan hama. Tekstur daun normal dan pertumbuhan optimal.
</p>
</div>
<div class="bg-blue-50/50 p-6 rounded-3xl border border-blue-100">
<h3 class="font-bold text-blue-800 text-lg mb-3 flex items-center gap-2">
<span>💡</span> Rekomendasi Perawatan
</h3>
<p class="text-gray-600 leading-relaxed">
Untuk mempertahankan kondisi ini, pastikan menjaga pemupukan yang seimbang, manajemen irigasi air yang cukup, serta melakukan pengecekan dan pengendalian hama secara rutin.
</p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
@endsection

View File

@ -0,0 +1,73 @@
@extends('layouts.main')
@section('title', 'Daftar Akun - Rice Leaf AI')
@section('content')
<div class="flex items-center justify-center min-h-[calc(100vh-76px)] px-6 py-12 relative overflow-hidden">
<div class="absolute top-10 right-10 w-64 h-64 bg-green-200 rounded-full blur-3xl opacity-30 animate-pulse-slow"></div>
<div class="absolute bottom-10 left-10 w-64 h-64 bg-yellow-200 rounded-full blur-3xl opacity-30 animate-pulse-slow" style="animation-delay: 1s;"></div>
<div class="bg-white p-10 rounded-[2.5rem] shadow-2xl border border-gray-100 w-full max-w-md relative z-10 animate-fade-in-up">
<div class="text-center mb-8">
<div class="bg-green-50 w-16 h-16 rounded-2xl flex items-center justify-center mx-auto mb-4">
<svg class="w-8 h-8 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M18 9v3m0 0v3m0-3h3m-3 0h-3m-2-5a4 4 0 11-8 0 4 4 0 018 0zM3 20a6 6 0 0112 0v1H3v-1z"></path></svg>
</div>
<h2 class="text-3xl font-extrabold text-gray-800">Buat Akun Baru</h2>
<p class="text-gray-500 mt-2 text-sm">Bergabunglah untuk mulai mengelola prediksi AI.</p>
</div>
<form action="/register" method="POST">
@csrf
<div class="mb-4">
<label for="name" class="block text-sm font-semibold text-gray-700 mb-2">Nama Lengkap</label>
<input type="text" name="name" id="name" required autofocus value="{{ old('name') }}"
class="w-full px-5 py-3 bg-gray-50 border border-gray-200 rounded-xl focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all outline-none text-gray-700 @error('name') border-red-500 @enderror"
placeholder="Masukkan nama Anda">
@error('name')
<p class="text-red-500 text-xs mt-1">{{ $message }}</p>
@enderror
</div>
<div class="mb-4">
<label for="email" class="block text-sm font-semibold text-gray-700 mb-2">Alamat Email</label>
<input type="email" name="email" id="email" required value="{{ old('email') }}"
class="w-full px-5 py-3 bg-gray-50 border border-gray-200 rounded-xl focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all outline-none text-gray-700 @error('email') border-red-500 @enderror"
placeholder="user@riceleaf.ai">
@error('email')
<p class="text-red-500 text-xs mt-1">{{ $message }}</p>
@enderror
</div>
<div class="mb-4">
<label for="password" class="block text-sm font-semibold text-gray-700 mb-2">Password</label>
<input type="password" name="password" id="password" required
class="w-full px-5 py-3 bg-gray-50 border border-gray-200 rounded-xl focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all outline-none text-gray-700 @error('password') border-red-500 @enderror"
placeholder="Minimal 5 karakter">
@error('password')
<p class="text-red-500 text-xs mt-1">{{ $message }}</p>
@enderror
</div>
<div class="mb-8">
<label for="password_confirmation" class="block text-sm font-semibold text-gray-700 mb-2">Konfirmasi Password</label>
<input type="password" name="password_confirmation" id="password_confirmation" required
class="w-full px-5 py-3 bg-gray-50 border border-gray-200 rounded-xl focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all outline-none text-gray-700"
placeholder="Ulangi password">
</div>
<button type="submit" class="w-full bg-gradient-to-r from-green-600 to-green-500 hover:from-green-700 hover:to-green-600 text-white py-3.5 rounded-xl text-lg font-bold shadow-lg hover:shadow-xl hover:-translate-y-0.5 transition-all duration-300">
Daftar Sekarang
</button>
</form>
<p class="text-center mt-6 text-sm text-gray-600 font-medium">
Sudah punya akun?
<a href="/login" class="text-green-600 hover:text-green-700 hover:underline font-bold transition-all">Login di sini</a>
</p>
</div>
</div>
@endsection

View File

@ -1,231 +1,188 @@
<!DOCTYPE html>
<html>
<head>
<title>Riwayat Prediksi</title>
@extends('layouts.main')
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-green-50 p-10">
@section('title', 'Riwayat Prediksi AI - Rice Leaf AI')
<div class="max-w-6xl mx-auto bg-white p-8 rounded-xl shadow">
<div class="flex justify-between items-center mb-6">
<h1 class="text-3xl font-bold text-green-700">
<a href="/export-pdf"
class="bg-red-600 text-white px-4 py-2 rounded">
Download PDF
</a>
Riwayat Prediksi
</h1>
<form method="GET"
class="flex flex-col md:flex-row gap-4 my-6">
<!-- Search -->
<input type="text"
name="search"
placeholder="Cari penyakit..."
value="{{ request('search') }}"
class="border border-gray-300 rounded-xl px-4 py-3 w-full">
<!-- Filter -->
<select name="filter"
class="border border-gray-300 rounded-xl px-4 py-3">
<option value="">Semua Penyakit</option>
<option value="Blast"
{{ request('filter') == 'Blast' ? 'selected' : '' }}>
Blast
</option>
<option value="Blight"
{{ request('filter') == 'Blight' ? 'selected' : '' }}>
Blight
</option>
<option value="Tungro"
{{ request('filter') == 'Tungro' ? 'selected' : '' }}>
Tungro
</option>
<option value="Healthy"
{{ request('filter') == 'Healthy' ? 'selected' : '' }}>
Healthy
</option>
</select>
<button type="submit"
class="bg-green-600 hover:bg-green-700 text-white px-6 py-3 rounded-xl">
Cari
</button>
</form>
<a href="/"
class="bg-green-600 text-white px-4 py-2 rounded">
Kembali
</a>
@section('content')
<div class="max-w-7xl mx-auto px-6 py-10">
<div class="bg-white p-8 rounded-3xl shadow-sm border border-gray-100">
<div class="flex flex-col md:flex-row justify-between items-start md:items-center mb-8 gap-4">
<div>
<h1 class="text-3xl font-extrabold text-gray-800">
Riwayat Prediksi
</h1>
<p class="text-gray-500 mt-1 text-sm">Kelola dan pantau hasil klasifikasi daun padi yang telah dilakukan.</p>
</div>
<div class="flex gap-3">
<a href="/export-pdf" class="bg-red-50 text-red-600 hover:bg-red-600 hover:text-white px-5 py-2.5 rounded-xl font-semibold transition-all duration-300 flex items-center gap-2 border border-red-100 hover:border-transparent shadow-sm">
<svg class="w-5 h-5" 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-3m2 8H7a2 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>
Download PDF
</a>
</div>
</div>
<table class="w-full border-collapse">
<div class="bg-gray-50 p-4 rounded-2xl border border-gray-100 mb-8">
<form method="GET" class="flex flex-col md:flex-row gap-4">
<div class="relative flex-grow">
<div class="absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none">
<svg class="w-5 h-5 text-gray-400" 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 0z"></path></svg>
</div>
<input type="text"
name="search"
placeholder="Cari berdasarkan penyakit..."
value="{{ request('search') }}"
class="w-full pl-11 pr-4 py-3 bg-white border border-gray-200 rounded-xl focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-shadow outline-none text-gray-700 shadow-sm">
</div>
<thead>
<div class="md:w-48 shrink-0">
<select name="filter"
class="w-full px-4 py-3 bg-white border border-gray-200 rounded-xl focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-shadow outline-none text-gray-700 shadow-sm appearance-none cursor-pointer">
<option value="">Semua Penyakit</option>
<option value="Blast" {{ request('filter') == 'Blast' ? 'selected' : '' }}>Blast</option>
<option value="Blight" {{ request('filter') == 'Blight' ? 'selected' : '' }}>Blight</option>
<option value="Tungro" {{ request('filter') == 'Tungro' ? 'selected' : '' }}>Tungro</option>
<option value="Healthy" {{ request('filter') == 'Healthy' ? 'selected' : '' }}>Healthy</option>
</select>
</div>
<tr class="bg-green-600 text-white">
<button type="submit"
class="bg-green-600 hover:bg-green-700 text-white px-8 py-3 rounded-xl font-semibold transition-all duration-300 shadow-md hover:shadow-lg flex items-center justify-center gap-2 shrink-0">
Cari Data
</button>
</form>
</div>
<th class="p-3">No</th>
<th class="p-3">Gambar</th>
<th class="p-3">Penyakit</th>
<th class="p-3">Confidence</th>
<th class="p-3">Tanggal</th>
<th class="p-3">Aksi</th>
<div class="overflow-x-auto rounded-2xl border border-gray-100">
<table class="w-full whitespace-nowrap">
<thead class="bg-gray-50 border-b border-gray-100 text-gray-500 text-xs uppercase tracking-wider font-semibold text-center">
<tr>
<th class="p-4 w-16">No</th>
<th class="p-4 text-left">Gambar</th>
<th class="p-4">Penyakit</th>
<th class="p-4">Confidence</th>
<th class="p-4">Tanggal</th>
<th class="p-4">Aksi</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-50 text-center">
@foreach($data as $item)
<tr class="hover:bg-green-50/30 transition-colors group">
<td class="p-4 text-gray-500 font-medium">
{{ $loop->iteration }}
</td>
<td class="p-4 text-left">
<img src="{{ asset('uploads/' . $item->gambar) }}"
class="w-20 h-20 object-cover rounded-xl shadow-sm border border-gray-200 group-hover:scale-105 transition-transform duration-300">
</td>
</tr>
<td class="p-4">
@if($item->penyakit == 'Blast')
<span class="inline-flex items-center justify-center bg-red-50 text-red-600 px-4 py-1.5 rounded-lg font-bold border border-red-100">
Blast
</span>
@elseif($item->penyakit == 'Blight')
<span class="inline-flex items-center justify-center bg-yellow-50 text-yellow-600 px-4 py-1.5 rounded-lg font-bold border border-yellow-100">
Blight
</span>
@elseif($item->penyakit == 'Tungro')
<span class="inline-flex items-center justify-center bg-orange-50 text-orange-600 px-4 py-1.5 rounded-lg font-bold border border-orange-100">
Tungro
</span>
@else
<span class="inline-flex items-center justify-center bg-green-50 text-green-600 px-4 py-1.5 rounded-lg font-bold border border-green-100">
Healthy
</span>
@endif
</td>
</thead>
<td class="p-4">
<span class="font-bold text-gray-700">{{ $item->confidence }}%</span>
</td>
<tbody>
<td class="p-4 text-sm text-gray-500">
{{ $item->created_at }}
</td>
@foreach($data as $item)
<tr class="border-b text-center">
<td class="p-3">
{{ $loop->iteration }}
</td>
<td class="p-3">
<img src="{{ asset('uploads/' . $item->gambar) }}"
class="w-24 h-24 object-cover rounded mx-auto">
</td>
<td class="p-3">
@if($item->penyakit == 'Blast')
<span class="bg-red-100 text-red-700 px-4 py-2 rounded-full font-semibold">
Blast
</span>
@elseif($item->penyakit == 'Blight')
<span class="bg-yellow-100 text-yellow-700 px-4 py-2 rounded-full font-semibold">
Blight
</span>
@elseif($item->penyakit == 'Tungro')
<span class="bg-orange-100 text-orange-700 px-4 py-2 rounded-full font-semibold">
Tungro
</span>
@else
<span class="bg-green-100 text-green-700 px-4 py-2 rounded-full font-semibold">
Healthy
</span>
@endif
</td>
<td class="p-3">
{{ $item->confidence }}%
</td>
<td class="p-3">
{{ $item->created_at }}
</td>
<td class="p-3">
<form action="/hapus/{{ $item->id }}"
method="POST"
class="formHapus">>
@csrf
@method('DELETE')
<button type="submit"
class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg">
Hapus
</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
<td class="p-4">
<form action="/hapus/{{ $item->id }}" method="POST" class="formHapus inline-block">
@csrf
@method('DELETE')
<button type="submit"
class="bg-white border border-red-200 text-red-500 hover:bg-red-50 hover:text-red-600 px-4 py-2 rounded-xl text-sm font-semibold transition-all duration-300 flex items-center gap-2 mx-auto">
<svg class="w-4 h-4" 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>
</td>
</tr>
@endforeach
@if($data->isEmpty())
<tr>
<td colspan="6" class="p-10 text-center text-gray-400 font-medium">
Belum ada data riwayat prediksi.
</td>
</tr>
@endif
</tbody>
</table>
</div>
</div>
</div>
@endsection
@push('scripts')
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
@if(session('success'))
<script>
Swal.fire({
icon: 'success',
title: 'Berhasil!',
text: '{{ session('success') }}',
timer: 2000,
showConfirmButton: false
});
</script>
@endif
<script>
const forms = document.querySelectorAll('.formHapus');
forms.forEach(form => {
form.addEventListener('submit', function(e) {
e.preventDefault();
Swal.fire({
title: 'Yakin?',
text: "Data prediksi akan dihapus!",
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#16a34a',
cancelButtonColor: '#dc2626',
confirmButtonText: 'Ya, Hapus!',
cancelButtonText: 'Batal'
}).then((result) => {
if (result.isConfirmed) {
form.submit();
}
});
Swal.fire({
icon: 'success',
title: 'Berhasil!',
text: '{{ session('success') }}',
timer: 2000,
showConfirmButton: false,
customClass: {
popup: 'rounded-3xl'
}
});
});
</script>
</body>
</html>
@endif
<script>
const forms = document.querySelectorAll('.formHapus');
forms.forEach(form => {
form.addEventListener('submit', function(e) {
e.preventDefault();
Swal.fire({
title: 'Yakin ingin menghapus?',
text: "Data prediksi ini tidak dapat dikembalikan!",
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#16a34a',
cancelButtonColor: '#ef4444',
confirmButtonText: 'Ya, Hapus!',
cancelButtonText: 'Batal',
customClass: {
popup: 'rounded-3xl',
confirmButton: 'rounded-xl px-6 py-2.5 font-semibold',
cancelButton: 'rounded-xl px-6 py-2.5 font-semibold'
}
}).then((result) => {
if (result.isConfirmed) {
form.submit();
}
});
});
});
</script>
@endpush
```

View File

@ -1,445 +1,300 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Klasifikasi Penyakit Daun Padi</title>
@extends('layouts.main')
<script src="https://cdn.tailwindcss.com"></script>
</head>
@section('title', 'Klasifikasi Penyakit Daun Padi - Rice Leaf AI')
<body id="body"
class="bg-gradient-to-br from-green-100 to-green-50 min-h-screen transition-all duration-500">
@push('styles')
<style>
/* CSS murni untuk memastikan animasi berjalan lancar tanpa bentrok config global */
@keyframes fadeInUp {
0% { opacity: 0; transform: translateY(20px); }
100% { opacity: 1; transform: translateY(0); }
}
.animate-fade-in-up {
animation: fadeInUp 0.8s ease-out forwards;
}
@keyframes pulseSlow {
0%, 100% { opacity: 0.2; transform: scale(1); }
50% { opacity: 0.3; transform: scale(1.05); }
}
.animate-pulse-slow {
animation: pulseSlow 3s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
</style>
@endpush
<!-- Navbar -->
<nav class="bg-white shadow-md">
<div class="max-w-7xl mx-auto px-6 py-4 flex justify-between items-center">
<h1 class="text-2xl font-bold text-green-700">
Rice Leaf AI
</h1>
<div class="flex flex-col md:flex-row gap-4">
<a href="/dashboard"
class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-lg">
Dashboard
</a>
<a href="/riwayat"
class="bg-yellow-500 hover:bg-yellow-600 text-white px-4 py-2 rounded-lg">
Riwayat
</a>
<a href="/penyakit"
class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg">
Informasi Penyakit
</a>
<button onclick="toggleDarkMode()"
class="bg-gray-800 hover:bg-black text-white px-4 py-2 rounded-lg">
🌙 Dark Mode
</button>
@section('content')
<div class="bg-gradient-to-br from-green-100 via-white to-green-50 min-h-screen transition-all duration-500">
<section class="max-w-7xl mx-auto px-6 py-20 grid md:grid-cols-2 gap-12 items-center min-h-[80vh]">
<div class="animate-fade-in-up">
<div class="inline-block bg-green-100 text-green-700 px-4 py-1.5 rounded-full text-sm font-semibold mb-6 shadow-sm border border-green-200">
Deep Learning Technology
</div>
</div>
</nav>
<!-- Hero -->
<section class="max-w-7xl mx-auto px-6 py-16 grid md:grid-cols-2 gap-10 items-center">
<div>
<h1 class="text-5xl font-bold text-green-800 leading-tight mb-6">
Sistem Klasifikasi
Penyakit Daun Padi
Berbasis Artificial Intelligence
<h1 class="text-5xl lg:text-6xl font-extrabold text-transparent bg-clip-text bg-gradient-to-r from-green-900 to-green-600 leading-tight mb-6">
Sistem Klasifikasi<br>Penyakit Daun Padi<br>Berbasis AI
</h1>
<p class="text-lg text-gray-700 mb-8">
Deteksi penyakit daun padi secara otomatis menggunakan
teknologi Deep Learning berbasis website.
<p class="text-lg text-gray-600 mb-10 leading-relaxed max-w-lg">
Deteksi penyakit daun padi secara otomatis dan akurat menggunakan teknologi <strong>Deep Learning</strong> berbasis website. Cukup unggah foto, biarkan AI yang menganalisis.
</p>
<div class="flex gap-4">
<div class="flex flex-wrap gap-4">
<a href="#upload"
class="bg-green-600 hover:bg-green-700 text-white px-6 py-3 rounded-xl text-lg shadow-lg">
Mulai Prediksi
class="bg-gradient-to-r from-green-600 to-green-500 hover:from-green-700 hover:to-green-600 text-white px-8 py-4 rounded-2xl text-lg font-semibold shadow-xl hover:shadow-2xl transition-all duration-300 hover:-translate-y-1 flex items-center gap-2">
🎯 Mulai Prediksi
</a>
<a href="/dashboard"
class="bg-white border border-green-600 text-green-700 px-6 py-3 rounded-xl text-lg">
Lihat Dashboard
class="bg-white border-2 border-green-500 text-green-600 hover:bg-green-50 px-8 py-4 rounded-2xl text-lg font-semibold transition-all duration-300 hover:-translate-y-1 flex items-center gap-2">
📊 Lihat Dashboard
</a>
</div>
</div>
<div>
<div class="relative animate-fade-in-up" style="animation-delay: 0.2s;">
<div class="absolute inset-0 bg-green-400 rounded-3xl blur-3xl opacity-20 animate-pulse-slow"></div>
<img src="https://images.unsplash.com/photo-1625246333195-78d9c38ad449?q=80&w=1200&auto=format&fit=crop"
class="rounded-3xl shadow-2xl">
class="relative rounded-3xl shadow-2xl border-4 border-white transform hover:scale-[1.02] transition-transform duration-500 w-full object-cover h-[500px]">
</div>
</section>
<!-- Upload -->
<section id="upload" class="max-w-4xl mx-auto px-6 pb-20">
<div class="bg-white rounded-3xl shadow-2xl p-10">
<h2 class="text-3xl font-bold text-center text-green-700 mb-8">
Upload Gambar Daun Padi
</h2>
@if(session('success'))
<div class="bg-green-100 border border-green-300 text-green-700 p-4 rounded-xl mb-6">
{{ session('success') }}
</div>
@endif
@if(session('error'))
<div class="bg-red-100 border border-red-300 text-red-700 p-4 rounded-xl mb-6">
{{ session('error') }}
</div>
@endif
<form id="formPrediksi"
action="/prediksi"
method="POST"
enctype="multipart/form-data">
@csrf
<div class="border-2 border-dashed border-green-400 rounded-2xl p-10 text-center">
<input type="file"
name="gambar"
id="gambar"
accept="image/*"
onchange="previewImage(event)"
class="w-full border border-gray-300 rounded-xl p-3">
<div class="mt-6 text-center">
<img id="preview"
class="hidden mx-auto rounded-2xl shadow-lg w-64 h-64 object-cover">
</div>
<p class="text-gray-500 mt-6">
Upload gambar daun padi untuk diprediksi
</p>
<section id="upload" class="max-w-4xl mx-auto px-6 pb-24 pt-10">
<div class="bg-white/90 backdrop-blur-xl rounded-[2.5rem] shadow-2xl p-8 md:p-14 border border-white/50 relative overflow-hidden">
<div class="absolute top-0 right-0 w-40 h-40 bg-green-100 rounded-full blur-3xl opacity-50 -mr-20 -mt-20"></div>
<div class="absolute bottom-0 left-0 w-40 h-40 bg-blue-100 rounded-full blur-3xl opacity-50 -ml-20 -mb-20"></div>
<div class="relative z-10">
<div class="text-center mb-10">
<h2 class="text-4xl font-extrabold text-gray-800 mb-3">Upload Gambar Daun</h2>
<p class="text-gray-500">Pilih gambar daun padi yang ingin dianalisis dengan jelas</p>
</div>
<button type="submit"
id="btnPrediksi"
class="w-full mt-6 bg-green-600 hover:bg-green-700 text-white py-4 rounded-2xl text-xl font-semibold shadow-lg">
Prediksi Sekarang
</button>
</form>
<!-- Hasil Prediksi -->
@if(session('hasil'))
<div class="mt-10 bg-green-50 border border-green-200 rounded-3xl p-8">
<h2 class="text-3xl font-bold text-green-700 mb-6">
Hasil Prediksi
</h2>
<img src="{{ asset('uploads/' . session('gambar')) }}"
class="w-64 rounded-2xl shadow-lg mb-6 mx-auto">
<div class="grid md:grid-cols-2 gap-6">
<div class="bg-white p-6 rounded-2xl shadow">
<h3 class="text-lg text-gray-500 mb-2">
Penyakit
</h3>
<p class="text-3xl font-bold text-red-600">
{{ session('hasil') }}
</p>
</div>
<div class="bg-white p-6 rounded-2xl shadow">
<h3 class="text-lg text-gray-500 mb-2">
Confidence
</h3>
<p class="text-3xl font-bold text-green-700">
{{ session('confidence') }}%
</p>
</div>
@if(session('success'))
<div class="bg-green-50 border-l-4 border-green-500 text-green-800 p-4 rounded-r-xl mb-8 shadow-sm flex items-center gap-3">
<span></span> {{ session('success') }}
</div>
@endif
@if(session('allPredictions'))
<div class="bg-white p-6 rounded-2xl shadow mt-6">
<h3 class="text-2xl font-bold text-green-700 mb-4">
Probabilitas Semua Kelas
</h3>
@foreach(session('allPredictions') as $kelas => $nilai)
<div class="mb-4">
<div class="flex justify-between mb-1">
<span class="font-semibold">
{{ $kelas }}
</span>
<span>
{{ $nilai }}%
</span>
@if(session('error'))
<div class="bg-red-50 border-l-4 border-red-500 text-red-800 p-4 rounded-r-xl mb-8 shadow-sm flex items-center gap-3">
<span>⚠️</span> {{ session('error') }}
</div>
@endif
@auth
<form id="formPrediksi" action="/prediksi" method="POST" enctype="multipart/form-data">
@csrf
@else
<form action="/login" method="GET">
@endauth
<div class="group border-3 border-dashed border-green-300 hover:border-green-500 hover:bg-green-50/50 bg-gray-50 rounded-3xl p-10 text-center transition-all duration-300 relative cursor-pointer">
<div class="absolute inset-0 w-full h-full cursor-pointer z-20 opacity-0">
<input type="file" name="gambar" id="gambar" accept="image/*" onchange="previewImage(event)" class="w-full h-full cursor-pointer" {{ Auth::check() ? '' : 'disabled' }}>
</div>
<div class="w-full bg-gray-200 rounded-full h-4">
<div id="upload-placeholder" class="pointer-events-none">
<div class="bg-white w-20 h-20 rounded-full shadow-md flex items-center justify-center mx-auto mb-4 group-hover:scale-110 transition-transform duration-300">
@auth
<svg class="w-8 h-8 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12"></path></svg>
@else
<svg class="w-8 h-8 text-yellow-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><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>
@endauth
</div>
<h3 class="text-xl font-semibold text-gray-700">Drag & Drop atau Klik Disini</h3>
<p class="text-gray-400 mt-2 text-sm">Mendukung format JPG, PNG, JPEG</p>
</div>
<div class="bg-green-600 h-4 rounded-full"
style="width: {{ $nilai }}%">
<div class="mt-6 text-center pointer-events-none z-10 relative">
<img id="preview" class="hidden mx-auto rounded-2xl shadow-xl w-64 h-64 object-cover border-4 border-white">
</div>
</div>
<button type="submit" id="{{ Auth::check() ? 'btnPrediksi' : '' }}" class="w-full mt-8 bg-gradient-to-r from-green-600 to-green-500 hover:from-green-700 hover:to-green-600 text-white py-4 rounded-2xl text-xl font-bold shadow-lg hover:shadow-xl hover:-translate-y-1 transition-all duration-300 flex justify-center items-center gap-2 group">
@auth
<span>Prediksi Sekarang</span>
<svg class="w-6 h-6 group-hover:translate-x-1 transition-transform" 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>
@else
<span>Login untuk Memulai Prediksi</span>
<svg class="w-6 h-6 group-hover:translate-x-1 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3"></path></svg>
@endauth
</button>
</form>
@if(session('hasil'))
<div class="mt-12 bg-white/50 border border-green-100 rounded-[2rem] p-8 shadow-inner relative overflow-hidden">
<div class="absolute top-0 left-0 w-2 h-full bg-green-500"></div>
<h2 class="text-3xl font-extrabold text-gray-800 mb-8 text-center">
Hasil Analisis AI
</h2>
<img src="{{ asset('uploads/' . session('gambar')) }}" class="w-72 rounded-2xl shadow-xl mb-10 mx-auto border-4 border-white transform hover:scale-105 transition-transform duration-500">
<div class="grid md:grid-cols-2 gap-6">
<div class="bg-white p-6 rounded-2xl shadow-sm border border-gray-100 hover:shadow-md transition-shadow">
<h3 class="text-sm font-semibold text-gray-400 uppercase tracking-wider mb-1">Diagnosis Penyakit</h3>
<p class="text-3xl font-extrabold text-red-600 bg-red-50 inline-block px-4 py-1 rounded-lg mt-2">
{{ session('hasil') }}
</p>
</div>
<div class="bg-white p-6 rounded-2xl shadow-sm border border-gray-100 hover:shadow-md transition-shadow">
<h3 class="text-sm font-semibold text-gray-400 uppercase tracking-wider mb-1">Tingkat Kepercayaan (Confidence)</h3>
<p class="text-3xl font-extrabold text-green-600 mt-2 flex items-center gap-2">
{{ session('confidence') }}%
<svg class="w-8 h-8 text-green-500" 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>
</p>
</div>
</div>
@if(session('allPredictions'))
<div class="bg-white p-8 rounded-2xl shadow-sm border border-gray-100 mt-6">
<h3 class="text-xl font-bold text-gray-800 mb-6 flex items-center gap-2">
<svg class="w-6 h-6 text-blue-500" 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>
Probabilitas Semua Kelas
</h3>
@foreach(session('allPredictions') as $kelas => $nilai)
<div class="mb-5 group">
<div class="flex justify-between mb-2">
<span class="font-semibold text-gray-700 group-hover:text-green-600 transition-colors">{{ $kelas }}</span>
<span class="font-bold text-gray-900">{{ $nilai }}%</span>
</div>
<div class="w-full bg-gray-100 rounded-full h-3 overflow-hidden shadow-inner">
<div class="bg-gradient-to-r from-green-500 to-green-400 h-3 rounded-full relative transition-all duration-1000 ease-out" style="width: {{ $nilai }}%">
<div class="absolute top-0 right-0 bottom-0 left-0 bg-[url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4IiBoZWlnaHQ9IjgiPgo8cmVjdCB3aWR0aD0iOCIgaGVpZ2h0PSI4IiBmaWxsPSIjZmZmIiBmaWxsLW9wYWNpdHk9IjAuMSIvPgo8L3N2Zz4=')] opacity-50"></div>
</div>
</div>
</div>
@endforeach
</div>
@endif
@if(session('deskripsi'))
<div class="bg-white p-8 rounded-2xl shadow-sm border border-gray-100 mt-6">
<h3 class="text-xl font-bold text-gray-800 mb-6 flex items-center gap-2">
<svg class="w-6 h-6 text-yellow-500" 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"></path></svg>
Informasi Detail
</h3>
<div class="space-y-6">
<div class="bg-blue-50/50 p-5 rounded-xl border border-blue-100">
<h4 class="font-bold text-blue-800 mb-2">Deskripsi Penyakit:</h4>
<p class="text-gray-700 leading-relaxed">{{ session('deskripsi') }}</p>
</div>
<div class="bg-green-50/50 p-5 rounded-xl border border-green-100">
<h4 class="font-bold text-green-800 mb-2">Saran & Solusi:</h4>
<p class="text-gray-700 leading-relaxed">{{ session('solusi') }}</p>
</div>
</div>
</div>
@endforeach
@endif
</div>
@endif
@if(session('deskripsi'))
<div class="bg-white p-6 rounded-2xl shadow mt-6">
<h3 class="text-2xl font-bold text-green-700 mb-4">
Informasi Penyakit
</h3>
<p class="mb-4 text-gray-700">
<span class="font-bold">Deskripsi:</span><br>
{{ session('deskripsi') }}
</p>
<p class="text-gray-700">
<span class="font-bold">Solusi:</span><br>
{{ session('solusi') }}
</p>
</div>
@endif
</div>
@endif
</div>
</section>
<!-- Contoh Penyakit -->
<section class="max-w-7xl mx-auto px-6 pb-20">
<h2 class="text-4xl font-bold text-center text-green-700 mb-12">
Contoh Penyakit Daun Padi
</h2>
<div class="grid md:grid-cols-4 gap-8">
<div class="bg-white rounded-3xl shadow-xl overflow-hidden">
<img src="https://images.unsplash.com/photo-1592982537447-6f2a6a0f4d4d?q=80&w=1200&auto=format&fit=crop"
class="h-56 w-full object-cover">
<div class="p-5">
<h3 class="text-2xl font-bold text-red-600 mb-3">
Blast
</h3>
<p class="text-gray-600">
Penyakit akibat jamur yang menyerang daun padi.
</p>
</div>
</div>
<div class="bg-white rounded-3xl shadow-xl overflow-hidden">
<img src="https://images.unsplash.com/photo-1500382017468-9049fed747ef?q=80&w=1200&auto=format&fit=crop"
class="h-56 w-full object-cover">
<div class="p-5">
<h3 class="text-2xl font-bold text-yellow-600 mb-3">
Blight
</h3>
<p class="text-gray-600">
Hawar daun yang menyebabkan daun menguning.
</p>
</div>
</div>
<div class="bg-white rounded-3xl shadow-xl overflow-hidden">
<img src="https://images.unsplash.com/photo-1464226184884-fa280b87c399?q=80&w=1200&auto=format&fit=crop"
class="h-56 w-full object-cover">
<div class="p-5">
<h3 class="text-2xl font-bold text-orange-500 mb-3">
Tungro
</h3>
<p class="text-gray-600">
Penyakit virus yang ditularkan wereng hijau.
</p>
</div>
</div>
<div class="bg-white rounded-3xl shadow-xl overflow-hidden">
<img src="https://images.unsplash.com/photo-1472396961693-142e6e269027?q=80&w=1200&auto=format&fit=crop"
class="h-56 w-full object-cover">
<div class="p-5">
<h3 class="text-2xl font-bold text-green-600 mb-3">
Healthy
</h3>
<p class="text-gray-600">
Daun padi sehat tanpa gejala penyakit.
</p>
</div>
</div>
<section class="max-w-7xl mx-auto px-6 pb-24">
<div class="text-center mb-16">
<h2 class="text-4xl font-extrabold text-gray-800 mb-4">Galeri Penyakit Padi</h2>
<p class="text-gray-500 max-w-2xl mx-auto">Kenali berbagai jenis penyakit yang sering menyerang daun padi beserta gejalanya secara visual.</p>
</div>
<div class="grid md:grid-cols-2 lg:grid-cols-4 gap-8">
<div class="group bg-white rounded-3xl shadow-lg hover:shadow-2xl hover:-translate-y-2 transition-all duration-300 overflow-hidden border border-gray-100">
<div class="relative overflow-hidden">
<img src="https://images.unsplash.com/photo-1592982537447-6f2a6a0f4d4d?q=80&w=1200&auto=format&fit=crop" class="h-56 w-full object-cover group-hover:scale-110 transition-transform duration-700">
<div class="absolute top-4 right-4 bg-white/90 backdrop-blur-sm px-3 py-1 rounded-full text-xs font-bold text-red-600 shadow-sm">Bahaya</div>
</div>
<div class="p-6">
<h3 class="text-2xl font-bold text-gray-800 mb-3 group-hover:text-red-600 transition-colors">Blast</h3>
<p class="text-gray-500 text-sm leading-relaxed">Penyakit akibat jamur yang menyerang daun padi, ditandai dengan bercak belah ketupat.</p>
</div>
</div>
<div class="group bg-white rounded-3xl shadow-lg hover:shadow-2xl hover:-translate-y-2 transition-all duration-300 overflow-hidden border border-gray-100">
<div class="relative overflow-hidden">
<img src="https://images.unsplash.com/photo-1500382017468-9049fed747ef?q=80&w=1200&auto=format&fit=crop" class="h-56 w-full object-cover group-hover:scale-110 transition-transform duration-700">
<div class="absolute top-4 right-4 bg-white/90 backdrop-blur-sm px-3 py-1 rounded-full text-xs font-bold text-yellow-600 shadow-sm">Waspada</div>
</div>
<div class="p-6">
<h3 class="text-2xl font-bold text-gray-800 mb-3 group-hover:text-yellow-600 transition-colors">Blight</h3>
<p class="text-gray-500 text-sm leading-relaxed">Hawar daun bakteri yang menyebabkan daun menguning, mengering, dan mati dari ujungnya.</p>
</div>
</div>
<div class="group bg-white rounded-3xl shadow-lg hover:shadow-2xl hover:-translate-y-2 transition-all duration-300 overflow-hidden border border-gray-100">
<div class="relative overflow-hidden">
<img src="https://images.unsplash.com/photo-1464226184884-fa280b87c399?q=80&w=1200&auto=format&fit=crop" class="h-56 w-full object-cover group-hover:scale-110 transition-transform duration-700">
<div class="absolute top-4 right-4 bg-white/90 backdrop-blur-sm px-3 py-1 rounded-full text-xs font-bold text-orange-500 shadow-sm">Virus</div>
</div>
<div class="p-6">
<h3 class="text-2xl font-bold text-gray-800 mb-3 group-hover:text-orange-500 transition-colors">Tungro</h3>
<p class="text-gray-500 text-sm leading-relaxed">Penyakit virus yang ditularkan wereng hijau, menyebabkan tanaman kerdil dan daun kuning-oranye.</p>
</div>
</div>
<div class="group bg-white rounded-3xl shadow-lg hover:shadow-2xl hover:-translate-y-2 transition-all duration-300 overflow-hidden border border-gray-100">
<div class="relative overflow-hidden">
<img src="https://images.unsplash.com/photo-1472396961693-142e6e269027?q=80&w=1200&auto=format&fit=crop" class="h-56 w-full object-cover group-hover:scale-110 transition-transform duration-700">
<div class="absolute top-4 right-4 bg-white/90 backdrop-blur-sm px-3 py-1 rounded-full text-xs font-bold text-green-600 shadow-sm">Aman</div>
</div>
<div class="p-6">
<h3 class="text-2xl font-bold text-gray-800 mb-3 group-hover:text-green-600 transition-colors">Healthy</h3>
<p class="text-gray-500 text-sm leading-relaxed">Daun padi sehat tanpa gejala penyakit. Memiliki warna hijau merata dan tekstur normal.</p>
</div>
</div>
</div>
</section>
<!-- Footer -->
<footer class="bg-green-700 text-white py-6 text-center">
<p class="text-lg">
Sistem Klasifikasi Penyakit Daun Padi Berbasis AI
</p>
<p class="text-sm mt-2">
Politeknik Negeri Jember 2026
</p>
</footer>
<!-- Loading -->
<div id="loading"
class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div class="bg-white p-10 rounded-3xl shadow-2xl text-center">
<div class="animate-spin rounded-full h-20 w-20 border-b-4 border-green-700 mx-auto mb-6"></div>
<h2 class="text-2xl font-bold text-green-700">
AI Sedang Menganalisis...
</h2>
<p class="text-gray-500 mt-2">
Mohon tunggu sebentar
</p>
</div>
<div id="loading" class="hidden fixed inset-0 bg-gray-900/80 backdrop-blur-sm flex items-center justify-center z-50 transition-opacity">
<div class="bg-white p-12 rounded-[2rem] shadow-2xl text-center max-w-sm w-full mx-4 border border-gray-100 transform scale-100 animate-[fadeInUp_0.3s_ease-out]">
<div class="relative w-24 h-24 mx-auto mb-8">
<div class="absolute inset-0 rounded-full border-t-4 border-green-500 animate-spin"></div>
<div class="absolute inset-2 rounded-full border-r-4 border-blue-500 animate-[spin_1.5s_linear_infinite_reverse]"></div>
<div class="absolute inset-4 rounded-full border-b-4 border-yellow-400 animate-spin"></div>
</div>
<h2 class="text-2xl font-extrabold text-gray-800 mb-2">Menganalisis...</h2>
<p class="text-gray-500 font-medium">AI sedang memproses gambar Anda.</p>
</div>
</div>
@endsection
<script>
function previewImage(event)
{
const preview = document.getElementById('preview');
@push('scripts')
<script>
function previewImage(event) {
const preview = document.getElementById('preview');
const placeholder = document.getElementById('upload-placeholder');
if(event.target.files.length > 0){
preview.src = URL.createObjectURL(event.target.files[0]);
preview.classList.remove('hidden');
if(placeholder) placeholder.classList.add('hidden');
}
}
const form = document.getElementById('formPrediksi');
const form = document.getElementById('formPrediksi');
if(form){
form.addEventListener('submit', function() {
document.getElementById('loading')
.classList.remove('hidden');
document.getElementById('loading').classList.remove('hidden');
});
}
function toggleDarkMode()
{
const body = document.getElementById('body');
function toggleDarkMode() {
const body = document.getElementById('body');
if(body) {
body.classList.toggle('bg-gray-900');
body.classList.toggle('text-white');
body.classList.toggle('from-green-100');
body.classList.toggle('to-green-50');
body.classList.toggle('text-gray-800');
}
</script>
</body>
</html>
}
</script>
@endpush

View File

@ -2,12 +2,41 @@
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\KlasifikasiController;
use App\Http\Controllers\AuthController;
// ==========================================
// BISA DIAKSES SIAPA SAJA (TANPA LOGIN)
// ==========================================
Route::get('/', [KlasifikasiController::class, 'index']);
Route::post('/prediksi', [KlasifikasiController::class, 'prediksi']);
Route::get('/riwayat', [KlasifikasiController::class, 'riwayat']);
Route::get('/dashboard', [KlasifikasiController::class, 'dashboard']);
Route::get('/export-pdf', [KlasifikasiController::class, 'exportPdf']);
Route::delete('/hapus/{id}', [KlasifikasiController::class, 'hapus']);
Route::view('/penyakit', 'penyakit');
Route::get('/statistik', [KlasifikasiController::class, 'statistik']);
// ==========================================
// ROUTE UNTUK TAMU (BELUM LOGIN)
// ==========================================
// middleware('guest') memastikan orang yang sudah login tidak bisa ke halaman ini lagi
Route::middleware('guest')->group(function () {
// Jalur Login
Route::get('/login', [AuthController::class, 'index'])->name('login');
Route::post('/login', [AuthController::class, 'authenticate']);
// Jalur Registrasi
Route::get('/register', [AuthController::class, 'register']);
Route::post('/register', [AuthController::class, 'store']);
});
// ==========================================
// HANYA BISA DIAKSES JIKA SUDAH LOGIN
// ==========================================
// middleware('auth') memastikan hanya orang yang sudah login yang bisa ke sini
Route::middleware('auth')->group(function () {
// Jalur Logout
Route::post('/logout', [AuthController::class, 'logout']);
// Jalur Fitur AI & Klasifikasi
Route::post('/prediksi', [KlasifikasiController::class, 'prediksi']);
Route::get('/riwayat', [KlasifikasiController::class, 'riwayat']);
Route::get('/dashboard', [KlasifikasiController::class, 'dashboard']);
Route::get('/export-pdf', [KlasifikasiController::class, 'exportPdf']);
Route::delete('/hapus/{id}', [KlasifikasiController::class, 'hapus']);
Route::view('/penyakit', 'penyakit');
Route::get('/statistik', [KlasifikasiController::class, 'statistik']);
});