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\Http\Request;
use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Auth; // <-- WAJIB TAMBAH INI
use App\Models\Prediksi; use App\Models\Prediksi;
use Barryvdh\DomPDF\Facade\Pdf; use Barryvdh\DomPDF\Facade\Pdf;
@ -29,69 +30,43 @@ public function prediksi(Request $request)
} }
$namaFile = time() . '.' . $gambar->getClientOriginalExtension(); $namaFile = time() . '.' . $gambar->getClientOriginalExtension();
$gambar->move($uploadPath, $namaFile); $gambar->move($uploadPath, $namaFile);
$pathGambar = $uploadPath . DIRECTORY_SEPARATOR . $namaFile; $pathGambar = $uploadPath . DIRECTORY_SEPARATOR . $namaFile;
try { try {
$response = Http::timeout(60) $response = Http::timeout(60)
->attach( ->attach('gambar', file_get_contents($pathGambar), $namaFile)
'gambar',
file_get_contents($pathGambar),
$namaFile
)
->post('http://127.0.0.1:5000/prediksi'); ->post('http://127.0.0.1:5000/prediksi');
if (!$response->successful()) { if (!$response->successful()) {
Log::error('Server prediksi gagal', ['body' => $response->body()]);
Log::error('Server prediksi gagal', [ return back()->with('error', 'Tidak dapat memproses prediksi.');
'body' => $response->body()
]);
return back()->with([
'error' => 'Tidak dapat memproses prediksi.'
]);
} }
$hasil = $response->json(); $hasil = $response->json();
$allPredictions = $hasil['all_predictions'] ?? [];
$deskripsi = '';
$solusi = '';
// Logika deskripsi tetap sama
$deskripsi = ''; $solusi = '';
if ($hasil['penyakit'] == 'Blast') { 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.';
}
$deskripsi = 'Blast adalah penyakit daun padi akibat jamur Pyricularia oryzae yang menyebabkan bercak berbentuk belah ketupat.'; // SIMPAN DATA DENGAN USER_ID
$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.';
}
Prediksi::create([ Prediksi::create([
'gambar' => $namaFile, 'gambar' => $namaFile,
'penyakit' => $hasil['penyakit'], 'penyakit' => $hasil['penyakit'],
'confidence' => $hasil['confidence'] 'confidence' => $hasil['confidence'],
'user_id' => Auth::id(), // <-- INI YANG MEMBUAT PRIVAT
]); ]);
return back()->with([ return back()->with([
@ -101,26 +76,19 @@ public function prediksi(Request $request)
'confidence' => $hasil['confidence'] ?? 0, 'confidence' => $hasil['confidence'] ?? 0,
'deskripsi' => $deskripsi, 'deskripsi' => $deskripsi,
'solusi' => $solusi, 'solusi' => $solusi,
'allPredictions' => $allPredictions, 'allPredictions' => $hasil['all_predictions'] ?? [],
]); ]);
} catch (\Exception $e) { } catch (\Exception $e) {
Log::error('Prediksi request error: ' . $e->getMessage());
Log::error( return back()->with('error', 'Terjadi kesalahan server.');
'Prediksi request error: ' . $e->getMessage()
);
return back()->with([
'error' => 'Terjadi kesalahan saat menghubungi server prediksi.'
]);
} }
} }
// ===== RIWAYAT ===== public function riwayat(Request $request)
{
public function riwayat(Request $request) // FILTER BERDASARKAN USER_ID
{ $query = Prediksi::where('user_id', Auth::id());
$query = Prediksi::query();
if ($request->filled('search')) { if ($request->filled('search')) {
$query->where('penyakit', 'like', '%' . $request->search . '%'); $query->where('penyakit', 'like', '%' . $request->search . '%');
@ -131,74 +99,53 @@ public function riwayat(Request $request)
} }
$data = $query->latest()->get(); $data = $query->latest()->get();
return view('riwayat', compact('data')); return view('riwayat', compact('data'));
} }
// ===== DASHBOARD =====
public function 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(); return view('dashboard', compact('totalPrediksi', 'blast', 'blight', 'healthy', 'tungro', 'terbaru'));
$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'
));
} }
public function exportPdf() public function exportPdf()
{ {
$data = Prediksi::latest()->get(); $data = Prediksi::where('user_id', Auth::id())->latest()->get();
$pdf = Pdf::loadView('pdf.laporan', compact('data'));
$pdf = Pdf::loadView( return $pdf->download('laporan-prediksi.pdf');
'pdf.laporan',
compact('data')
);
return $pdf->download(
'laporan-prediksi.pdf'
);
} }
public function hapus($id) 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); $path = public_path('uploads/' . $data->gambar);
if (file_exists($path)) { if (file_exists($path)) {
unlink($path); unlink($path);
} }
$data->delete(); $data->delete();
return redirect()->back()->with('success', 'Data berhasil dihapus');
return redirect()->back()->with(
'success',
'Data berhasil dihapus'
);
} }
public function statistik() public function statistik()
{ {
$userId = Auth::id();
return response()->json([ return response()->json([
'blast' => Prediksi::where('penyakit', 'Blast')->count(), 'blast' => Prediksi::where('user_id', $userId)->where('penyakit', 'Blast')->count(),
'blight' => Prediksi::where('penyakit', 'Blight')->count(), 'blight' => Prediksi::where('user_id', $userId)->where('penyakit', 'Blight')->count(),
'healthy' => Prediksi::where('penyakit', 'Healthy')->count(), 'healthy' => Prediksi::where('user_id', $userId)->where('penyakit', 'Healthy')->count(),
'tungro' => Prediksi::where('penyakit', 'Tungro')->count(), 'tungro' => Prediksi::where('user_id', $userId)->where('penyakit', 'Tungro')->count(),
]); ]);
} }
} }

View File

@ -9,6 +9,7 @@ class Prediksi extends Model
protected $fillable = [ protected $fillable = [
'gambar', 'gambar',
'penyakit', '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> @extends('layouts.main')
<html>
<head>
<title>Dashboard</title>
<script src="https://cdn.tailwindcss.com"></script> @section('title', 'Dashboard - Rice Leaf AI')
</head>
<body class="bg-green-50"> @section('content')
<div class="max-w-7xl mx-auto px-6 py-10">
<div class="p-10"> <div class="mb-10">
<h1 class="text-3xl font-extrabold text-gray-800">Dashboard Overview</h1>
<h1 class="text-4xl font-bold text-green-700 mb-8"> <p class="text-gray-500 mt-2">Ringkasan data klasifikasi dan performa model Artificial Intelligence.</p>
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>
<div class="bg-white p-6 rounded-xl shadow"> <div class="grid grid-cols-2 md:grid-cols-5 gap-6 mb-10">
<h2 class="text-gray-500">Blast</h2> @foreach(['Total Prediksi' => [$totalPrediksi, 'blue'], 'Blast' => [$blast, 'red'], 'Blight' => [$blight, 'yellow'], 'Healthy' => [$healthy, 'green'], 'Tungro' => [$tungro, 'orange']] as $label => $data)
<p class="text-4xl font-bold text-red-600 mt-2"> <div class="bg-white p-6 rounded-2xl shadow-sm border border-gray-100 hover:shadow-md transition-shadow group relative overflow-hidden">
{{ $blast }} <div class="absolute -right-6 -top-6 bg-{{$data[1]}}-50 w-20 h-20 rounded-full"></div>
</p> <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>
<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>
</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>
<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>
</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>
<!-- 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>
<!-- 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 @endforeach
</tbody>
</table>
</div> </div>
<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>
<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>
</div> </div>
@endsection
@push('scripts')
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script> <script>
new Chart(document.getElementById('chartPenyakit'), {
const ctx = document.getElementById('chartPenyakit');
new Chart(ctx, {
type: 'bar', type: 'bar',
data: { data: {
labels: ['Blast', 'Blight', 'Healthy', 'Tungro'], labels: ['Blast', 'Blight', 'Healthy', 'Tungro'],
datasets: [{ datasets: [{
label: 'Jumlah Data', data: [{{ $blast }}, {{ $blight }}, {{ $healthy }}, {{ $tungro }}],
backgroundColor: ['#ef4444', '#eab308', '#22c55e', '#f97316'],
data: [ borderRadius: 6
{{ $blast }},
{{ $blight }},
{{ $healthy }},
{{ $tungro }}
],
borderWidth: 1
}] }]
}, },
options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false } } }
options: { });
responsive: true
}
});
</script> </script>
@endpush
</body>
</html>

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> @extends('layouts.main')
<html>
<head>
<title>Informasi Penyakit Daun Padi</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-green-50"> @section('title', 'Informasi Penyakit Daun Padi - Rice Leaf AI')
<nav class="bg-green-700 text-white p-4"> @section('content')
<div class="max-w-7xl mx-auto flex justify-between"> <div class="max-w-7xl mx-auto px-6 py-12 flex-grow">
<h1 class="font-bold text-2xl">
Rice Leaf AI
</h1>
<div class="space-x-3"> <div class="text-center mb-16 animate-[fadeInUp_0.8s_ease-out_forwards]">
<a href="/" class="hover:underline">Beranda</a> <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">
<a href="/dashboard" class="hover:underline">Dashboard</a> 📚 Ensiklopedia Botani
<a href="/riwayat" class="hover:underline">Riwayat</a> </span>
</div> <h1 class="text-4xl md:text-5xl font-extrabold text-gray-800 mb-4">
</div>
</nav>
<div class="max-w-7xl mx-auto p-10">
<h1 class="text-5xl font-bold text-center text-green-700 mb-12">
Informasi Penyakit Daun Padi Informasi Penyakit Daun Padi
</h1> </h1>
<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>
<div class="grid md:grid-cols-2 gap-8"> <div class="grid md:grid-cols-2 gap-10">
<!-- Blast --> <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="bg-white p-8 rounded-3xl shadow-lg"> <div class="relative overflow-hidden h-64 shrink-0">
<h2 class="text-3xl font-bold text-red-600 mb-4"> <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 Blast
</h2> </h2>
</div>
<p class="mb-4">
Penyakit yang disebabkan oleh jamur
<b>Pyricularia oryzae</b>.
</p>
<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> </div>
<!-- Blight --> <div class="p-8 flex-grow">
<div class="bg-white p-8 rounded-3xl shadow-lg"> <div class="grid gap-4 h-full">
<h2 class="text-3xl font-bold text-yellow-600 mb-4"> <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>
<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>
<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>
<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>
<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 Blight
</h2> </h2>
</div>
<p class="mb-4">
Penyakit bakteri yang menyebabkan hawar daun.
</p>
<ul class="list-disc ml-5">
<li>Daun menguning</li>
<li>Tepi daun mengering</li>
<li>Pertumbuhan terganggu</li>
</ul>
<p class="mt-4">
Solusi:
Gunakan benih sehat dan sanitasi lahan.
</p>
</div> </div>
<!-- Tungro --> <div class="p-8 flex-grow">
<div class="bg-white p-8 rounded-3xl shadow-lg"> <div class="grid gap-4 h-full">
<h2 class="text-3xl font-bold text-orange-500 mb-4"> <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>
<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>
<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>
<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 Tungro
</h2> </h2>
</div>
<p class="mb-4">
Penyakit virus yang ditularkan oleh wereng hijau.
</p>
<ul class="list-disc ml-5">
<li>Daun menguning</li>
<li>Tanaman kerdil</li>
<li>Produksi menurun</li>
</ul>
<p class="mt-4">
Solusi:
Kendalikan populasi wereng dan gunakan varietas tahan.
</p>
</div> </div>
<!-- Healthy --> <div class="p-8 flex-grow">
<div class="bg-white p-8 rounded-3xl shadow-lg"> <div class="grid gap-4 h-full">
<h2 class="text-3xl font-bold text-green-600 mb-4"> <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>
<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>
<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>
<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>
<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 Healthy
</h2> </h2>
</div>
</div>
<p> <div class="p-8 flex-grow flex flex-col justify-center">
Daun padi sehat berwarna hijau segar, <div class="bg-green-50/50 p-6 rounded-3xl border border-green-100 mb-6">
tidak terdapat bercak ataupun gejala penyakit. <h3 class="font-bold text-gray-800 text-lg mb-3 flex items-center gap-2">
</p> <span>🌿</span> Deskripsi Fisik
</h3>
<p class="mt-4"> <p class="text-gray-600 leading-relaxed">
Pertahankan pemupukan dan pengairan yang baik. 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> </p>
</div> </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>
</div> </div>
@endsection
</body>
</html>

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

View File

@ -1,445 +1,300 @@
<!DOCTYPE html> @extends('layouts.main')
<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>
<script src="https://cdn.tailwindcss.com"></script> @section('title', 'Klasifikasi Penyakit Daun Padi - Rice Leaf AI')
</head>
<body id="body" @push('styles')
class="bg-gradient-to-br from-green-100 to-green-50 min-h-screen transition-all duration-500"> <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 --> @section('content')
<div class="bg-gradient-to-br from-green-100 via-white to-green-50 min-h-screen transition-all duration-500">
<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 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>
</div> <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
</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> </h1>
<p class="text-lg text-gray-700 mb-8"> <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.
Deteksi penyakit daun padi secara otomatis menggunakan
teknologi Deep Learning berbasis website.
</p> </p>
<div class="flex gap-4"> <div class="flex flex-wrap gap-4">
<a href="#upload" <a href="#upload"
class="bg-green-600 hover:bg-green-700 text-white px-6 py-3 rounded-xl text-lg shadow-lg"> 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
Mulai Prediksi
</a> </a>
<a href="/dashboard" <a href="/dashboard"
class="bg-white border border-green-600 text-green-700 px-6 py-3 rounded-xl text-lg"> 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
Lihat Dashboard
</a> </a>
</div>
</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>
<div>
<img src="https://images.unsplash.com/photo-1625246333195-78d9c38ad449?q=80&w=1200&auto=format&fit=crop" <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> </div>
</section> </section>
<!-- Upload --> <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">
<section id="upload" class="max-w-4xl mx-auto px-6 pb-20"> <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="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 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> </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 @endif
@if(session('error')) @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">
<div class="bg-red-100 border border-red-300 text-red-700 p-4 rounded-xl mb-6"> <span>⚠️</span> {{ session('error') }}
{{ session('error') }}
</div> </div>
@endif @endif
<form id="formPrediksi" @auth
action="/prediksi" <form id="formPrediksi" action="/prediksi" method="POST" enctype="multipart/form-data">
method="POST"
enctype="multipart/form-data">
@csrf @csrf
@else
<form action="/login" method="GET">
@endauth
<div class="border-2 border-dashed border-green-400 rounded-2xl p-10 text-center"> <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">
<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 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>
<p class="text-gray-500 mt-6"> <div id="upload-placeholder" class="pointer-events-none">
Upload gambar daun padi untuk diprediksi <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">
</p> @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>
<button type="submit" <div class="mt-6 text-center pointer-events-none z-10 relative">
id="btnPrediksi" <img id="preview" class="hidden mx-auto rounded-2xl shadow-xl w-64 h-64 object-cover border-4 border-white">
class="w-full mt-6 bg-green-600 hover:bg-green-700 text-white py-4 rounded-2xl text-xl font-semibold shadow-lg"> </div>
</div>
Prediksi Sekarang
<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> </button>
</form> </form>
<!-- Hasil Prediksi -->
@if(session('hasil')) @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>
<div class="mt-10 bg-green-50 border border-green-200 rounded-3xl p-8"> <h2 class="text-3xl font-extrabold text-gray-800 mb-8 text-center">
Hasil Analisis AI
<h2 class="text-3xl font-bold text-green-700 mb-6">
Hasil Prediksi
</h2> </h2>
<img src="{{ asset('uploads/' . session('gambar')) }}" <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">
class="w-64 rounded-2xl shadow-lg mb-6 mx-auto">
<div class="grid md:grid-cols-2 gap-6"> <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">
<div class="bg-white p-6 rounded-2xl 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">
<h3 class="text-lg text-gray-500 mb-2">
Penyakit
</h3>
<p class="text-3xl font-bold text-red-600">
{{ session('hasil') }} {{ session('hasil') }}
</p> </p>
</div> </div>
<div class="bg-white p-6 rounded-2xl shadow"> <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>
<h3 class="text-lg text-gray-500 mb-2"> <p class="text-3xl font-extrabold text-green-600 mt-2 flex items-center gap-2">
Confidence
</h3>
<p class="text-3xl font-bold text-green-700">
{{ session('confidence') }}% {{ 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> </p>
</div> </div>
</div> </div>
@if(session('allPredictions')) @if(session('allPredictions'))
<div class="bg-white p-8 rounded-2xl shadow-sm border border-gray-100 mt-6">
<div class="bg-white p-6 rounded-2xl shadow 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>
<h3 class="text-2xl font-bold text-green-700 mb-4">
Probabilitas Semua Kelas Probabilitas Semua Kelas
</h3> </h3>
@foreach(session('allPredictions') as $kelas => $nilai) @foreach(session('allPredictions') as $kelas => $nilai)
<div class="mb-5 group">
<div class="mb-4"> <div class="flex justify-between mb-2">
<span class="font-semibold text-gray-700 group-hover:text-green-600 transition-colors">{{ $kelas }}</span>
<div class="flex justify-between mb-1"> <span class="font-bold text-gray-900">{{ $nilai }}%</span>
<span class="font-semibold">
{{ $kelas }}
</span>
<span>
{{ $nilai }}%
</span>
</div> </div>
<div class="w-full bg-gray-100 rounded-full h-3 overflow-hidden shadow-inner">
<div class="w-full bg-gray-200 rounded-full h-4"> <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 class="bg-green-600 h-4 rounded-full"
style="width: {{ $nilai }}%">
</div> </div>
</div> </div>
</div> </div>
@endforeach @endforeach
</div> </div>
@endif @endif
@if(session('deskripsi')) @if(session('deskripsi'))
<div class="bg-white p-8 rounded-2xl shadow-sm border border-gray-100 mt-6">
<div class="bg-white p-6 rounded-2xl shadow 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>
<h3 class="text-2xl font-bold text-green-700 mb-4"> Informasi Detail
Informasi Penyakit
</h3> </h3>
<p class="mb-4 text-gray-700"> <div class="space-y-6">
<span class="font-bold">Deskripsi:</span><br> <div class="bg-blue-50/50 p-5 rounded-xl border border-blue-100">
{{ session('deskripsi') }} <h4 class="font-bold text-blue-800 mb-2">Deskripsi Penyakit:</h4>
</p> <p class="text-gray-700 leading-relaxed">{{ session('deskripsi') }}</p>
<p class="text-gray-700">
<span class="font-bold">Solusi:</span><br>
{{ session('solusi') }}
</p>
</div> </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>
@endif @endif
</div> </div>
@endif @endif
</div> </div>
</div>
</section> </section>
<!-- Contoh Penyakit --> <section class="max-w-7xl mx-auto px-6 pb-24">
<div class="text-center mb-16">
<section class="max-w-7xl mx-auto px-6 pb-20"> <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>
<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="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>
<div class="bg-white rounded-3xl shadow-xl overflow-hidden"> <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" <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">
class="h-56 w-full object-cover"> <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-5"> <div class="p-6">
<h3 class="text-2xl font-bold text-gray-800 mb-3 group-hover:text-yellow-600 transition-colors">Blight</h3>
<h3 class="text-2xl font-bold text-yellow-600 mb-3"> <p class="text-gray-500 text-sm leading-relaxed">Hawar daun bakteri yang menyebabkan daun menguning, mengering, dan mati dari ujungnya.</p>
Blight </div>
</h3>
<p class="text-gray-600">
Hawar daun yang menyebabkan daun menguning.
</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>
<div class="bg-white rounded-3xl shadow-xl overflow-hidden"> <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" <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">
class="h-56 w-full object-cover"> <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 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="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 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>
</div> </div>
</div>
</section> </section>
<!-- Footer --> </div>
<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 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> </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>
</div>
@endsection
<script> @push('scripts')
<script>
function previewImage(event) function previewImage(event) {
{
const preview = document.getElementById('preview'); 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.src = URL.createObjectURL(event.target.files[0]);
preview.classList.remove('hidden'); 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() { form.addEventListener('submit', function() {
document.getElementById('loading').classList.remove('hidden');
document.getElementById('loading')
.classList.remove('hidden');
}); });
function toggleDarkMode()
{
const body = document.getElementById('body');
body.classList.toggle('bg-gray-900');
body.classList.toggle('text-white');
body.classList.toggle('from-green-100');
body.classList.toggle('to-green-50');
} }
</script> function toggleDarkMode() {
const body = document.getElementById('body');
</body> if(body) {
</html> 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>
@endpush

View File

@ -2,12 +2,41 @@
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
use App\Http\Controllers\KlasifikasiController; use App\Http\Controllers\KlasifikasiController;
use App\Http\Controllers\AuthController;
// ==========================================
// BISA DIAKSES SIAPA SAJA (TANPA LOGIN)
// ==========================================
Route::get('/', [KlasifikasiController::class, 'index']); Route::get('/', [KlasifikasiController::class, 'index']);
Route::post('/prediksi', [KlasifikasiController::class, 'prediksi']);
Route::get('/riwayat', [KlasifikasiController::class, 'riwayat']); // ==========================================
Route::get('/dashboard', [KlasifikasiController::class, 'dashboard']); // ROUTE UNTUK TAMU (BELUM LOGIN)
Route::get('/export-pdf', [KlasifikasiController::class, 'exportPdf']); // ==========================================
Route::delete('/hapus/{id}', [KlasifikasiController::class, 'hapus']); // middleware('guest') memastikan orang yang sudah login tidak bisa ke halaman ini lagi
Route::view('/penyakit', 'penyakit'); Route::middleware('guest')->group(function () {
Route::get('/statistik', [KlasifikasiController::class, 'statistik']); // 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']);
});