krushimitravit's picture
Update templates/index.html
9268474 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fertilizer Recommender & Usage Requirement Estimator</title>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<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=Outfit:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css">
<style>
:root {
--color-primary: #1a5d3a;
--color-primary-light: #2d7a52;
--color-primary-dark: #143d2e;
--color-accent: #198754;
--color-accent-light: #28a745;
--bg-light: #eaf6ee;
--bg-gradient-start: #f0fdf4;
--bg-gradient-end: #dcfce7;
--surface: #ffffff;
--text: #1f2937;
--text-light: #6b7280;
--border: #143d2e;
--border-light: rgba(20, 61, 46, 0.2);
--shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.04);
--shadow-md: 0 4px 16px rgba(0, 0, 0, 0.08);
--shadow-lg: 0 10px 40px rgba(0, 0, 0, 0.12);
--shadow-xl: 0 20px 60px rgba(0, 0, 0, 0.15);
--radius-sm: 8px;
--radius-md: 12px;
--radius-lg: 20px;
--radius-xl: 24px;
--space-xs: 0.5rem;
--space-sm: 1rem;
--space-md: 1.5rem;
--space-lg: 2rem;
--space-xl: 3rem;
--space-2xl: 4rem;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background: linear-gradient(135deg, var(--bg-gradient-start) 0%, var(--bg-gradient-end) 100%);
font-family: 'Outfit', sans-serif;
color: var(--text);
min-height: 100vh;
line-height: 1.6;
}
.main-container {
max-width: 1400px;
margin: 0 auto;
padding: 0 var(--space-md);
}
.heading {
background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-light) 100%);
color: white;
padding: var(--space-2xl) var(--space-md);
text-align: center;
position: relative;
overflow: hidden;
margin: 0 0 var(--space-xl) 0;
border-radius: 0 0 var(--radius-xl) var(--radius-xl);
}
.heading::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background:
radial-gradient(circle at 20% 50%, rgba(255,255,255,0.1) 0%, transparent 50%),
radial-gradient(circle at 80% 80%, rgba(255,255,255,0.08) 0%, transparent 50%);
pointer-events: none;
}
.heading i {
font-size: 3rem;
margin-bottom: var(--space-sm);
display: block;
opacity: 0.9;
}
.heading h1 {
font-size: 2.5rem;
font-weight: 700;
letter-spacing: -0.5px;
position: relative;
z-index: 1;
text-shadow: 0 2px 10px rgba(0,0,0,0.1);
margin: 0;
}
.heading p {
font-size: 1.1rem;
margin-top: var(--space-sm);
opacity: 0.95;
font-weight: 300;
}
.input-container {
background: var(--bg-light);
border-radius: 20px;
padding: var(--space-2xl);
box-shadow: var(--shadow-xl);
margin-bottom: var(--space-xl);
position: relative;
z-index: 10;
border: 2px solid var(--border);
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
.input-container:hover {
transform: translateY(-4px);
box-shadow: 0 25px 70px rgba(0, 0, 0, 0.18);
}
.input-container::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(90deg, var(--color-primary) 0%, var(--color-accent) 100%);
border-radius: var(--radius-xl) var(--radius-xl) 0 0;
}
.form-group {
margin-bottom: var(--space-md);
}
.form-group label {
display: flex;
align-items: center;
gap: var(--space-xs);
font-weight: 600;
color: var(--text);
margin-bottom: var(--space-xs);
font-size: 0.95rem;
}
.form-group label i {
font-size: 1.1rem;
color: var(--color-accent);
}
.form-control {
background: var(--bg-light);
border: 2px solid transparent;
border-radius: var(--radius-md);
font-family: 'Outfit', sans-serif;
font-size: 1rem;
color: var(--text);
width: 100%;
transition: all 0.3s ease;
box-shadow: var(--shadow-sm);
}
.form-control:hover {
border-color: var(--border-light);
}
.form-control:focus {
background: var(--surface);
outline: none;
border-color: var(--color-accent);
box-shadow: 0 0 0 4px rgba(25, 135, 84, 0.1), var(--shadow-md);
transform: translateY(-1px);
}
.predict-btn {
background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-accent) 100%);
color: white;
border: none;
border-radius: var(--radius-md);
padding: 1rem 2rem;
font-family: 'Outfit', sans-serif;
font-weight: 600;
font-size: 1.1rem;
cursor: pointer;
width: 100%;
margin-top: var(--space-md);
position: relative;
overflow: hidden;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(26, 93, 58, 0.3);
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
}
.predict-btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 25px rgba(26, 93, 58, 0.4);
}
/* --- LOADER STYLES --- */
#loader-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.85);
backdrop-filter: blur(8px);
display: none; /* Hidden by default */
justify-content: center;
align-items: center;
flex-direction: column;
z-index: 9999;
}
.loader-spinner {
width: 80px;
height: 80px;
border: 6px solid var(--bg-light);
border-top: 6px solid var(--color-primary);
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 20px;
box-shadow: var(--shadow-md);
}
.loader-text {
font-weight: 600;
color: var(--color-primary);
font-size: 1.2rem;
letter-spacing: 1px;
animation: pulse 1.5s ease-in-out infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
@keyframes pulse {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.6; transform: scale(1.05); }
}
/* -------------------- */
.result-container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--space-xl);
margin-top: var(--space-xl);
margin-bottom: var(--space-2xl);
animation: fadeInUp 0.6s ease-out;
}
@media (max-width: 968px) {
.result-container {
grid-template-columns: 1fr;
}
}
.left-container,
.right-container {
background: var(--surface);
border: 1px solid var(--border-light);
border-radius: var(--radius-lg);
padding: var(--space-xl);
box-shadow: var(--shadow-lg);
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
overflow: hidden;
}
.left-container::before,
.right-container::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 3px;
background: linear-gradient(90deg, var(--color-primary) 0%, var(--color-accent) 100%);
}
.fertilizer-name {
background: linear-gradient(135deg, rgba(26, 93, 58, 0.08) 0%, rgba(25, 135, 84, 0.08) 100%);
color: var(--color-primary);
font-weight: 700;
font-size: 2rem;
text-align: center;
padding: var(--space-md);
border-radius: var(--radius-md);
border-left: 5px solid var(--color-accent);
margin: var(--space-md) 0;
box-shadow: var(--shadow-sm);
}
.fertilizer-info {
background: var(--bg-light);
padding: var(--space-lg);
border-radius: var(--radius-md);
border: 1px solid var(--border-light);
margin-top: var(--space-md);
line-height: 1.8;
color: var(--text);
font-size: 1.05rem;
}
.section-heading {
color: var(--color-primary);
font-weight: 600;
text-align: center;
margin-bottom: var(--space-lg);
font-size: 1.5rem;
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--space-md);
margin-bottom: 0;
}
@media (max-width: 768px) {
.form-row {
grid-template-columns: 1fr;
}
}
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(30px); }
to { opacity: 1; transform: translateY(0); }
}
</style>
</head>
<body>
<!-- Full Screen Loader Overlay -->
<div id="loader-overlay">
<div class="loader-spinner"></div>
<div class="loader-text">Analyzing Soil Conditions...</div>
</div>
<div class="heading">
<i class="bi bi-flower2"></i>
<h1>Fertilizer Recommender & Usage Requirement Estimator</h1>
<p>Get intelligent fertilizer recommendations based on your soil and crop conditions</p>
</div>
<div class="main-container">
<!-- Added id="predictionForm" for JS handling -->
<form method="post" id="predictionForm" class="input-container">
<div class="form-row">
<div class="form-group">
<label for="temperature"><i class="bi bi-thermometer-half"></i> Temperature (°C)</label>
<input type="number" class="form-control" id="temperature" name="temperature" placeholder="Enter temperature" step="0.1" required>
</div>
<div class="form-group">
<label for="humidity"><i class="bi bi-droplet-half"></i> Humidity (%)</label>
<input type="number" class="form-control" id="humidity" name="humidity" placeholder="Enter humidity" step="0.1" min="0" max="100" required>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="moisture"><i class="bi bi-moisture"></i> Soil Moisture (%)</label>
<input type="number" class="form-control" id="moisture" name="moisture" placeholder="Enter soil moisture" step="0.1" min="0" max="100" required>
</div>
<div class="form-group">
<label for="soil_type"><i class="bi bi-layers-fill"></i> Soil Type</label>
<select class="form-control" id="soil_type" name="soil_type" required>
<option value="" disabled selected>Select soil type</option>
<option value="Black">Black</option>
<option value="Sandy">Sandy</option>
<option value="Loamy">Loamy</option>
<option value="Clayey">Clayey</option>
<option value="Red">Red</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="crop_type"><i class="bi bi-flower3"></i> Crop Type</label>
<select class="form-control" id="crop_type" name="crop_type" required>
<option value="" disabled selected>Select crop type</option>
<option value="Barley">Barley</option>
<option value="Coffee">Coffee</option>
<option value="Cotton">Cotton</option>
<option value="Ground Nuts">Ground Nuts</option>
<option value="Maize">Maize</option>
<option value="Millets">Millets</option>
<option value="Oil seeds">Oil seeds</option>
<option value="Paddy">Paddy</option>
<option value="Pulses">Pulses</option>
<option value="Rice">Rice</option>
<option value="Sugarcane">Sugarcane</option>
<option value="Tobacco">Tobacco</option>
<option value="Wheat">Wheat</option>
<option value="Other Variety">Other Variety</option>
</select>
</div>
<div class="form-group">
<label for="nitrogen"><i class="bi bi-circle-fill" style="color: #4169E1;"></i> Nitrogen (N)</label>
<input type="number" class="form-control" id="nitrogen" name="nitrogen" placeholder="Enter nitrogen level" step="0.1" min="0" required>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="potassium"><i class="bi bi-circle-fill" style="color: #FF6347;"></i> Potassium (K)</label>
<input type="number" class="form-control" id="potassium" name="potassium" placeholder="Enter potassium level" step="0.1" min="0" required>
</div>
<div class="form-group">
<label for="phosphorous"><i class="bi bi-circle-fill" style="color: #FFD700;"></i> Phosphorous (P)</label>
<input type="number" class="form-control" id="phosphorous" name="phosphorous" placeholder="Enter phosphorous level" step="0.1" min="0" required>
</div>
</div>
<button type="submit" class="predict-btn">
<i class="bi bi-search"></i> Recommend Fertilizer
</button>
</form>
{% if prediction %}
<div class="result-container">
<div class="left-container">
<h3 class="section-heading">Recommended Fertilizer</h3>
<div class="fertilizer-name">{{ fertilizer_name }}</div>
{% if pred_info %}
<div class="fertilizer-info">{{ pred_info|safe }}</div>
{% endif %}
</div>
<div class="right-container">
<h3 class="section-heading">Optimal Fertilizer Usage (kg/Acres)</h3>
<div class="gauge-container" style="display: flex; justify-content: center;">
<div id="gauge"></div>
</div>
<script>
var optimalUsage = {{ optimal_usage }};
var gaugeData = [{
type: 'indicator',
mode: 'gauge+number',
value: optimalUsage,
gauge: {
axis: { range: [0, 100], tickwidth: 2, tickcolor: "#1a5d3a" },
bar: { color: "#198754" },
bgcolor: "white",
borderwidth: 2,
steps: [
{ range: [0, 33], color: "#e8f5e9" },
{ range: [33, 66], color: "#a5d6a7" },
{ range: [66, 100], color: "#66bb6a" }
]
}
}];
var layout = {
width: 350, height: 250,
margin: { t: 25, b: 25, l: 25, r: 25 },
paper_bgcolor: 'rgba(0,0,0,0)',
font: { family: 'Outfit, sans-serif', color: '#1f2937' }
};
Plotly.newPlot('gauge', gaugeData, layout, {responsive: true, displayModeBar: false});
</script>
</div>
</div>
{% endif %}
</div>
<!-- Script to Trigger Loader -->
<script>
document.getElementById('predictionForm').addEventListener('submit', function() {
// Show the loader overlay
document.getElementById('loader-overlay').style.display = 'flex';
// Optional: Disable the button to prevent double submission
const btn = this.querySelector('.predict-btn');
btn.disabled = true;
btn.innerHTML = '<i class="bi bi-hourglass-split"></i> Processing...';
});
</script>
</body>
</html>