From 9e72f82975151797ca66ed6fe3673ada72f22cf9 Mon Sep 17 00:00:00 2001 From: Aditya8369 Date: Thu, 28 May 2026 15:52:05 +0530 Subject: [PATCH 1/3] =?UTF-8?q?Bug=20:disease.js=20&=20disease.html=20?= =?UTF-8?q?=E2=80=93=20Race=20Condition=20in=20Image=20Upload?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- disease.js | 61 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/disease.js b/disease.js index 309a20124..8d37f97ca 100644 --- a/disease.js +++ b/disease.js @@ -255,6 +255,8 @@ const loading = document.getElementById("loading"); const resultsDiv = document.getElementById("results"); let selectedFile = null; +let uploadInProgress = false; +let fileSelectionToken = 0; // File upload handling uploadArea.addEventListener("click", () => fileInput.click()); @@ -308,7 +310,7 @@ fileInput.addEventListener("change", (e) => { // Analysis function analyzeBtn.addEventListener("click", async () => { - if (!selectedFile) return; + if (uploadInProgress || !selectedFile) return; loading.style.display = "block"; resultsDiv.innerHTML = ""; @@ -470,40 +472,59 @@ function validateImage(file) { return true; } +function readPreviewDataUrl(file) { + return new Promise((resolve, reject) => { + const reader = new FileReader(); + + reader.onload = (event) => resolve(event.target.result); + reader.onerror = () => reject(new Error("Error loading image preview.")); + reader.readAsDataURL(file); + }); +} + // Enhanced file handling with validation -function handleFileSelect(file) { +async function handleFileSelect(file) { + const currentSelectionToken = ++fileSelectionToken; + try { validateImage(file); - selectedFile = file; + uploadInProgress = true; + selectedFile = null; + analyzeBtn.disabled = true; previewContainer.innerHTML = '
'; - const reader = new FileReader(); - reader.onload = (e) => { - previewContainer.innerHTML = `Plant preview`; - analyzeBtn.disabled = false; - resultsDiv.innerHTML = ""; - document.getElementById("downloadPdfBtn").style.display = "none"; + const previewDataUrl = await readPreviewDataUrl(file); - document.getElementById("modelStatus").innerHTML = - "🔍 Image loaded - Ready for analysis"; - document.getElementById("modelStatus").className = - "status-indicator status-warning"; - }; + if (currentSelectionToken !== fileSelectionToken) { + return; + } + + selectedFile = file; + previewContainer.innerHTML = `Plant preview`; + resultsDiv.innerHTML = ""; + document.getElementById("downloadPdfBtn").style.display = "none"; - reader.onerror = () => { - previewContainer.innerHTML = - '
❌ Error loading image
'; - selectedFile = null; - }; + document.getElementById("modelStatus").innerHTML = + "🔍 Image loaded - Ready for analysis"; + document.getElementById("modelStatus").className = + "status-indicator status-warning"; - reader.readAsDataURL(file); + analyzeBtn.disabled = false; } catch (error) { + if (currentSelectionToken !== fileSelectionToken) { + return; + } + alert(error.message); previewContainer.innerHTML = '
📷 Upload an image to get started
'; selectedFile = null; analyzeBtn.disabled = true; + } finally { + if (currentSelectionToken === fileSelectionToken) { + uploadInProgress = false; + } } } From 26f0b19bba30ec63831e159d07320dabd72aa2cd Mon Sep 17 00:00:00 2001 From: Aditya8369 Date: Thu, 28 May 2026 16:14:38 +0530 Subject: [PATCH 2/3] Fertilizer Recommendation System --- README.md | 2 + domain/README.md | 2 + domain/fertilizer.schema.js | 79 +++++++++++++++++++++++++++++++++++++ domain/index.js | 5 +++ domain/validate.js | 4 ++ 5 files changed, 92 insertions(+) create mode 100644 domain/fertilizer.schema.js diff --git a/README.md b/README.md index 1ef914b16..dc82fe74a 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,7 @@ Note: Backend and frontend must be running simultaneously for proper functionali ## 🌟 Core Features - 🌾 Crop Recommendation +- 🌿 Fertilizer Recommendation - 📉 Yield Prediction - 🔬 Disease Detection - � **AI Chatbot** - Platform guidance & agriculture support @@ -226,6 +227,7 @@ AGRITECH/ │ ├── 📁 css/ # Stylesheets │ └── 📁 js/ # Client-side scripts ├── 📁 Crop Recommendation/ # 🌾 Crop recommendation module +├── 📁 Fertiliser Recommendation System/ # 🌿 Fertilizer recommendation ML module ├── 📁 Disease Prediction/ # 🔬 Disease detection module ├── 📁 Crop Yield Prediction/ # 📊 Yield forecasting module ├── 📁 Community/ # 💬 community/forum backend diff --git a/domain/README.md b/domain/README.md index 3f06e4d9d..e55456451 100644 --- a/domain/README.md +++ b/domain/README.md @@ -9,6 +9,8 @@ This directory defines shared domain contracts used across AgriTech. ## Current Schemas - Crop +- FertilizerRecommendationInput +- FertilizerRecommendation - GrowthStage - SoilData - PredictionResult diff --git a/domain/fertilizer.schema.js b/domain/fertilizer.schema.js new file mode 100644 index 000000000..577660f78 --- /dev/null +++ b/domain/fertilizer.schema.js @@ -0,0 +1,79 @@ +/** + * Fertilizer recommendation schema + */ + +export const FertilizerRecommendationInputSchema = { + $id: "FertilizerRecommendationInput", + type: "object", + required: [ + "temperature", + "humidity", + "moisture", + "soilType", + "cropType", + "nitrogen", + "phosphorous", + "potassium" + ], + additionalProperties: false, + properties: { + temperature: { + type: "number", + description: "Ambient temperature in degrees Celsius" + }, + humidity: { + type: "number", + description: "Relative humidity percentage" + }, + moisture: { + type: "number", + description: "Soil moisture percentage" + }, + soilType: { + type: "string", + description: "Categorical soil type" + }, + cropType: { + type: "string", + description: "Categorical crop type" + }, + nitrogen: { + type: "number", + description: "Nitrogen content" + }, + phosphorous: { + type: "number", + description: "Phosphorous content" + }, + potassium: { + type: "number", + description: "Potassium content" + } + } +}; + +export const FertilizerRecommendationSchema = { + $id: "FertilizerRecommendation", + type: "object", + required: ["fertilizerName", "confidence", "inputs"], + additionalProperties: false, + properties: { + fertilizerName: { + type: "string", + description: "Recommended fertilizer label" + }, + confidence: { + type: "number", + description: "Prediction confidence score (0-1)" + }, + inputs: FertilizerRecommendationInputSchema, + modelVersion: { + type: "string", + description: "Version of the fertilizer recommendation model" + }, + createdAt: { + type: "string", + description: "ISO timestamp when the recommendation was generated" + } + } +}; \ No newline at end of file diff --git a/domain/index.js b/domain/index.js index 12eae6bd2..e3a696ae9 100644 --- a/domain/index.js +++ b/domain/index.js @@ -1,10 +1,13 @@ import { CropSchema } from "./crop.schema.js"; +import { FertilizerRecommendationInputSchema, FertilizerRecommendationSchema } from "./fertilizer.schema.js"; import { GrowthStageSchema } from "./growthStage.schema.js"; import { PredictionResultSchema } from "./prediction.schema.js"; import { SoilDataSchema } from "./soil.schema.js"; export { CropSchema, + FertilizerRecommendationInputSchema, + FertilizerRecommendationSchema, GrowthStageSchema, PredictionResultSchema, SoilDataSchema @@ -12,6 +15,8 @@ export { export const DomainSchemas = { Crop: CropSchema, + FertilizerRecommendationInput: FertilizerRecommendationInputSchema, + FertilizerRecommendation: FertilizerRecommendationSchema, GrowthStage: GrowthStageSchema, PredictionResult: PredictionResultSchema, SoilData: SoilDataSchema diff --git a/domain/validate.js b/domain/validate.js index 2e9e394e4..110e47d60 100644 --- a/domain/validate.js +++ b/domain/validate.js @@ -1,5 +1,7 @@ import { CropSchema, + FertilizerRecommendationInputSchema, + FertilizerRecommendationSchema, GrowthStageSchema, PredictionResultSchema, SoilDataSchema @@ -7,6 +9,8 @@ import { const schemaMap = { Crop: CropSchema, + FertilizerRecommendationInput: FertilizerRecommendationInputSchema, + FertilizerRecommendation: FertilizerRecommendationSchema, GrowthStage: GrowthStageSchema, PredictionResult: PredictionResultSchema, SoilData: SoilDataSchema From fa9070871f05194c75d36b8d1ebfe4cc6268925a Mon Sep 17 00:00:00 2001 From: Aditya8369 Date: Thu, 28 May 2026 16:18:25 +0530 Subject: [PATCH 3/3] fix: Dark mode not persisting across page --- theme.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/theme.js b/theme.js index 5e30db247..046fb5e6b 100644 --- a/theme.js +++ b/theme.js @@ -1,9 +1,11 @@ (function () { - const KEY = 'theme'; + const KEY = 'agritech-theme'; + const LEGACY_KEY = 'theme'; function applyTheme(theme) { document.documentElement.setAttribute('data-theme', theme); localStorage.setItem(KEY, theme); + localStorage.removeItem(LEGACY_KEY); const btn = document.getElementById('themeToggle'); if (btn) { const label = theme === 'light' ? 'Switch to dark mode' : 'Switch to light mode'; @@ -14,9 +16,15 @@ } // Apply immediately on script load (no flash) - const saved = localStorage.getItem(KEY); + const saved = localStorage.getItem(KEY) || localStorage.getItem(LEGACY_KEY); const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; - applyTheme(saved || (prefersDark ? 'dark' : 'light')); + const initialTheme = saved || (prefersDark ? 'dark' : 'light'); + + if (saved && !localStorage.getItem(KEY)) { + localStorage.setItem(KEY, saved); + } + + applyTheme(initialTheme); document.addEventListener('DOMContentLoaded', function () { const btn = document.getElementById('themeToggle');