Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Smart Irrigation Predictor</title> | |
| <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet"> | |
| <style> | |
| body { | |
| background-color: #f4f8f4; | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| } | |
| .navbar { | |
| background-color: #28a745; | |
| color: white; | |
| } | |
| .navbar-brand { | |
| font-weight: bold; | |
| } | |
| .container { | |
| margin-top: 30px; | |
| margin-bottom: 30px; | |
| } | |
| .card { | |
| border: none; | |
| border-radius: 15px; | |
| box-shadow: 0 4px 12px rgba(0,0,0,0.1); | |
| } | |
| .card-header { | |
| background-color: #28a745; | |
| color: white; | |
| text-align: center; | |
| font-weight: bold; | |
| font-size: 1.5rem; | |
| border-top-left-radius: 15px; | |
| border-top-right-radius: 15px; | |
| } | |
| #weather_info { | |
| background-color: #e9f5e9; | |
| border: 1px solid #28a745; | |
| padding: 15px; | |
| border-radius: 5px; | |
| min-height: 100px; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| } | |
| .form-control { | |
| border-color: #28a745; | |
| background-color: #fafffa; | |
| } | |
| .btn-green { | |
| background-color: #28a745; | |
| color: white; | |
| font-weight: bold; | |
| width: 100%; | |
| padding: 10px; | |
| border-radius: 5px; | |
| transition: background-color 0.3s; | |
| } | |
| .btn-green:hover { | |
| background-color: #218838; | |
| } | |
| .hero-image { | |
| width: 100%; | |
| height: 100%; | |
| object-fit: cover; | |
| border-radius: 10px; | |
| max-height: 450px; /* Control max height */ | |
| } | |
| /* --- Full Page Loader Styles --- */ | |
| #page-loader { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background-color: rgba(0, 0, 0, 0.5); /* Semi-transparent background */ | |
| z-index: 9999; | |
| display: none; /* Hidden by default */ | |
| justify-content: center; | |
| align-items: center; | |
| } | |
| .loader-spinner { | |
| width: 4rem; | |
| height: 4rem; | |
| border-width: .4em; /* Makes spinner thicker */ | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- Full Page Loader HTML --> | |
| <div id="page-loader"> | |
| <div class="spinner-border text-light loader-spinner" role="status"> | |
| <span class="sr-only">Loading...</span> | |
| </div> | |
| </div> | |
| <nav class="navbar navbar-dark"> | |
| <span class="navbar-brand mb-0 h1 mx-auto">🌱 Smart Irrigation Water Predictor</span> | |
| </nav> | |
| <div class="container"> | |
| <div class="card"> | |
| <div class="card-header"> | |
| Predict Irrigation Water Requirement | |
| </div> | |
| <div class="card-body p-lg-5"> | |
| <form action="/predict" method="POST" id="prediction-form"> | |
| <div class="row align-items-center"> | |
| <!-- Column 1: Form Inputs --> | |
| <!-- order-2 makes it second on mobile, order-lg-1 makes it first on desktop --> | |
| <div class="col-lg-6 order-2 order-lg-1"> | |
| <div class="form-group"> | |
| <label for="crop_type"><strong>Crop Type</strong></label> | |
| <select class="form-control" id="crop_type" name="crop_type" required> | |
| <option value="BANANA">Banana</option> | |
| <option value="BEAN">Bean</option> | |
| <!-- Add other crop options here --> | |
| <option value="CABBAGE">Cabbage</option> | |
| <option value="CITRUS">Citrus</option> | |
| <option value="COTTON">Cotton</option> | |
| <option value="MAIZE">Maize</option> | |
| <option value="MELON">Melon</option> | |
| <option value="MUSTARD">Mustard</option> | |
| <option value="ONION">Onion</option> | |
| <option value="OTHER">Other</option> | |
| <option value="POTATO">Potato</option> | |
| <option value="RICE">Rice</option> | |
| <option value="SOYABEAN">Soyabean</option> | |
| <option value="SUGARCANE">Sugarcane</option> | |
| <option value="TOMATO">Tomato</option> | |
| <option value="WHEAT">Wheat</option> | |
| </select> | |
| </div> | |
| <div class="form-group"> | |
| <label for="soil_type"><strong>Soil Type</strong></label> | |
| <select class="form-control" id="soil_type" name="soil_type" required> | |
| <option value="DRY">Dry</option> | |
| <option value="HUMID">Humid</option> | |
| <option value="WET">Wet</option> | |
| </select> | |
| </div> | |
| <div class="form-group"> | |
| <label for="city"><strong>City / Location</strong></label> | |
| <input type="text" class="form-control" id="city" name="city" placeholder="Enter city for weather data" required> | |
| </div> | |
| <button type="button" class="btn btn-secondary btn-block" id="fetch-weather-btn" onclick="fetchWeather()">Fetch Weather Data</button> | |
| <div id="weather_info" class="mt-3" style="display: none;"> | |
| <div id="weather_data"></div> | |
| </div> | |
| <div class="form-group mt-3"> | |
| <label for="motor_capacity"><strong>Motor Capacity (liters/sec)</strong></label> | |
| <input type="text" class="form-control" id="motor_capacity" name="motor_capacity" required> | |
| </div> | |
| <button type="submit" class="btn btn-green mt-3" id="predict-btn">Predict Water Requirement</button> | |
| </div> | |
| <!-- Column 2: Image --> | |
| <!-- order-1 makes it first on mobile, order-lg-2 makes it second on desktop --> | |
| <div class="col-lg-6 order-1 order-lg-2 mb-4 mb-lg-0"> | |
| <img src="/static/images/img.png" alt="Smart Irrigation" class="hero-image"> | |
| </div> | |
| </div> | |
| </form> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| function fetchWeather() { | |
| // This function remains the same as before | |
| const city = document.getElementById('city').value; | |
| if (!city) { | |
| alert('Please enter a city name first.'); | |
| return; | |
| } | |
| const weatherDiv = document.getElementById('weather_data'); | |
| const weatherInfoBox = document.getElementById('weather_info'); | |
| const fetchBtn = document.getElementById('fetch-weather-btn'); | |
| weatherInfoBox.style.display = 'flex'; | |
| weatherDiv.innerHTML = `<div class="spinner-border text-success" role="status"><span class="sr-only">Loading...</span></div>`; | |
| fetchBtn.disabled = true; | |
| fetch(`/fetch_weather?city=${city}`) | |
| .then(response => { | |
| if (!response.ok) throw new Error('City not found or server error.'); | |
| return response.json(); | |
| }) | |
| .then(data => { | |
| if (data) { | |
| weatherDiv.innerHTML = ` | |
| <div style="text-align: left; width: 100%;"> | |
| <strong>Weather:</strong> ${data.description}<br> | |
| <strong>Temperature:</strong> ${data.temperature}°C<br> | |
| <strong>Humidity:</strong> ${data.humidity}%<br> | |
| <strong>Pressure:</strong> ${data.pressure} hPa | |
| </div> | |
| `; | |
| } else { | |
| weatherDiv.innerHTML = 'Could not retrieve weather data.'; | |
| } | |
| }) | |
| .catch(error => { | |
| console.error('Error fetching weather:', error); | |
| weatherDiv.innerHTML = 'An error occurred. Please check the city name.'; | |
| }) | |
| .finally(() => { | |
| fetchBtn.disabled = false; | |
| }); | |
| } | |
| // --- NEW: TRIGGER FULL PAGE LOADER ON FORM SUBMISSION --- | |
| document.getElementById('prediction-form').addEventListener('submit', function(event) { | |
| // Basic form validation check | |
| if (!this.checkValidity()) { | |
| // If form is invalid, let the browser handle the validation messages | |
| return; | |
| } | |
| // Show the full-page loader | |
| document.getElementById('page-loader').style.display = 'flex'; | |
| // Disable the predict button to prevent multiple submissions | |
| document.getElementById('predict-btn').disabled = true; | |
| }); | |
| </script> | |
| </body> | |
| </html> |