krushimitravit's picture
Update templates/index.html
7a2a2ec verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Crop Revenue Analyzer | Smart Farm Planning</title>
<!-- Google Fonts: Outfit -->
<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">
<!-- Bootstrap Icons -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css">
<style>
:root {
--primary: #1a5d3a;
--primary-dark: #143d2e;
--accent: #198754;
--danger: #dc3545;
--success: #198754;
--bg-page: #f8f9fa;
--bg-surface: #ffffff;
--text-dark: #212529;
--text-muted: #6c757d;
--border: #dee2e6;
--radius-lg: 20px;
--radius-md: 12px;
--radius-sm: 8px;
--shadow-card: 0 10px 40px rgba(0, 0, 0, 0.08);
--shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.06);
--font-main: 'Outfit', sans-serif;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: var(--font-main);
background-color: var(--bg-page);
color: var(--text-dark);
line-height: 1.6;
min-height: 100vh;
}
/* Hero Section */
.hero {
background: var(--primary);
color: white;
padding: 4rem 1rem 6rem;
text-align: center;
border-bottom-left-radius: 60px;
border-bottom-right-radius: 60px;
position: relative;
}
.hero h1 {
font-size: 2.5rem;
font-weight: 700;
margin-bottom: 0.5rem;
}
.hero p {
font-size: 1.1rem;
opacity: 0.9;
font-weight: 300;
max-width: 600px;
margin: 0 auto;
}
/* Container */
.container {
max-width: 1000px;
margin: 0 auto;
padding: 0 1rem;
}
/* Floating Card */
.card {
background: var(--bg-surface);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-card);
padding: 2.5rem;
margin-top: -3rem;
position: relative;
z-index: 10;
}
/* Form Grid */
.form-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1.5rem;
margin-bottom: 2rem;
}
.form-group {
display: flex;
flex-direction: column;
}
.form-label {
font-weight: 600;
font-size: 0.85rem;
color: var(--text-dark);
margin-bottom: 0.5rem;
text-transform: uppercase;
letter-spacing: 0.03em;
}
.form-label i {
color: var(--accent);
margin-right: 0.4rem;
}
.form-control {
background: var(--bg-page);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
padding: 0.85rem 1rem;
font-size: 1rem;
font-family: var(--font-main);
color: var(--text-dark);
transition: all 0.2s ease;
}
.form-control:focus {
outline: none;
border-color: var(--accent);
background: var(--bg-surface);
box-shadow: 0 0 0 4px rgba(25, 135, 84, 0.1);
}
/* Crop Table */
.crop-table {
width: 100%;
border-collapse: collapse;
margin-bottom: 1.5rem;
background: var(--bg-surface);
border-radius: var(--radius-md);
overflow: hidden;
box-shadow: var(--shadow-sm);
}
.crop-table th {
background: var(--primary);
color: white;
padding: 1rem;
text-align: left;
font-weight: 500;
font-size: 0.85rem;
text-transform: uppercase;
}
.crop-table td {
padding: 0.75rem 1rem;
border-bottom: 1px solid var(--border);
}
.crop-table select,
.crop-table input {
width: 100%;
padding: 0.6rem 0.8rem;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
font-family: var(--font-main);
}
.crop-table input:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 3px rgba(25, 135, 84, 0.1);
}
/* Buttons */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
padding: 0.85rem 1.5rem;
border-radius: var(--radius-sm);
font-family: var(--font-main);
font-size: 1rem;
font-weight: 500;
cursor: pointer;
border: none;
}
.btn-primary {
background: var(--primary);
color: white;
}
.btn-secondary {
background: var(--bg-surface);
color: var(--accent);
border: 1px solid var(--accent);
}
.btn-icon {
background: transparent;
color: #dc3545;
padding: 0.5rem;
border-radius: 50%;
}
/* Results */
.results-card {
background: var(--bg-surface);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-card);
padding: 2rem;
margin-top: 2rem;
animation: fadeIn 0.5s ease;
}
.results-header {
display: flex;
align-items: center;
gap: 0.75rem;
margin-bottom: 2rem;
padding-bottom: 1rem;
border-bottom: 2px solid var(--primary);
}
.results-header h2 {
margin: 0;
font-size: 1.5rem;
font-weight: 700;
color: var(--text-dark);
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* --- DASHBOARD --- */
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1.5rem;
margin-bottom: 3rem;
}
.stat-card {
background: linear-gradient(145deg, #ffffff, #f0fdf4);
border: 1px solid var(--border);
border-bottom: 4px solid var(--accent);
border-radius: var(--radius-md);
padding: 1.5rem;
text-align: center;
box-shadow: var(--shadow-sm);
transition: transform 0.2s;
}
.stat-card:hover {
transform: translateY(-3px);
}
.stat-value {
font-size: 2rem;
font-weight: 700;
color: var(--primary);
line-height: 1.2;
}
.stat-label {
font-size: 0.9rem;
color: var(--text-muted);
text-transform: uppercase;
margin-top: 0.5rem;
letter-spacing: 0.05em;
}
/* --- NEW GAP ANALYSIS CARD --- */
.gap-analysis-card {
background: #fdf2f2;
/* Light Red */
border-left: 5px solid #dc3545;
border-radius: var(--radius-sm);
padding: 1.5rem;
margin-bottom: 3rem;
}
.gap-analysis-card h4 {
color: #b02a37;
margin: 0 0 1rem 0;
font-size: 1.1rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
.gap-analysis-card ul {
margin: 0;
padding-left: 1.5rem;
}
.gap-analysis-card li {
margin-bottom: 0.5rem;
color: var(--text-dark);
font-size: 0.95rem;
}
.gap-analysis-card b {
color: #b02a37;
}
/* Single Breakdown Bar */
.breakdown-section {
background: #f8f9fa;
padding: 1.5rem 2rem;
border-radius: var(--radius-md);
margin-bottom: 3rem;
border: 1px solid var(--border);
}
.breakdown-title {
font-weight: 700;
margin-bottom: 1rem;
display: flex;
justify-content: space-between;
font-size: 1.05rem;
color: var(--text-dark);
}
.stacked-bar-container {
height: 28px;
width: 100%;
background: #e9ecef;
border-radius: 8px;
overflow: hidden;
display: flex;
}
.bar-cost {
background-color: #ef4444;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 0.8rem;
font-weight: 600;
}
.bar-profit {
background-color: var(--success);
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 0.8rem;
font-weight: 600;
}
.breakdown-legend {
display: flex;
justify-content: flex-end;
gap: 1.5rem;
margin-top: 0.75rem;
font-size: 0.85rem;
color: var(--text-muted);
}
.legend-item {
display: flex;
align-items: center;
gap: 0.4rem;
}
.dot {
width: 10px;
height: 10px;
border-radius: 50%;
}
/* Vertical Growth Timeline */
.growth-timeline {
position: relative;
padding: 1rem 0;
max-width: 900px;
margin: 0 auto 3rem;
}
.growth-timeline::before {
content: '';
position: absolute;
top: 0;
bottom: 0;
left: 50%;
width: 4px;
background: #d1e7dd;
transform: translateX(-50%);
border-radius: 2px;
}
.growth-node {
position: relative;
margin-bottom: 3rem;
width: 100%;
display: flex;
justify-content: center;
}
.growth-card {
background: white;
border: 1px solid var(--border);
border-radius: var(--radius-md);
width: 46%;
padding: 0;
box-shadow: var(--shadow-sm);
position: relative;
border-top: 4px solid var(--accent);
overflow: hidden;
}
.growth-node:nth-child(odd) .growth-card {
margin-right: auto;
border-top-right-radius: 0;
}
.growth-node:nth-child(even) .growth-card {
margin-left: auto;
border-top-left-radius: 0;
}
.growth-node::after {
content: '';
position: absolute;
top: 0;
left: 50%;
width: 16px;
height: 16px;
background: var(--accent);
border: 3px solid white;
border-radius: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 0 0 3px #d1e7dd;
z-index: 2;
}
.growth-header {
background: #f8f9fa;
padding: 1rem 1.5rem;
border-bottom: 1px solid var(--border);
font-weight: 700;
color: var(--primary);
display: flex;
justify-content: space-between;
align-items: center;
}
.annual-table {
width: 100%;
border-collapse: collapse;
font-size: 0.9rem;
}
.annual-table th {
background: white;
color: var(--text-muted);
font-size: 0.75rem;
text-transform: uppercase;
padding: 0.75rem 1rem;
border-bottom: 1px solid var(--border);
text-align: left;
}
.annual-table td {
padding: 0.75rem 1rem;
border-bottom: 1px solid #f0f0f0;
color: var(--text-dark);
vertical-align: middle;
}
.annual-table tr:last-child td {
border-bottom: none;
}
.season-badge {
font-family: monospace;
font-size: 0.75rem;
padding: 3px 8px;
background: #e9ecef;
border-radius: 4px;
color: var(--text-dark);
font-weight: 600;
display: inline-block;
width: 60px;
text-align: center;
}
/* Smart Table */
.smart-table-container {
overflow-x: auto;
margin-bottom: 3rem;
border: 1px solid var(--border);
border-radius: var(--radius-md);
box-shadow: var(--shadow-sm);
}
.smart-table {
width: 100%;
border-collapse: collapse;
background: white;
}
.smart-table th {
background: #f8f9fa;
color: var(--text-muted);
padding: 1rem 1.5rem;
text-align: left;
font-size: 0.8rem;
text-transform: uppercase;
border-bottom: 2px solid var(--border);
}
.smart-table td {
padding: 1rem 1.5rem;
border-bottom: 1px solid var(--border);
color: var(--text-dark);
}
.smart-table tr:last-child td {
border-bottom: none;
}
.positive {
color: var(--success);
font-weight: 700;
background: #f0fdf4;
padding: 2px 8px;
border-radius: 4px;
}
.negative {
color: var(--danger);
font-weight: 700;
background: #fef2f2;
padding: 2px 8px;
border-radius: 4px;
}
h3 {
font-size: 1.25rem;
color: var(--primary);
margin-bottom: 1.5rem;
font-weight: 700;
display: flex;
align-items: center;
gap: 0.5rem;
}
@media (max-width: 768px) {
.hero h1 {
font-size: 1.75rem;
}
.growth-node {
flex-direction: column;
padding-left: 30px;
margin-bottom: 2rem;
}
.growth-timeline::before {
left: 15px;
}
.growth-node::after {
left: 15px;
}
.growth-card {
width: 100%;
margin: 0 !important;
border-radius: var(--radius-md) !important;
}
}
.loading {
display: none;
text-align: center;
padding: 2rem;
}
.spinner {
margin: 0 auto 1rem;
width: 40px;
height: 40px;
border: 3px solid var(--border);
border-top-color: var(--primary);
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
</style>
</head>
<body>
<header class="hero">
<div class="container">
<h1>Crop Revenue Analyzer</h1>
<p>AI-powered crop swapping strategies for maximum profitability</p>
</div>
</header>
<main class="container">
<div class="card">
<form id="cropForm" action="/" method="POST">
<div class="form-grid">
<div class="form-group">
<label class="form-label" for="location"><i class="bi bi-geo-alt"></i> Location</label>
<input type="text" class="form-control" id="location" name="location" placeholder="Enter your location"
required>
</div>
<div class="form-group">
<label class="form-label" for="total_area"><i class="bi bi-rulers"></i> Total Area (acres)</label>
<input type="number" class="form-control" id="total_area" name="total_area" step="0.1" min="0.1"
placeholder="e.g., 10" required>
</div>
<div class="form-group">
<label class="form-label" for="language"><i class="bi bi-translate"></i> Language</label>
<select class="form-control" id="language" name="language">
<option value="English" selected>English</option>
<option value="Hindi">Hindi</option>
<option value="Marathi">Marathi</option>
<option value="Malayalam">Malayalam</option>
<option value="Tamil">Tamil</option>
<option value="Telugu">Telugu</option>
<option value="Bengali">Bengali</option>
<option value="Odia">Odia</option>
<option value="Urdu">Urdu</option>
</select>
</div>
</div>
<h3 class="section-title" style="margin-top: 0; font-size: 1.1rem; border:none; padding-left: 0;"><i
class="bi bi-flower2"></i> CURRENT ANNUAL CROP PLAN</h3>
<table class="crop-table" id="cropTable">
<thead>
<tr>
<th style="width: 25%">Season</th>
<th style="width: 35%">Crop Name</th>
<th style="width: 25%">Area (acres)</th>
<th style="width: 15%; text-align: center;">Action</th>
</tr>
</thead>
<tbody id="cropTableBody">
<tr>
<td>
<select name="crop_season" required>
<option value="Kharif">Kharif (Monsoon)</option>
<option value="Rabi">Rabi (Winter)</option>
<option value="Zaid">Zaid (Summer)</option>
</select>
</td>
<td><input type="text" name="crop_name" placeholder="Crop Name" required></td>
<td><input type="number" name="crop_area" step="0.1" min="0.1" placeholder="Acres" required></td>
<td style="text-align: center;">
<button type="button" class="btn btn-icon" onclick="removeRow(this)" title="Remove"><i
class="bi bi-trash"></i></button>
</td>
</tr>
</tbody>
</table>
<div class="btn-group">
<button type="button" class="btn btn-secondary" onclick="addRow()"><i class="bi bi-plus-circle"></i> Add More
Crops</button>
<button type="submit" class="btn btn-primary" id="submitBtn"><i class="bi bi-lightning-charge"></i> Analyze
Strategy</button>
</div>
</form>
<div class="loading" id="loadingSpinner">
<div class="spinner"></div>
<p>Generating your comprehensive 3-year plan...</p>
</div>
{% if error %}
<div class="alert-error">
<i class="bi bi-exclamation-triangle"></i>
<span>{{ error }}</span>
</div>
{% endif %}
</div>
{% if result %}
<div class="results-card">
<div class="results-header">
<i class="bi bi-bar-chart-line"></i>
<h2>Optimized Annual Strategy</h2>
</div>
<div class="results-content">
{{ result|safe }}
</div>
</div>
{% endif %}
</main>
<script>
function addRow() {
const tbody = document.getElementById('cropTableBody');
const row = document.createElement('tr');
row.innerHTML = `
<td>
<select name="crop_season" required>
<option value="Kharif">Kharif</option>
<option value="Rabi">Rabi</option>
<option value="Zaid">Zaid</option>
</select>
</td>
<td><input type="text" name="crop_name" placeholder="Crop Name" required></td>
<td><input type="number" name="crop_area" step="0.1" min="0.1" placeholder="Acres" required></td>
<td style="text-align: center;"><button type="button" class="btn btn-icon" onclick="removeRow(this)"><i class="bi bi-trash"></i></button></td>
`;
tbody.appendChild(row);
}
function removeRow(btn) {
if (document.querySelectorAll('#cropTableBody tr').length > 1) btn.closest('tr').remove();
}
document.getElementById('cropForm').addEventListener('submit', function () {
document.getElementById('submitBtn').disabled = true;
document.getElementById('submitBtn').innerHTML = '<i class="bi bi-hourglass-split"></i> Processing...';
document.getElementById('loadingSpinner').style.display = 'block';
});
</script>
</body>
</html>