FarmSmart-Agentic-AI / index.html
NSamson1's picture
Update index.html
3995253 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FarmSmart Agentic AI - Rwanda</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="style.css">
</head>
<body class="bg-green-50 font-sans">
<!-- Header/Navigation -->
<header class="bg-green-800 text-white shadow-md sticky top-0 z-50">
<div class="container mx-auto px-4 py-3 flex justify-between items-center">
<div class="flex items-center">
<i class="fas fa-leaf text-2xl mr-2"></i>
<h1 class="text-xl md:text-2xl font-bold">FarmSmart Rwanda</h1>
</div>
<button id="mobile-menu-button" class="md:hidden text-xl">
<i class="fas fa-bars"></i>
</button>
<nav class="hidden md:flex space-x-6">
<a href="#home" class="nav-link font-medium hover:text-green-200 transition">Home</a>
<a href="#crop-advisor" class="nav-link font-medium hover:text-green-200 transition">Crop Advisor</a>
<a href="#climate" class="nav-link font-medium hover:text-green-200 transition">Climate</a>
<a href="#market" class="nav-link font-medium hover:text-green-200 transition">Market</a>
<a href="#soil-water" class="nav-link font-medium hover:text-green-200 transition">Soil & Water</a>
<a href="#about" class="nav-link font-medium hover:text-green-200 transition">About</a>
</nav>
</div>
<!-- Mobile Menu -->
<div id="mobile-menu" class="hidden md:hidden bg-green-700 px-4 py-2">
<a href="#home" class="block py-2 border-b border-green-600">Home</a>
<a href="#crop-advisor" class="block py-2 border-b border-green-600">Crop Advisor</a>
<a href="#climate" class="block py-2 border-b border-green-600">Climate</a>
<a href="#market" class="block py-2 border-b border-green-600">Market</a>
<a href="#soil-water" class="block py-2 border-b border-green-600">Soil & Water</a>
<a href="#about" class="block py-2">About</a>
</div>
</header>
<!-- Hero Section -->
<section id="home" class="py-12 md:py-20 bg-gradient-to-b from-green-700 to-green-600 text-white">
<div class="container mx-auto px-4 text-center">
<h1 class="text-3xl md:text-5xl font-bold mb-6">Smart Farming, Smart Choices</h1>
<p class="text-xl md:text-2xl mb-8">🌱 Personalized Fertilizer & Crop Advice for Rwandan Farmers 🌱</p>
<div class="max-w-3xl mx-auto bg-white bg-opacity-20 rounded-lg p-6 backdrop-blur-sm">
<p class="text-lg md:text-xl mb-4">Get AI-powered recommendations based on your district, soil, and crop.</p>
<a href="#crop-advisor" class="inline-block bg-white text-green-800 font-bold py-3 px-8 rounded-full hover:bg-green-100 transition">
Get Started <i class="fas fa-arrow-right ml-2"></i>
</a>
</div>
</div>
</section>
<!-- Features Section -->
<section class="py-12 bg-white">
<div class="container mx-auto px-4">
<h2 class="text-2xl md:text-3xl font-bold text-center mb-12 text-green-800">How FarmSmart Helps You</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
<div class="bg-green-50 p-6 rounded-lg border border-green-100">
<div class="text-green-700 text-4xl mb-4"><i class="fas fa-calendar-alt"></i></div>
<h3 class="text-xl font-bold mb-3 text-green-800">Seasonal Advice</h3>
<p class="text-gray-700">Get recommendations tailored to Rwanda's three growing seasons (A, B, C).</p>
</div>
<div class="bg-green-50 p-6 rounded-lg border border-green-100">
<div class="text-green-700 text-4xl mb-4"><i class="fas fa-cloud-sun-rain"></i></div>
<h3 class="text-xl font-bold mb-3 text-green-800">Climate Analysis</h3>
<p class="text-gray-700">Localized weather forecasts and historical data for your district.</p>
</div>
<div class="bg-green-50 p-6 rounded-lg border border-green-100">
<div class="text-green-700 text-4xl mb-4"><i class="fas fa-flask"></i></div>
<h3 class="text-xl font-bold mb-3 text-green-800">Soil‑Specific Fertilizer</h3>
<p class="text-gray-700">Recommendations based on your soil's pH, nitrogen, phosphorus, and potassium levels.</p>
</div>
<div class="bg-green-50 p-6 rounded-lg border border-green-100">
<div class="text-green-700 text-4xl mb-4"><i class="fas fa-seedling"></i></div>
<h3 class="text-xl font-bold mb-3 text-green-800">Inter‑Cropping</h3>
<p class="text-gray-700">Discover crop combinations that improve soil health and income.</p>
</div>
<div class="bg-green-50 p-6 rounded-lg border border-green-100">
<div class="text-green-700 text-4xl mb-4"><i class="fas fa-tint"></i></div>
<h3 class="text-xl font-bold mb-3 text-green-800">Water Management</h3>
<p class="text-gray-700">Irrigation advice based on crop needs and local rainfall.</p>
</div>
<div class="bg-green-50 p-6 rounded-lg border border-green-100">
<div class="text-green-700 text-4xl mb-4"><i class="fas fa-chart-line"></i></div>
<h3 class="text-xl font-bold mb-3 text-green-800">Market Prices</h3>
<p class="text-gray-700">Current market prices in RWF and demand forecasts for major crops.</p>
</div>
</div>
</div>
</section>
<!-- Crop Advisor Section (Interactive) -->
<section id="crop-advisor" class="py-12 bg-green-100">
<div class="container mx-auto px-4">
<h2 class="text-2xl md:text-3xl font-bold text-center mb-8 text-green-800">🌾 FarmSmart Agentic AI – Fertilizer Advisor</h2>
<div class="bg-white rounded-lg shadow-md p-6 mb-6">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-4">
<div>
<label class="block text-gray-700 mb-2 font-medium">1. District</label>
<select id="district" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500">
<option value="Gasabo">Gasabo</option>
<option value="Kicukiro">Kicukiro</option>
<option value="Nyarugenge">Nyarugenge</option>
<option value="Bugesera">Bugesera</option>
<option value="Gatsibo">Gatsibo</option>
<option value="Kayonza">Kayonza</option>
<option value="Ngoma">Ngoma</option>
<option value="Nyagatare">Nyagatare</option>
<option value="Rwamagana">Rwamagana</option>
<option value="Burera">Burera</option>
<option value="Gakenke">Gakenke</option>
<option value="Gicumbi">Gicumbi</option>
<option value="Musanze">Musanze</option>
<option value="Rulindo">Rulindo</option>
<option value="Nyabihu">Nyabihu</option>
<option value="Ngororero">Ngororero</option>
<option value="Rubavu">Rubavu</option>
<option value="Rutsiro">Rutsiro</option>
<option value="Karongi">Karongi</option>
<option value="Nyanza">Nyanza</option>
<option value="Ruhango">Ruhango</option>
<option value="Nyamagabe">Nyamagabe</option>
<option value="Muhanga">Muhanga</option>
<option value="Kamonyi">Kamonyi</option>
<option value="Gisagara">Gisagara</option>
<option value="Huye">Huye</option>
<option value="Nyamasheke">Nyamasheke</option>
<option value="Rusizi">Rusizi</option>
</select>
</div>
<div>
<label class="block text-gray-700 mb-2 font-medium">2. Soil Type</label>
<select id="soilType" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500">
<option value="Acrisol">Acrisol (Sandy loam)</option>
<option value="Ferralsol">Ferralsol (Red clay)</option>
<option value="Andosol">Andosol (Volcanic ash)</option>
<option value="Histosol">Histosol (Peaty)</option>
<option value="Vertisol">Vertisol (Black clay)</option>
<option value="Regosol">Regosol (Sandy)</option>
<option value="Luvisol">Luvisol (Loamy)</option>
</select>
</div>
<div>
<label class="block text-gray-700 mb-2 font-medium">3. Crop</label>
<select id="crop" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500">
<option value="Maize">Maize</option>
<option value="Beans">Beans</option>
<option value="Irish Potatoes">Irish Potatoes</option>
<option value="Cassava">Cassava</option>
<option value="Banana">Banana</option>
<option value="Sorghum">Sorghum</option>
<option value="Rice">Rice</option>
<option value="Wheat">Wheat</option>
</select>
</div>
<div>
<label class="block text-gray-700 mb-2 font-medium">4. Season</label>
<select id="season" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500">
<option value="Season A (Sep-Jan)">Season A (Sep-Jan)</option>
<option value="Season B (Feb-Jun)">Season B (Feb-Jun)</option>
<option value="Season C (Jul-Aug)">Season C (Jul-Aug)</option>
</select>
</div>
</div>
<button id="getAdviceBtn" class="w-full md:w-auto bg-green-700 text-white font-bold py-3 px-8 rounded-lg hover:bg-green-800 transition flex items-center justify-center">
<i class="fas fa-robot mr-2"></i> Run Agentic AI
</button>
</div>
<!-- Agent Thinking / Progress -->
<div id="agent-thinking" class="bg-white rounded-lg shadow-md p-6 mb-6 hidden">
<h3 class="text-xl font-bold text-green-700 mb-4">🤖 Agent at Work</h3>
<div class="space-y-3">
<div id="step1" class="flex items-center text-gray-600"><i class="fas fa-circle-notch fa-spin mr-3 text-green-600"></i> Step 1: Interpreting your query...</div>
<div id="step2" class="flex items-center text-gray-600"><i class="fas fa-circle-notch fa-spin mr-3 text-green-600 hidden"></i> Step 2: Calling Soil Database tool...</div>
<div id="step3" class="flex items-center text-gray-600"><i class="fas fa-circle-notch fa-spin mr-3 text-green-600 hidden"></i> Step 3: Fetching Weather API...</div>
<div id="step4" class="flex items-center text-gray-600"><i class="fas fa-circle-notch fa-spin mr-3 text-green-600 hidden"></i> Step 4: Running Fertilizer Calculator...</div>
</div>
</div>
<!-- Recommendation Output -->
<div id="recommendation" class="bg-white rounded-lg shadow-md p-6 recommendation-card hidden">
<h3 class="text-xl font-bold text-green-700 mb-4">🌱 Personalized Recommendation</h3>
<div id="adviceText" class="prose max-w-none text-gray-800"></div>
</div>
<!-- Chat Interface -->
<div class="mt-8 bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold text-green-700 mb-4">💬 Chat with FarmSmart Agent</h3>
<div id="chatMessages" class="space-y-3 max-h-60 overflow-y-auto mb-4 p-2 border border-gray-200 rounded">
<div class="flex items-start">
<div class="bg-green-100 rounded-lg p-2 inline-block max-w-xs">Hello! I'm FarmSmart. Ask me about fertilizer for your crop.</div>
</div>
</div>
<div class="flex gap-2">
<input type="text" id="chatInput" placeholder="e.g., What fertilizer for maize in Musanze?" class="flex-1 p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500">
<button id="sendChatBtn" class="bg-green-700 text-white px-6 py-3 rounded-lg hover:bg-green-800">Send</button>
</div>
</div>
</div>
</section>
<!-- Climate Dashboard (simplified) -->
<section id="climate" class="py-12 bg-white">
<div class="container mx-auto px-4">
<h2 class="text-2xl md:text-3xl font-bold text-center mb-8 text-green-800">Climate Dashboard</h2>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<div class="bg-green-50 rounded-lg shadow-md p-6">
<h3 class="text-lg font-bold text-green-700 mb-2">Today's Weather (Kigali)</h3>
<div class="text-3xl font-bold">24°C</div>
<div>Partly cloudy, 70% humidity</div>
</div>
<div class="bg-green-50 rounded-lg shadow-md p-6">
<h3 class="text-lg font-bold text-green-700 mb-2">Rainfall (this month)</h3>
<div class="text-3xl font-bold">45mm</div>
<div>Below average</div>
</div>
<div class="bg-green-50 rounded-lg shadow-md p-6">
<h3 class="text-lg font-bold text-green-700 mb-2">Season Outlook</h3>
<div>Season B: Normal rains expected</div>
</div>
</div>
</div>
</section>
<!-- Footer -->
<footer class="bg-green-800 text-white py-8">
<div class="container mx-auto px-4 text-center">
<p>© 2026 FarmSmart Rwanda – AIMSRIC </p>
<p class="text-sm mt-2">Data sources: Rwanda Soil Information System (simplified), FAO, Rwanda Meteorology Agency</p>
</div>
</footer>
<script>
// ---------- Data ----------
const soilData = [
{ District: "Gasabo", pH: 5.5, N: 15, P: 8, K: 60 },
{ District: "Kicukiro", pH: 5.2, N: 12, P: 6, K: 45 },
{ District: "Nyarugenge", pH: 6.0, N: 18, P: 10, K: 80 },
{ District: "Bugesera", pH: 5.0, N: 10, P: 5, K: 40 },
{ District: "Gatsibo", pH: 6.2, N: 25, P: 12, K: 90 },
{ District: "Kayonza", pH: 5.4, N: 14, P: 7, K: 55 },
{ District: "Ngoma", pH: 5.1, N: 11, P: 5, K: 42 },
{ District: "Nyagatare", pH: 6.8, N: 30, P: 15, K: 110 },
{ District: "Rwamagana", pH: 5.3, N: 13, P: 6, K: 50 },
{ District: "Burera", pH: 5.8, N: 20, P: 9, K: 70 },
{ District: "Gakenke", pH: 5.9, N: 22, P: 10, K: 75 },
{ District: "Gicumbi", pH: 5.4, N: 14, P: 7, K: 52 },
{ District: "Musanze", pH: 6.0, N: 25, P: 12, K: 95 },
{ District: "Rulindo", pH: 5.5, N: 16, P: 8, K: 62 },
{ District: "Nyabihu", pH: 5.9, N: 21, P: 10, K: 73 },
{ District: "Ngororero", pH: 5.4, N: 14, P: 7, K: 50 },
{ District: "Rubavu", pH: 5.7, N: 18, P: 8, K: 65 },
{ District: "Rutsiro", pH: 5.0, N: 10, P: 5, K: 38 },
{ District: "Karongi", pH: 5.2, N: 12, P: 6, K: 46 },
{ District: "Nyanza", pH: 5.5, N: 15, P: 8, K: 60 },
{ District: "Ruhango", pH: 5.1, N: 11, P: 5, K: 40 },
{ District: "Nyamagabe", pH: 5.4, N: 14, P: 7, K: 52 },
{ District: "Muhanga", pH: 5.2, N: 12, P: 6, K: 44 },
{ District: "Kamonyi", pH: 5.5, N: 15, P: 8, K: 58 },
{ District: "Gisagara", pH: 5.1, N: 11, P: 5, K: 38 },
{ District: "Huye", pH: 5.5, N: 15, P: 8, K: 60 },
{ District: "Nyamasheke", pH: 5.2, N: 12, P: 6, K: 45 },
{ District: "Rusizi", pH: 5.3, N: 13, P: 6, K: 48 }
];
const cropRequirements = {
"Maize": { N: 120, P: 30, K: 40 },
"Beans": { N: 40, P: 30, K: 30 },
"Irish Potatoes": { N: 150, P: 50, K: 120 },
"Cassava": { N: 80, P: 20, K: 100 },
"Banana": { N: 200, P: 30, K: 300 },
"Sorghum": { N: 80, P: 20, K: 30 },
"Rice": { N: 100, P: 30, K: 40 },
"Wheat": { N: 120, P: 30, K: 40 }
};
// Mock weather per district (simplified)
function getMockWeather(district) {
const baseTemp = 24;
const conditions = ["Sunny", "Partly cloudy", "Light rain", "Cloudy"];
const rand = Math.floor(Math.random() * 4);
return {
temp: baseTemp + Math.floor(Math.random() * 5) - 2,
condition: conditions[rand],
humidity: 65 + Math.floor(Math.random() * 20),
rainfall_mm: Math.floor(Math.random() * 10)
};
}
// Fertilizer recommendation logic (same as Streamlit)
function recommendFertilizer(crop, soilProps) {
const req = cropRequirements[crop] || { N: 100, P: 30, K: 40 };
const convFactor = 2; // mg/kg to kg/ha rough
const soilN = soilProps.N * convFactor;
const soilP = soilProps.P * convFactor;
const soilK = soilProps.K * convFactor;
const efficiency = 0.5;
const recN = Math.max(0, (req.N - soilN * 0.3) / efficiency);
const recP = Math.max(0, (req.P - soilP * 0.1) / efficiency);
const recK = Math.max(0, (req.K - soilK * 0.2) / efficiency);
return {
N: Math.round(recN),
P: Math.round(recP),
K: Math.round(recK),
Urea: Math.round(recN / 0.46),
DAP: recP > 0 ? Math.round(recP / 0.46) : 0,
MOP: Math.round(recK / 0.6)
};
}
// Synthesize answer
function synthesizeAnswer(crop, soil, weather, fert, district, season) {
return `🌾 **Crop:** ${crop}
📍 **Location:** ${district} (${season})
🧪 **Soil Health:** pH ${soil.pH}, N: ${soil.N} mg/kg, P: ${soil.P} mg/kg, K: ${soil.K} mg/kg
☁️ **Weather:** ${weather.temp}°C, ${weather.condition}, Humidity ${weather.humidity}%, Rainfall ${weather.rainfall_mm}mm
💊 **Recommended Fertilizer (kg/ha):**
- Nitrogen (N): ${fert.N} kg
- Phosphorus (P): ${fert.P} kg
- Potassium (K): ${fert.K} kg
**Product equivalents:**
- Urea (46-0-0): ${fert.Urea} kg/ha
- DAP (18-46-0): ${fert.DAP} kg/ha
- MOP (0-0-60): ${fert.MOP} kg/ha
🌱 **Tip:** Apply in split doses. Incorporate into soil. Consider legumes for nitrogen fixation.`;
}
// ---------- UI Elements ----------
const getAdviceBtn = document.getElementById('getAdviceBtn');
const agentThinking = document.getElementById('agent-thinking');
const recommendationDiv = document.getElementById('recommendation');
const adviceText = document.getElementById('adviceText');
const step1 = document.getElementById('step1');
const step2 = document.getElementById('step2');
const step3 = document.getElementById('step3');
const step4 = document.getElementById('step4');
const stepIcons = [
step1.querySelector('i'),
step2.querySelector('i'),
step3.querySelector('i'),
step4.querySelector('i')
];
// Reset steps
function resetSteps() {
stepIcons.forEach(icon => icon.classList.add('hidden'));
step1.querySelector('i').classList.remove('hidden');
step2.querySelector('i').classList.add('hidden');
step3.querySelector('i').classList.add('hidden');
step4.querySelector('i').classList.add('hidden');
step1.querySelector('i').classList.add('fa-spin');
}
// Run agent simulation
getAdviceBtn.addEventListener('click', function() {
const district = document.getElementById('district').value;
const soilType = document.getElementById('soilType').value;
const crop = document.getElementById('crop').value;
const season = document.getElementById('season').value;
// Show thinking box
agentThinking.classList.remove('hidden');
recommendationDiv.classList.add('hidden');
resetSteps();
// Simulate steps with delays
setTimeout(() => {
step1.querySelector('i').classList.add('hidden');
step2.querySelector('i').classList.remove('hidden');
}, 800);
setTimeout(() => {
step2.querySelector('i').classList.add('hidden');
step3.querySelector('i').classList.remove('hidden');
}, 1600);
setTimeout(() => {
step3.querySelector('i').classList.add('hidden');
step4.querySelector('i').classList.remove('hidden');
}, 2400);
setTimeout(() => {
step4.querySelector('i').classList.add('hidden');
// Get soil data
const soilRow = soilData.find(d => d.District === district);
const soilProps = {
pH: soilRow.pH,
N: soilRow.N,
P: soilRow.P,
K: soilRow.K
};
const weather = getMockWeather(district);
const fert = recommendFertilizer(crop, soilProps);
const answer = synthesizeAnswer(crop, soilProps, weather, fert, district, season);
adviceText.innerHTML = answer.replace(/\n/g, '<br>');
recommendationDiv.classList.remove('hidden');
agentThinking.classList.add('hidden');
}, 3200);
});
// Chat functionality (simple)
const chatMessages = document.getElementById('chatMessages');
const chatInput = document.getElementById('chatInput');
const sendChatBtn = document.getElementById('sendChatBtn');
function addChatMessage(text, isUser = false) {
const div = document.createElement('div');
div.className = 'flex items-start ' + (isUser ? 'justify-end' : '');
const bubble = document.createElement('div');
bubble.className = isUser ? 'bg-green-600 text-white rounded-lg p-2 max-w-xs' : 'bg-green-100 rounded-lg p-2 max-w-xs';
bubble.innerText = text;
div.appendChild(bubble);
chatMessages.appendChild(div);
chatMessages.scrollTop = chatMessages.scrollHeight;
}
sendChatBtn.addEventListener('click', function() {
const question = chatInput.value.trim();
if (!question) return;
addChatMessage(question, true);
chatInput.value = '';
// Simulate agent response
setTimeout(() => {
const lower = question.toLowerCase();
let response = "I can help with fertilizer advice. Please use the form above or ask about a specific crop and district.";
if (lower.includes('maize') || lower.includes('corn')) {
response = "For maize in most districts, a basal dose of DAP and top dressing with Urea is recommended. Use the advisor tool for exact rates.";
} else if (lower.includes('musanze')) {
response = "Musanze has volcanic Andosols rich in organic matter. Potatoes and maize grow well there. I recommend getting a soil test for precise fertilizer needs.";
}
addChatMessage(response);
}, 1000);
});
// Mobile menu toggle
document.getElementById('mobile-menu-button').addEventListener('click', function() {
const menu = document.getElementById('mobile-menu');
menu.classList.toggle('hidden');
});
</script>
</body>
</html>