Update MobileNetV2 4 kelas
|
|
@ -5,6 +5,8 @@
|
|||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Models\Prediksi;
|
||||
use Barryvdh\DomPDF\Facade\Pdf;
|
||||
|
||||
class KlasifikasiController extends Controller
|
||||
{
|
||||
|
|
@ -27,37 +29,176 @@ 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()) {
|
||||
$message = 'Server prediksi gagal: ' . $response->status();
|
||||
Log::error($message, ['body' => $response->body()]);
|
||||
|
||||
Log::error('Server prediksi gagal', [
|
||||
'body' => $response->body()
|
||||
]);
|
||||
|
||||
return back()->with([
|
||||
'error' => 'Tidak dapat memproses prediksi. Coba lagi nanti.',
|
||||
'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.';
|
||||
}
|
||||
|
||||
Prediksi::create([
|
||||
'gambar' => $namaFile,
|
||||
'penyakit' => $hasil['penyakit'],
|
||||
'confidence' => $hasil['confidence']
|
||||
]);
|
||||
|
||||
return back()->with([
|
||||
'success' => 'Prediksi berhasil',
|
||||
'gambar' => $namaFile,
|
||||
'hasil' => $hasil['penyakit'] ?? 'Tidak ada hasil',
|
||||
'confidence' => $hasil['confidence'] ?? 0,
|
||||
'deskripsi' => $deskripsi,
|
||||
'solusi' => $solusi,
|
||||
'allPredictions' => $allPredictions,
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Prediksi request error: ' . $e->getMessage());
|
||||
|
||||
Log::error(
|
||||
'Prediksi request error: ' . $e->getMessage()
|
||||
);
|
||||
|
||||
return back()->with([
|
||||
'error' => 'Terjadi kesalahan saat menghubungi server prediksi.',
|
||||
'error' => 'Terjadi kesalahan saat menghubungi server prediksi.'
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ===== RIWAYAT =====
|
||||
|
||||
public function riwayat(Request $request)
|
||||
{
|
||||
$query = Prediksi::query();
|
||||
|
||||
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'));
|
||||
}
|
||||
|
||||
// ===== DASHBOARD =====
|
||||
|
||||
public function dashboard()
|
||||
{
|
||||
$totalPrediksi = Prediksi::count();
|
||||
|
||||
$blast = Prediksi::where('penyakit', 'Blast')->count();
|
||||
|
||||
$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'
|
||||
));
|
||||
}
|
||||
|
||||
public function exportPdf()
|
||||
{
|
||||
$data = Prediksi::latest()->get();
|
||||
|
||||
$pdf = Pdf::loadView(
|
||||
'pdf.laporan',
|
||||
compact('data')
|
||||
);
|
||||
|
||||
return $pdf->download(
|
||||
'laporan-prediksi.pdf'
|
||||
);
|
||||
}
|
||||
public function hapus($id)
|
||||
{
|
||||
$data = Prediksi::findOrFail($id);
|
||||
|
||||
$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(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Prediksi extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'gambar',
|
||||
'penyakit',
|
||||
'confidence'
|
||||
];
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^8.3",
|
||||
"barryvdh/laravel-dompdf": "^3.1",
|
||||
"laravel/framework": "^13.8",
|
||||
"laravel/tinker": "^3.0"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -4,8 +4,85 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "36793882908b6cbdd344b5a4840231db",
|
||||
"content-hash": "a044b0654c78954203ccd470e8939dfb",
|
||||
"packages": [
|
||||
{
|
||||
"name": "barryvdh/laravel-dompdf",
|
||||
"version": "v3.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/barryvdh/laravel-dompdf.git",
|
||||
"reference": "ee3b72b19ccdf57d0243116ecb2b90261344dedc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/barryvdh/laravel-dompdf/zipball/ee3b72b19ccdf57d0243116ecb2b90261344dedc",
|
||||
"reference": "ee3b72b19ccdf57d0243116ecb2b90261344dedc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"dompdf/dompdf": "^3.0",
|
||||
"illuminate/support": "^9|^10|^11|^12|^13.0",
|
||||
"php": "^8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"larastan/larastan": "^2.7|^3.0",
|
||||
"orchestra/testbench": "^7|^8|^9.16|^10|^11.0",
|
||||
"phpro/grumphp": "^2.5",
|
||||
"squizlabs/php_codesniffer": "^3.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"aliases": {
|
||||
"PDF": "Barryvdh\\DomPDF\\Facade\\Pdf",
|
||||
"Pdf": "Barryvdh\\DomPDF\\Facade\\Pdf"
|
||||
},
|
||||
"providers": [
|
||||
"Barryvdh\\DomPDF\\ServiceProvider"
|
||||
]
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-master": "3.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Barryvdh\\DomPDF\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Barry vd. Heuvel",
|
||||
"email": "barryvdh@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A DOMPDF Wrapper for Laravel",
|
||||
"keywords": [
|
||||
"dompdf",
|
||||
"laravel",
|
||||
"pdf"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/barryvdh/laravel-dompdf/issues",
|
||||
"source": "https://github.com/barryvdh/laravel-dompdf/tree/v3.1.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://fruitcake.nl",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/barryvdh",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2026-02-21T08:51:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "brick/math",
|
||||
"version": "0.14.8",
|
||||
|
|
@ -377,6 +454,161 @@
|
|||
],
|
||||
"time": "2024-02-05T11:56:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dompdf/dompdf",
|
||||
"version": "v3.1.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dompdf/dompdf.git",
|
||||
"reference": "f11ead23a8a76d0ff9bbc6c7c8fd7e05ca328496"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dompdf/dompdf/zipball/f11ead23a8a76d0ff9bbc6c7c8fd7e05ca328496",
|
||||
"reference": "f11ead23a8a76d0ff9bbc6c7c8fd7e05ca328496",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"dompdf/php-font-lib": "^1.0.0",
|
||||
"dompdf/php-svg-lib": "^1.0.0",
|
||||
"ext-dom": "*",
|
||||
"ext-mbstring": "*",
|
||||
"masterminds/html5": "^2.0",
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-gd": "*",
|
||||
"ext-json": "*",
|
||||
"ext-zip": "*",
|
||||
"mockery/mockery": "^1.3",
|
||||
"phpunit/phpunit": "^7.5 || ^8 || ^9 || ^10 || ^11",
|
||||
"squizlabs/php_codesniffer": "^3.5",
|
||||
"symfony/process": "^4.4 || ^5.4 || ^6.2 || ^7.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-gd": "Needed to process images",
|
||||
"ext-gmagick": "Improves image processing performance",
|
||||
"ext-imagick": "Improves image processing performance",
|
||||
"ext-zlib": "Needed for pdf stream compression"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Dompdf\\": "src/"
|
||||
},
|
||||
"classmap": [
|
||||
"lib/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-2.1"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "The Dompdf Community",
|
||||
"homepage": "https://github.com/dompdf/dompdf/blob/master/AUTHORS.md"
|
||||
}
|
||||
],
|
||||
"description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter",
|
||||
"homepage": "https://github.com/dompdf/dompdf",
|
||||
"support": {
|
||||
"issues": "https://github.com/dompdf/dompdf/issues",
|
||||
"source": "https://github.com/dompdf/dompdf/tree/v3.1.5"
|
||||
},
|
||||
"time": "2026-03-03T13:54:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dompdf/php-font-lib",
|
||||
"version": "1.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dompdf/php-font-lib.git",
|
||||
"reference": "a6e9a688a2a80016ac080b97be73d3e10c444c9a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/a6e9a688a2a80016ac080b97be73d3e10c444c9a",
|
||||
"reference": "a6e9a688a2a80016ac080b97be73d3e10c444c9a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.5 || ^8 || ^9 || ^10 || ^11 || ^12"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"FontLib\\": "src/FontLib"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-2.1-or-later"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "The FontLib Community",
|
||||
"homepage": "https://github.com/dompdf/php-font-lib/blob/master/AUTHORS.md"
|
||||
}
|
||||
],
|
||||
"description": "A library to read, parse, export and make subsets of different types of font files.",
|
||||
"homepage": "https://github.com/dompdf/php-font-lib",
|
||||
"support": {
|
||||
"issues": "https://github.com/dompdf/php-font-lib/issues",
|
||||
"source": "https://github.com/dompdf/php-font-lib/tree/1.0.2"
|
||||
},
|
||||
"time": "2026-01-20T14:10:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dompdf/php-svg-lib",
|
||||
"version": "1.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dompdf/php-svg-lib.git",
|
||||
"reference": "8259ffb930817e72b1ff1caef5d226501f3dfeb1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dompdf/php-svg-lib/zipball/8259ffb930817e72b1ff1caef5d226501f3dfeb1",
|
||||
"reference": "8259ffb930817e72b1ff1caef5d226501f3dfeb1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": "^7.1 || ^8.0",
|
||||
"sabberworm/php-css-parser": "^8.4 || ^9.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.5 || ^8 || ^9 || ^10 || ^11"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Svg\\": "src/Svg"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-3.0-or-later"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "The SvgLib Community",
|
||||
"homepage": "https://github.com/dompdf/php-svg-lib/blob/master/AUTHORS.md"
|
||||
}
|
||||
],
|
||||
"description": "A library to read, parse and export to PDF SVG files.",
|
||||
"homepage": "https://github.com/dompdf/php-svg-lib",
|
||||
"support": {
|
||||
"issues": "https://github.com/dompdf/php-svg-lib/issues",
|
||||
"source": "https://github.com/dompdf/php-svg-lib/tree/1.0.2"
|
||||
},
|
||||
"time": "2026-01-02T16:01:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dragonmantank/cron-expression",
|
||||
"version": "v3.6.0",
|
||||
|
|
@ -2026,6 +2258,73 @@
|
|||
],
|
||||
"time": "2026-03-08T20:05:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "masterminds/html5",
|
||||
"version": "2.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Masterminds/html5-php.git",
|
||||
"reference": "fcf91eb64359852f00d921887b219479b4f21251"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Masterminds/html5-php/zipball/fcf91eb64359852f00d921887b219479b4f21251",
|
||||
"reference": "fcf91eb64359852f00d921887b219479b4f21251",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.7-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Masterminds\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Matt Butcher",
|
||||
"email": "technosophos@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Matt Farina",
|
||||
"email": "matt@mattfarina.com"
|
||||
},
|
||||
{
|
||||
"name": "Asmir Mustafic",
|
||||
"email": "goetas@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "An HTML5 parser and serializer.",
|
||||
"homepage": "http://masterminds.github.io/html5-php",
|
||||
"keywords": [
|
||||
"HTML5",
|
||||
"dom",
|
||||
"html",
|
||||
"parser",
|
||||
"querypath",
|
||||
"serializer",
|
||||
"xml"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Masterminds/html5-php/issues",
|
||||
"source": "https://github.com/Masterminds/html5-php/tree/2.10.0"
|
||||
},
|
||||
"time": "2025-07-25T09:04:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "3.10.0",
|
||||
|
|
@ -3301,6 +3600,86 @@
|
|||
},
|
||||
"time": "2025-12-14T04:43:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sabberworm/php-css-parser",
|
||||
"version": "v9.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/MyIntervals/PHP-CSS-Parser.git",
|
||||
"reference": "88dbd0f7f91abbfe4402d0a3071e9ff4d81ed949"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/MyIntervals/PHP-CSS-Parser/zipball/88dbd0f7f91abbfe4402d0a3071e9ff4d81ed949",
|
||||
"reference": "88dbd0f7f91abbfe4402d0a3071e9ff4d81ed949",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-iconv": "*",
|
||||
"php": "^7.2.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0",
|
||||
"thecodingmachine/safe": "^1.3 || ^2.5 || ^3.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"php-parallel-lint/php-parallel-lint": "1.4.0",
|
||||
"phpstan/extension-installer": "1.4.3",
|
||||
"phpstan/phpstan": "1.12.32 || 2.1.32",
|
||||
"phpstan/phpstan-phpunit": "1.4.2 || 2.0.8",
|
||||
"phpstan/phpstan-strict-rules": "1.6.2 || 2.0.7",
|
||||
"phpunit/phpunit": "8.5.52",
|
||||
"rawr/phpunit-data-provider": "3.3.1",
|
||||
"rector/rector": "1.2.10 || 2.2.8",
|
||||
"rector/type-perfect": "1.0.0 || 2.1.0",
|
||||
"squizlabs/php_codesniffer": "4.0.1",
|
||||
"thecodingmachine/phpstan-safe-rule": "1.2.0 || 1.4.1"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "for parsing UTF-8 CSS"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "9.4.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/Rule/Rule.php",
|
||||
"src/RuleSet/RuleContainer.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Sabberworm\\CSS\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Raphael Schweikert"
|
||||
},
|
||||
{
|
||||
"name": "Oliver Klee",
|
||||
"email": "github@oliverklee.de"
|
||||
},
|
||||
{
|
||||
"name": "Jake Hotson",
|
||||
"email": "jake.github@qzdesign.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "Parser for CSS Files written in PHP",
|
||||
"homepage": "https://www.sabberworm.com/blog/2010/6/10/php-css-parser",
|
||||
"keywords": [
|
||||
"css",
|
||||
"parser",
|
||||
"stylesheet"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/MyIntervals/PHP-CSS-Parser/issues",
|
||||
"source": "https://github.com/MyIntervals/PHP-CSS-Parser/tree/v9.3.0"
|
||||
},
|
||||
"time": "2026-03-03T17:31:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/clock",
|
||||
"version": "v7.4.8",
|
||||
|
|
@ -5890,6 +6269,149 @@
|
|||
],
|
||||
"time": "2026-03-30T13:44:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "thecodingmachine/safe",
|
||||
"version": "v3.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thecodingmachine/safe.git",
|
||||
"reference": "705683a25bacf0d4860c7dea4d7947bfd09eea19"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thecodingmachine/safe/zipball/705683a25bacf0d4860c7dea4d7947bfd09eea19",
|
||||
"reference": "705683a25bacf0d4860c7dea4d7947bfd09eea19",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"php-parallel-lint/php-parallel-lint": "^1.4",
|
||||
"phpstan/phpstan": "^2",
|
||||
"phpunit/phpunit": "^10",
|
||||
"squizlabs/php_codesniffer": "^3.2"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/special_cases.php",
|
||||
"generated/apache.php",
|
||||
"generated/apcu.php",
|
||||
"generated/array.php",
|
||||
"generated/bzip2.php",
|
||||
"generated/calendar.php",
|
||||
"generated/classobj.php",
|
||||
"generated/com.php",
|
||||
"generated/cubrid.php",
|
||||
"generated/curl.php",
|
||||
"generated/datetime.php",
|
||||
"generated/dir.php",
|
||||
"generated/eio.php",
|
||||
"generated/errorfunc.php",
|
||||
"generated/exec.php",
|
||||
"generated/fileinfo.php",
|
||||
"generated/filesystem.php",
|
||||
"generated/filter.php",
|
||||
"generated/fpm.php",
|
||||
"generated/ftp.php",
|
||||
"generated/funchand.php",
|
||||
"generated/gettext.php",
|
||||
"generated/gmp.php",
|
||||
"generated/gnupg.php",
|
||||
"generated/hash.php",
|
||||
"generated/ibase.php",
|
||||
"generated/ibmDb2.php",
|
||||
"generated/iconv.php",
|
||||
"generated/image.php",
|
||||
"generated/imap.php",
|
||||
"generated/info.php",
|
||||
"generated/inotify.php",
|
||||
"generated/json.php",
|
||||
"generated/ldap.php",
|
||||
"generated/libxml.php",
|
||||
"generated/lzf.php",
|
||||
"generated/mailparse.php",
|
||||
"generated/mbstring.php",
|
||||
"generated/misc.php",
|
||||
"generated/mysql.php",
|
||||
"generated/mysqli.php",
|
||||
"generated/network.php",
|
||||
"generated/oci8.php",
|
||||
"generated/opcache.php",
|
||||
"generated/openssl.php",
|
||||
"generated/outcontrol.php",
|
||||
"generated/pcntl.php",
|
||||
"generated/pcre.php",
|
||||
"generated/pgsql.php",
|
||||
"generated/posix.php",
|
||||
"generated/ps.php",
|
||||
"generated/pspell.php",
|
||||
"generated/readline.php",
|
||||
"generated/rnp.php",
|
||||
"generated/rpminfo.php",
|
||||
"generated/rrd.php",
|
||||
"generated/sem.php",
|
||||
"generated/session.php",
|
||||
"generated/shmop.php",
|
||||
"generated/sockets.php",
|
||||
"generated/sodium.php",
|
||||
"generated/solr.php",
|
||||
"generated/spl.php",
|
||||
"generated/sqlsrv.php",
|
||||
"generated/ssdeep.php",
|
||||
"generated/ssh2.php",
|
||||
"generated/stream.php",
|
||||
"generated/strings.php",
|
||||
"generated/swoole.php",
|
||||
"generated/uodbc.php",
|
||||
"generated/uopz.php",
|
||||
"generated/url.php",
|
||||
"generated/var.php",
|
||||
"generated/xdiff.php",
|
||||
"generated/xml.php",
|
||||
"generated/xmlrpc.php",
|
||||
"generated/yaml.php",
|
||||
"generated/yaz.php",
|
||||
"generated/zip.php",
|
||||
"generated/zlib.php"
|
||||
],
|
||||
"classmap": [
|
||||
"lib/DateTime.php",
|
||||
"lib/DateTimeImmutable.php",
|
||||
"lib/Exceptions/",
|
||||
"generated/Exceptions/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "PHP core functions that throw exceptions instead of returning FALSE on error",
|
||||
"support": {
|
||||
"issues": "https://github.com/thecodingmachine/safe/issues",
|
||||
"source": "https://github.com/thecodingmachine/safe/tree/v3.4.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/OskarStark",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/shish",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/silasjoisten",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/staabm",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2026-02-04T18:08:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "tijsverkoyen/css-to-inline-styles",
|
||||
"version": "v2.4.0",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('prediksis', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('gambar');
|
||||
$table->string('penyakit');
|
||||
$table->float('confidence');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('prediksis');
|
||||
}
|
||||
};
|
||||
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 3.5 MiB |
|
After Width: | Height: | Size: 1.7 MiB |
|
After Width: | Height: | Size: 2.1 MiB |
|
After Width: | Height: | Size: 1.7 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
127
python_ai/app.py
|
|
@ -11,56 +11,153 @@ UPLOAD_FOLDER = os.path.join(os.path.dirname(__file__), 'uploads')
|
|||
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
|
||||
|
||||
MODEL_PATH = os.path.join(os.path.dirname(__file__), 'model_padi.h5')
|
||||
CLASS_NAMES = ['Blast', 'Blight', 'Tungro']
|
||||
|
||||
CLASS_NAMES = [
|
||||
'Healthy',
|
||||
'Blast',
|
||||
'Blight',
|
||||
'Tungro'
|
||||
]
|
||||
|
||||
|
||||
# Load model
|
||||
model = None
|
||||
|
||||
try:
|
||||
model = load_model(MODEL_PATH)
|
||||
print('Model dimuat dari', MODEL_PATH)
|
||||
|
||||
print("Model berhasil dimuat")
|
||||
print("Input Shape :", model.input_shape)
|
||||
print("Output Shape:", model.output_shape)
|
||||
print("Model Type :", type(model))
|
||||
|
||||
except Exception as e:
|
||||
print('Gagal memuat model:', e)
|
||||
print("Gagal load model:", e)
|
||||
|
||||
|
||||
# Preprocessing gambar
|
||||
def preprocess_image(path):
|
||||
|
||||
image = Image.open(path).convert('RGB')
|
||||
image = image.resize((150, 150))
|
||||
|
||||
image = image.resize((224, 224))
|
||||
|
||||
image_array = np.array(image).astype('float32') / 255.0
|
||||
return np.expand_dims(image_array, axis=0)
|
||||
|
||||
image_array = np.expand_dims(image_array, axis=0)
|
||||
|
||||
return image_array
|
||||
|
||||
|
||||
@app.route('/prediksi', methods=['POST'])
|
||||
def prediksi():
|
||||
|
||||
if 'gambar' not in request.files:
|
||||
return jsonify({'error': 'Tidak ada file gambar'}), 400
|
||||
return jsonify({
|
||||
'error': 'Tidak ada gambar'
|
||||
}), 400
|
||||
|
||||
file = request.files['gambar']
|
||||
|
||||
if file.filename == '':
|
||||
return jsonify({'error': 'Nama file kosong'}), 400
|
||||
return jsonify({
|
||||
'error': 'File kosong'
|
||||
}), 400
|
||||
|
||||
# Simpan gambar
|
||||
filename = datetime.now().strftime('%Y%m%d%H%M%S_') + file.filename
|
||||
|
||||
filepath = os.path.join(UPLOAD_FOLDER, filename)
|
||||
|
||||
file.save(filepath)
|
||||
|
||||
print('GAMBAR DITERIMA:', filename)
|
||||
print("Gambar diterima:", filename)
|
||||
|
||||
if model is None:
|
||||
return jsonify({'error': 'Model tidak tersedia. Pastikan model_padi.h5 ada dan Flask dapat memuatnya.'}), 500
|
||||
return jsonify({
|
||||
'error': 'Model gagal dimuat'
|
||||
}), 500
|
||||
|
||||
try:
|
||||
|
||||
# Preprocessing
|
||||
image_array = preprocess_image(filepath)
|
||||
|
||||
# Prediksi
|
||||
predictions = model.predict(image_array)
|
||||
predicted_index = int(np.argmax(predictions, axis=1)[0])
|
||||
confidence = float(np.max(predictions, axis=1)[0]) * 100.0
|
||||
label = CLASS_NAMES[predicted_index] if predicted_index < len(CLASS_NAMES) else f'Kelas {predicted_index + 1}'
|
||||
|
||||
print("\n===== HASIL PREDIKSI =====")
|
||||
|
||||
for i, nama in enumerate(CLASS_NAMES):
|
||||
print(f"{nama}: {predictions[0][i] * 100:.2f}%")
|
||||
|
||||
predicted_index = int(np.argmax(predictions[0]))
|
||||
|
||||
label = CLASS_NAMES[predicted_index]
|
||||
|
||||
confidence_display = round(
|
||||
float(predictions[0][predicted_index]) * 100,
|
||||
2
|
||||
)
|
||||
|
||||
print(f"HASIL AKHIR: {label}")
|
||||
print(f"CONFIDENCE: {confidence_display}%")
|
||||
|
||||
# Semua probabilitas
|
||||
all_predictions = {}
|
||||
|
||||
for i, nama in enumerate(CLASS_NAMES):
|
||||
|
||||
all_predictions[nama] = round(
|
||||
float(predictions[0][i]) * 100,
|
||||
2
|
||||
)
|
||||
|
||||
# Deskripsi penyakit
|
||||
deskripsi = {
|
||||
'Blast': {
|
||||
'deskripsi': 'Penyakit jamur yang menyebabkan bercak pada daun.',
|
||||
'solusi': 'Gunakan fungisida dan varietas tahan penyakit.'
|
||||
},
|
||||
|
||||
'Blight': {
|
||||
'deskripsi': 'Hawar daun akibat bakteri.',
|
||||
'solusi': 'Gunakan benih sehat dan kurangi kelembapan.'
|
||||
},
|
||||
|
||||
'Healthy': {
|
||||
'deskripsi': 'Daun padi sehat tanpa gejala penyakit.',
|
||||
'solusi': 'Pertahankan perawatan tanaman.'
|
||||
},
|
||||
|
||||
'Tungro': {
|
||||
'deskripsi': 'Penyakit virus yang ditularkan wereng.',
|
||||
'solusi': 'Kendalikan wereng dan gunakan varietas tahan.'
|
||||
}
|
||||
}
|
||||
|
||||
return jsonify({
|
||||
|
||||
'penyakit': label,
|
||||
'confidence': round(confidence, 2)
|
||||
|
||||
'confidence': confidence_display,
|
||||
|
||||
'all_predictions': all_predictions,
|
||||
|
||||
'deskripsi': deskripsi[label]['deskripsi'],
|
||||
|
||||
'solusi': deskripsi[label]['solusi']
|
||||
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
print('Gagal prediksi:', e)
|
||||
return jsonify({'error': 'Terjadi kesalahan saat memprediksi gambar.'}), 500
|
||||
|
||||
print("ERROR:", e)
|
||||
|
||||
return jsonify({
|
||||
'error': str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True)
|
||||
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 3.5 MiB |
|
After Width: | Height: | Size: 1.7 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
|
@ -0,0 +1,209 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Dashboard</title>
|
||||
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
</head>
|
||||
|
||||
<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>
|
||||
|
||||
</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
|
||||
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<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
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Laporan Prediksi</title>
|
||||
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
table, th, td {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
th, td {
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>
|
||||
Laporan Prediksi Penyakit Daun Padi
|
||||
</h1>
|
||||
|
||||
<table>
|
||||
|
||||
<thead>
|
||||
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>Penyakit</th>
|
||||
<th>Confidence</th>
|
||||
<th>Tanggal</th>
|
||||
</tr>
|
||||
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
@foreach($data as $item)
|
||||
|
||||
<tr>
|
||||
|
||||
<td>{{ $loop->iteration }}</td>
|
||||
|
||||
<td>{{ $item->penyakit }}</td>
|
||||
|
||||
<td>{{ $item->confidence }}%</td>
|
||||
|
||||
<td>{{ $item->created_at }}</td>
|
||||
|
||||
</tr>
|
||||
|
||||
@endforeach
|
||||
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Informasi Penyakit Daun Padi</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
</head>
|
||||
|
||||
<body class="bg-green-50">
|
||||
|
||||
<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
|
||||
</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>
|
||||
</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
|
||||
</h1>
|
||||
|
||||
<div class="grid md:grid-cols-2 gap-8">
|
||||
|
||||
<!-- Blast -->
|
||||
<div class="bg-white p-8 rounded-3xl shadow-lg">
|
||||
<h2 class="text-3xl font-bold text-red-600 mb-4">
|
||||
Blast
|
||||
</h2>
|
||||
|
||||
<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>
|
||||
|
||||
<!-- Blight -->
|
||||
<div class="bg-white p-8 rounded-3xl shadow-lg">
|
||||
<h2 class="text-3xl font-bold text-yellow-600 mb-4">
|
||||
Blight
|
||||
</h2>
|
||||
|
||||
<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>
|
||||
|
||||
<!-- Tungro -->
|
||||
<div class="bg-white p-8 rounded-3xl shadow-lg">
|
||||
<h2 class="text-3xl font-bold text-orange-500 mb-4">
|
||||
Tungro
|
||||
</h2>
|
||||
|
||||
<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>
|
||||
|
||||
<!-- Healthy -->
|
||||
<div class="bg-white p-8 rounded-3xl shadow-lg">
|
||||
<h2 class="text-3xl font-bold text-green-600 mb-4">
|
||||
Healthy
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
Daun padi sehat berwarna hijau segar,
|
||||
tidak terdapat bercak ataupun gejala penyakit.
|
||||
</p>
|
||||
|
||||
<p class="mt-4">
|
||||
Pertahankan pemupukan dan pengairan yang baik.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,231 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Riwayat Prediksi</title>
|
||||
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
</head>
|
||||
<body class="bg-green-50 p-10">
|
||||
|
||||
<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>
|
||||
|
||||
</div>
|
||||
|
||||
<table class="w-full border-collapse">
|
||||
|
||||
<thead>
|
||||
|
||||
<tr class="bg-green-600 text-white">
|
||||
|
||||
<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>
|
||||
|
||||
</tr>
|
||||
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
@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>
|
||||
|
||||
</div>
|
||||
<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();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -3,79 +3,443 @@
|
|||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Klasifikasi Daun Padi</title>
|
||||
<title>Klasifikasi Penyakit Daun Padi</title>
|
||||
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
</head>
|
||||
<body class="bg-green-100">
|
||||
|
||||
<div class="container mx-auto mt-10">
|
||||
<body id="body"
|
||||
class="bg-gradient-to-br from-green-100 to-green-50 min-h-screen transition-all duration-500">
|
||||
|
||||
<div class="bg-white p-8 rounded shadow-md max-w-xl mx-auto">
|
||||
<!-- Navbar -->
|
||||
|
||||
<h1 class="text-3xl font-bold text-center text-green-700 mb-6">
|
||||
Klasifikasi Penyakit Daun Padi
|
||||
<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>
|
||||
|
||||
@if($errors->any())
|
||||
<div class="bg-red-100 text-red-800 p-3 rounded mb-4">
|
||||
<ul class="list-disc list-inside">
|
||||
@foreach($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
<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>
|
||||
|
||||
</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>
|
||||
|
||||
<p class="text-lg text-gray-700 mb-8">
|
||||
|
||||
Deteksi penyakit daun padi secara otomatis menggunakan
|
||||
teknologi Deep Learning berbasis website.
|
||||
|
||||
</p>
|
||||
|
||||
<div class="flex 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
|
||||
|
||||
</a>
|
||||
|
||||
<a href="/dashboard"
|
||||
class="bg-white border border-green-600 text-green-700 px-6 py-3 rounded-xl text-lg">
|
||||
|
||||
Lihat Dashboard
|
||||
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
||||
<img src="https://images.unsplash.com/photo-1625246333195-78d9c38ad449?q=80&w=1200&auto=format&fit=crop"
|
||||
class="rounded-3xl shadow-2xl">
|
||||
|
||||
</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 text-red-800 p-3 rounded mb-4">
|
||||
{{ session('error') }}
|
||||
</div>
|
||||
|
||||
<div class="bg-red-100 border border-red-300 text-red-700 p-4 rounded-xl mb-6">
|
||||
|
||||
{{ session('error') }}
|
||||
|
||||
</div>
|
||||
|
||||
@endif
|
||||
|
||||
@if(session('success'))
|
||||
<div class="bg-green-200 text-green-800 p-3 rounded mb-4">
|
||||
{{ session('success') }}
|
||||
</div>
|
||||
@endif
|
||||
<form id="formPrediksi"
|
||||
action="/prediksi"
|
||||
method="POST"
|
||||
enctype="multipart/form-data">
|
||||
|
||||
<form action="/prediksi" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
|
||||
<input
|
||||
type="file"
|
||||
name="gambar"
|
||||
class="w-full border p-2 rounded mb-4"
|
||||
>
|
||||
<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>
|
||||
|
||||
</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
|
||||
type="submit"
|
||||
class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded w-full"
|
||||
>
|
||||
Upload & Prediksi
|
||||
</button>
|
||||
|
||||
</form>
|
||||
|
||||
<!-- Hasil Prediksi -->
|
||||
|
||||
@if(session('hasil'))
|
||||
<div class="bg-blue-100 text-blue-800 p-4 rounded mt-6">
|
||||
<p class="font-semibold">Hasil prediksi:</p>
|
||||
<p class="mt-2">Penyakit: <span class="font-semibold">{{ session('hasil') }}</span></p>
|
||||
<p>Confidence: <span class="font-semibold">{{ session('confidence') }}%</span></p>
|
||||
|
||||
<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>
|
||||
|
||||
</div>
|
||||
|
||||
@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>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="w-full bg-gray-200 rounded-full h-4">
|
||||
|
||||
<div class="bg-green-600 h-4 rounded-full"
|
||||
style="width: {{ $nilai }}%">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@endforeach
|
||||
|
||||
</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
|
||||
|
||||
@if(session('gambar'))
|
||||
<div class="mt-6">
|
||||
<img
|
||||
src="{{ asset('uploads/' . session('gambar')) }}"
|
||||
class="rounded shadow"
|
||||
>
|
||||
</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>
|
||||
@endif
|
||||
|
||||
</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>
|
||||
|
||||
</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>
|
||||
|
||||
<script>
|
||||
|
||||
function previewImage(event)
|
||||
{
|
||||
const preview = document.getElementById('preview');
|
||||
|
||||
preview.src = URL.createObjectURL(event.target.files[0]);
|
||||
|
||||
preview.classList.remove('hidden');
|
||||
}
|
||||
|
||||
const form = document.getElementById('formPrediksi');
|
||||
|
||||
form.addEventListener('submit', function() {
|
||||
|
||||
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>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -4,4 +4,10 @@
|
|||
use App\Http\Controllers\KlasifikasiController;
|
||||
|
||||
Route::get('/', [KlasifikasiController::class, 'index']);
|
||||
Route::post('/prediksi', [KlasifikasiController::class, 'prediksi']);
|
||||
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']);
|
||||