Spaces:
Sleeping
Sleeping
| <html lang="id"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <title>Plantopia</title> | |
| <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;500;700&display=swap" rel="stylesheet" /> | |
| <style> | |
| * { | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: 'Poppins', sans-serif; | |
| background-color: #f9fafb; | |
| display: flex; | |
| justify-content: center; | |
| padding: 2rem; | |
| } | |
| .container { | |
| max-width: 720px; | |
| width: 100%; | |
| background: #fff; | |
| border-radius: 20px; | |
| padding: 2rem; | |
| text-align: center; | |
| box-shadow: 0 0 20px rgba(0, 0, 0, 0.05); | |
| } | |
| h1 { | |
| font-size: 1.8rem; | |
| font-weight: 700; | |
| color: #1a202c; | |
| } | |
| p.subtitle { | |
| color: #4a5568; | |
| margin-bottom: 2rem; | |
| } | |
| #dropArea { | |
| border: 2px dashed #38a169; | |
| border-radius: 12px; | |
| padding: 2.5rem 1rem; | |
| margin-bottom: 1.5rem; | |
| cursor: pointer; | |
| transition: background 0.3s ease; | |
| } | |
| #dropArea.dragover { | |
| background-color: #e6fffa; | |
| } | |
| #dropArea img { | |
| width: 48px; | |
| margin-bottom: 1rem; | |
| } | |
| #dropArea p { | |
| margin: 0; | |
| color: #2d3748; | |
| } | |
| input[type="file"] { | |
| display: none; | |
| } | |
| .buttons { | |
| display: flex; | |
| justify-content: center; | |
| gap: 1rem; | |
| margin-bottom: 1rem; | |
| } | |
| .btn-upload { | |
| background-color: #2f855a; | |
| color: white; | |
| } | |
| .btn-predict { | |
| background-color: #edf2f7; | |
| color: #2d3748; | |
| } | |
| .buttons button { | |
| padding: 0.6rem 1.5rem; | |
| border: none; | |
| border-radius: 8px; | |
| font-weight: 500; | |
| cursor: pointer; | |
| transition: all 0.2s ease; | |
| } | |
| .buttons button:hover { | |
| opacity: 0.85; | |
| } | |
| #preview { | |
| margin-top: 1rem; | |
| border-radius: 12px; | |
| max-width: 100%; | |
| display: none; | |
| } | |
| .result { | |
| margin-top: 1rem; | |
| font-weight: bold; | |
| } | |
| .steps { | |
| margin-top: 2rem; | |
| display: flex; | |
| justify-content: space-between; | |
| gap: 1rem; | |
| background: #f7fafc; | |
| border-radius: 16px; | |
| padding: 1rem; | |
| flex-wrap: wrap; | |
| } | |
| .step { | |
| flex: 1; | |
| min-width: 180px; | |
| text-align: center; | |
| } | |
| .step img { | |
| height: 40px; | |
| margin-bottom: 0.5rem; | |
| } | |
| .step p { | |
| font-size: 0.9rem; | |
| color: #4a5568; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <h1>“Deteksi Sekarang, Selamatkan Tanamanmu!”</h1> | |
| <p class="subtitle"> | |
| Unggah foto atau gunakan kamera untuk mendeteksi penyakit tanamanmu secara instan. Cepat, akurat, dan mudah digunakan. | |
| </p> | |
| <input type="file" id="fileInput" accept="image/*" /> | |
| <div id="dropArea"> | |
| <img src="https://img.icons8.com/ios-filled/100/upload.png" alt="upload" /> | |
| <p>atau upload gambar <strong>lewat sini</strong></p> | |
| </div> | |
| <div class="buttons"> | |
| <button class="btn-upload" onclick="fileInput.click()">Unggah</button> | |
| <button class="btn-predict" onclick="submitImage()">Prediksi</button> | |
| </div> | |
| <div class="result" id="result"></div> | |
| <img id="preview" /> | |
| <div class="steps"> | |
| <div class="step"> | |
| <img src="https://img.icons8.com/ios/100/leaf.png" alt="leaf" /> | |
| <p>Ambil foto daun atau bagian tanaman yang menunjukkan gejala.</p> | |
| </div> | |
| <div class="step"> | |
| <img src="https://img.icons8.com/ios/100/artificial-intelligence.png" alt="ai" /> | |
| <p>Sistem kami akan menganalisis gambar secara otomatis.</p> | |
| </div> | |
| <div class="step"> | |
| <img src="https://img.icons8.com/ios/100/stethoscope.png" alt="treatment" /> | |
| <p>Lihat jenis penyakit dan cara mengatasinya.</p> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| const dropArea = document.getElementById("dropArea"); | |
| const fileInput = document.getElementById("fileInput"); | |
| const preview = document.getElementById("preview"); | |
| const resultDiv = document.getElementById("result"); | |
| let selectedFile = null; // ✅ Global file tracker | |
| dropArea.addEventListener("click", () => fileInput.click()); | |
| dropArea.addEventListener("dragover", (e) => { | |
| e.preventDefault(); | |
| dropArea.classList.add("dragover"); | |
| }); | |
| dropArea.addEventListener("dragleave", () => { | |
| dropArea.classList.remove("dragover"); | |
| }); | |
| dropArea.addEventListener("drop", (e) => { | |
| e.preventDefault(); | |
| dropArea.classList.remove("dragover"); | |
| const file = e.dataTransfer.files[0]; | |
| handleFile(file); | |
| }); | |
| fileInput.addEventListener("change", () => { | |
| const file = fileInput.files[0]; | |
| handleFile(file); | |
| }); | |
| function handleFile(file) { | |
| if (!file || !file.type.startsWith("image/")) { | |
| alert("Silakan pilih gambar yang valid."); | |
| return; | |
| } | |
| selectedFile = file; // ✅ Track file global | |
| const reader = new FileReader(); | |
| reader.onload = () => { | |
| preview.src = reader.result; | |
| preview.style.display = "block"; | |
| resultDiv.innerHTML = "✅ Gambar berhasil dimuat. Siap untuk diproses."; | |
| }; | |
| reader.readAsDataURL(file); | |
| } | |
| function submitImage() { | |
| if (!selectedFile) { | |
| alert("Silakan unggah gambar terlebih dahulu."); | |
| return; | |
| } | |
| resultDiv.innerHTML = "⏳ Mengirim gambar untuk prediksi..."; | |
| const formData = new FormData(); | |
| formData.append("file", selectedFile); | |
| fetch("http://localhost:8000/predict", { | |
| method: "POST", | |
| body: formData | |
| }) | |
| .then((res) => res.json()) | |
| .then((data) => { | |
| resultDiv.innerHTML = ` | |
| <p><strong>${data.predicted_label}</strong> (${data.confidence.toFixed(2)}%)</p> | |
| <img src="${preview.src}" style="max-width:100%; border-radius:10px; margin-top:1rem;" /> | |
| `; | |
| }) | |
| .catch((err) => { | |
| resultDiv.innerHTML = "❌ Gagal memproses gambar."; | |
| console.error(err); | |
| }); | |
| } | |
| </script> | |
| </body> | |
| </html> | |