From 195fc1ad86ecb3331556dcbb86b6c8ffc842e8f3 Mon Sep 17 00:00:00 2001 From: Ksheetiz Agrahari Date: Fri, 13 Mar 2026 11:21:03 +0530 Subject: [PATCH 1/9] Fix : Layer visualize issue --- src/pages/kyl_dashboard.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/kyl_dashboard.jsx b/src/pages/kyl_dashboard.jsx index ef8bb9dd..ce3f672a 100644 --- a/src/pages/kyl_dashboard.jsx +++ b/src/pages/kyl_dashboard.jsx @@ -1272,7 +1272,7 @@ const KYLDashboardPage = () => { else if (filter.layer_store[i] === "panchayat_boundaries") { tempLayer = await getVectorLayers( filter.layer_store[i], - `${transformName(district.label)}_${transformName(block.label)}` + `${transformName(district.label)}_${transformName(block.label)}_${filter.layer_name[i]}` ); } else if(filter.layer_store[i] === "restoration"){ From bf4bbf651a475e218e9fe6b7e3b66be8217b5209 Mon Sep 17 00:00:00 2001 From: Ksheetiz Agrahari Date: Fri, 13 Mar 2026 12:21:30 +0530 Subject: [PATCH 2/9] Fix : layer name --- src/pages/kyl_dashboard.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/kyl_dashboard.jsx b/src/pages/kyl_dashboard.jsx index ce3f672a..301a5966 100644 --- a/src/pages/kyl_dashboard.jsx +++ b/src/pages/kyl_dashboard.jsx @@ -1266,7 +1266,7 @@ const KYLDashboardPage = () => { else if (filter.layer_store[i] === "drought" || filter.layer_store[i] === "green_credit") { tempLayer = await getVectorLayers( filter.layer_store[i], - `${transformName(district.label)}_${transformName(block.label)}` + `${transformName(district.label)}_${transformName(block.label)}_${filter.layer_name[i]}` ); } else if (filter.layer_store[i] === "panchayat_boundaries") { From b55e8904c5dc04d81f01d83db5be9165f83aeb2f Mon Sep 17 00:00:00 2001 From: manvi Date: Sat, 14 Mar 2026 17:58:23 +0530 Subject: [PATCH 3/9] Toggle issue resolve --- .../CroppingIntensityStackChart.jsx | 2 +- src/components/WaterAvailabilityChart.jsx | 16 ++++----- src/components/water_project_dashboard.jsx | 34 +++++++++---------- 3 files changed, 24 insertions(+), 28 deletions(-) diff --git a/src/components/CroppingIntensityStackChart.jsx b/src/components/CroppingIntensityStackChart.jsx index c90811b8..95795f04 100644 --- a/src/components/CroppingIntensityStackChart.jsx +++ b/src/components/CroppingIntensityStackChart.jsx @@ -35,7 +35,7 @@ const CroppingIntensityStackChart = ({ water_rej_data }) => { const [showImpact, setShowImpact] = useState(false); - +console.log(impactYear) const hasValidImpactYears = impactYear?.pre && impactYear?.post; const wbUID = diff --git a/src/components/WaterAvailabilityChart.jsx b/src/components/WaterAvailabilityChart.jsx index c59a8c2c..f06073da 100644 --- a/src/components/WaterAvailabilityChart.jsx +++ b/src/components/WaterAvailabilityChart.jsx @@ -35,7 +35,7 @@ const WaterAvailabilityChart = ({ }) => { const [showImpact, setShowImpact] = useState(false); const prevImpactRef = useRef(null); - console.log(waterbody) + const extractSeasonYears = (props = {}) => { const years = new Set(); @@ -50,11 +50,6 @@ const WaterAvailabilityChart = ({ return Array.from(years).sort(); }; - const yearToNumber = (year) => { - if (!year) return 0; - return Number(year.split("-")[0]); // "24-25" → 24 -}; - const computedImpactYear = impactPair ?? null; @@ -103,7 +98,7 @@ const getYearIndex = (year, years) => years.indexOf(year); if (!water_rej_data?.features?.length || !waterbody) return {}; const feature = water_rej_data.features.find( - (f) => f.properties?.UID === waterbody.UID + (f) => f.id?.toString() === waterbody?.waterbody_id?.toString() ); return feature?.properties || {}; @@ -310,7 +305,7 @@ useEffect(() => { })); water_rej_data.features.forEach((feature) => { - if (feature.properties.UID === waterbody.UID) { + if (feature.id?.toString() === waterbody?.waterbody_id?.toString()){ const p = feature.properties; years.forEach((year, i) => { @@ -402,7 +397,8 @@ useEffect(() => { // only show bars for impact years, set others to 0 data: years.map((year, i) => { const isImpactYear = - year === computedImpactYear.pre || year === computedImpactYear.post; + year.trim() === computedImpactYear?.pre?.trim() || + year.trim() === computedImpactYear?.post?.trim(); return isImpactYear ? normalizedData[i][key] ?? 0 : 0; }), position: "center", @@ -613,7 +609,7 @@ useEffect(() => { )} -{showImpact && !computedImpactYear && ( +{showImpact && !hasPostYear && (
No data available for post intervention year. Please wait for next year’s data. diff --git a/src/components/water_project_dashboard.jsx b/src/components/water_project_dashboard.jsx index c93802f0..208285de 100644 --- a/src/components/water_project_dashboard.jsx +++ b/src/components/water_project_dashboard.jsx @@ -411,13 +411,21 @@ const WaterProjectDashboard = () => { if (!featureId || !raw) return; const wbMwsList = extractMwsUidList(raw); - - const mws = mwsGeoData.features.find((f) => + const mws = mwsGeoData.features + .filter((f) => wbMwsList.includes(f.properties?.uid?.toString().trim()) - ); + ) + .find((f) => { + const p = f.properties || {}; + return Object.keys(p).some((k) => { + if (/^precipitation_(kharif|rabi|zaid)_/.test(k)) { + return Number(p[k]) > 0; + } + return false; + }); + }); if (!mws) return; - const rainfall = getRainfallByYear(mws); const ivRaw = wb.properties?.intervention_year; const ivNormalized = normalizeYear(ivRaw); @@ -674,16 +682,7 @@ const WaterProjectDashboard = () => { const ivNumFull = Number(`20${ivShort.split("-")[0]}`); if (postNum <= ivNumFull) return; - console.log("ivShort:", ivShort); -console.log("ivNumFull:", ivNumFull); -console.log("pair.post:", pair.post); -console.log("postNum:", postNum); -console.log("UID:", props.UID); -console.log("raw intervention:", props.intervention_year); -console.log("raw intervention:", props.waterbody_name); -console.log("normalized:", ivShort); - - const water = getTotalWaterAvailability(props, pair.post); + const water = getTotalWaterAvailability(props, pair.post); if (water > maxWater) { maxWater = water; @@ -785,12 +784,12 @@ console.log("normalized:", ivShort); activeSelectedWaterbody?.waterbody_id ?? activeSelectedWaterbody?.id; - const row = rows.find((r) => r.waterbody_id === featureId); - + const row = rows.find( + (r) => r.waterbody_id?.toString() === featureId?.toString() + ); return row?.selectedPair ?? null; }, [rows, activeSelectedWaterbody]); - const selectedInterventionYear = useMemo(() => { if (!activeSelectedWaterbody) return null; @@ -1583,6 +1582,7 @@ const mwsSheet = XLSX.utils.json_to_sheet(mwsData, {
Date: Mon, 9 Mar 2026 22:28:27 +0530 Subject: [PATCH 4/9] Waterbody filters added --- src/components/data/Filters.json | 209 +++++++++++++++++++++++------ src/components/kyl_leftSidebar.jsx | 6 +- src/pages/kyl_dashboard.jsx | 89 ++++++++++++ src/store/locationStore.jsx | 1 + 4 files changed, 264 insertions(+), 41 deletions(-) diff --git a/src/components/data/Filters.json b/src/components/data/Filters.json index a03f2092..6130cf21 100644 --- a/src/components/data/Filters.json +++ b/src/components/data/Filters.json @@ -490,45 +490,70 @@ }, { "name": "soge_class", - "label" : "Stage of groundwater extraction", - "type" : 1, - "values" : [ - {"label" : "Safe", "value" : 0}, - {"label" : "Semi-Critical", "value" : 1}, - {"label" : "Critical", "value" : 2}, - {"label" : "Over-exploited", "value" : 3}, - {"label" : "Not Assessed", "value" : 4} - ], - "layer_store" : ["soge"], - "layer_name" : ["soge_vector"], - "vectorStyle" : [{ - "fill" : "rgba(255, 255, 255, 0.5)", - "stroke" : "rgba(255, 255, 255, 1)", - "lower" : 0, "upper" : 0 - }, - { - "fill" : "rgba(224, 243, 248, 0.5)", - "stroke" : "rgba(224, 243, 248, 1)", - "lower" : 1, "upper" : 1 - }, - { - "fill" : "rgba(69, 117, 180, 0.5)", - "stroke" : "rgba(69, 117, 180, 1)", - "lower" : 2, "upper" : 2 - }, - { - "fill" : "rgba(49, 54, 149, 0.5)", - "stroke" : "rgba(49, 54, 149, 1)", - "lower" : 3, "upper" : 3 - }, - { - "fill" : "rgba(169, 169, 169, 0.5)", - "stroke" : "rgba(169, 169, 169, 1)", - "lower" : 4, "upper" : 4 - } - ], - "rasterStyle" : "", - "styleIdx" : 12 + "label": "Stage of groundwater extraction", + "type": 1, + "values": [ + { + "label": "Safe", + "value": 0 + }, + { + "label": "Semi-Critical", + "value": 1 + }, + { + "label": "Critical", + "value": 2 + }, + { + "label": "Over-exploited", + "value": 3 + }, + { + "label": "Not Assessed", + "value": 4 + } + ], + "layer_store": [ + "soge" + ], + "layer_name": [ + "soge_vector" + ], + "vectorStyle": [ + { + "fill": "rgba(255, 255, 255, 0.5)", + "stroke": "rgba(255, 255, 255, 1)", + "lower": 0, + "upper": 0 + }, + { + "fill": "rgba(224, 243, 248, 0.5)", + "stroke": "rgba(224, 243, 248, 1)", + "lower": 1, + "upper": 1 + }, + { + "fill": "rgba(69, 117, 180, 0.5)", + "stroke": "rgba(69, 117, 180, 1)", + "lower": 2, + "upper": 2 + }, + { + "fill": "rgba(49, 54, 149, 0.5)", + "stroke": "rgba(49, 54, 149, 1)", + "lower": 3, + "upper": 3 + }, + { + "fill": "rgba(169, 169, 169, 0.5)", + "stroke": "rgba(169, 169, 169, 1)", + "lower": 4, + "upper": 4 + } + ], + "rasterStyle": "", + "styleIdx": 12 }, { "name": "trend_g", @@ -1287,5 +1312,111 @@ "styleIdx": 8 } ] + }, + "Waterbody": { + "Waterbody": [ + { + "name": "waterbody_size", + "label": "Size of Waterbody", + "type": 2, + "values": [ + { + "label": "WB < 1 ha", + "value": { + "lower": 0, + "upper": 1 + } + }, + { + "label": "1 ha < WB < 5 ha", + "value": { + "lower": 1, + "upper": 5 + } + }, + { + "label": "5 ha < WB < 10 ha", + "value": { + "lower": 5, + "upper": 10 + } + }, + { + "label": "WB > 10 ha", + "value": { + "lower": 10, + "upper": 999999 + } + } + ], + "layer_store": [ + "waterbodies" + ], + "layer_name": [ + "waterbodies" + ], + "vectorStyle": [ + {} + ], + "rasterStyle": "", + "styleIdx": 0 + }, + { + "name": "surface_water_trend", + "label": "Surface Water Trend", + "type": 1, + "values": [ + { + "label": "Positive Trend", + "value": 1 + }, + { + "label": "Negative Trend", + "value": -1 + }, + { + "label": "Steady", + "value": 0 + } + ], + "layer_store": [ + "waterbodies" + ], + "layer_name": [ + "waterbodies" + ], + "vectorStyle": [ + {} + ], + "rasterStyle": "", + "styleIdx": 1 + }, + { + "name": "drainage_line", + "label": "Drainage Line", + "type": 1, + "values": [ + { + "label": "On drainage line", + "value": 1 + }, + { + "label": "Off drainage line", + "value": 0 + } + ], + "layer_store": [ + "waterbodies" + ], + "layer_name": [ + "waterbodies" + ], + "vectorStyle": [ + {} + ], + "rasterStyle": "", + "styleIdx": 2 + } + ] } } \ No newline at end of file diff --git a/src/components/kyl_leftSidebar.jsx b/src/components/kyl_leftSidebar.jsx index 65cfb170..cf647eb5 100644 --- a/src/components/kyl_leftSidebar.jsx +++ b/src/components/kyl_leftSidebar.jsx @@ -35,7 +35,8 @@ const KYLLeftSidebar = ({ const combinedSelectedValues = { ...filterSelections.selectedMWSValues, - ...filterSelections.selectedVillageValues + ...filterSelections.selectedVillageValues, + ...filterSelections.selectedWaterbodyValues }; const handleClearAll = () => { @@ -59,7 +60,8 @@ const KYLLeftSidebar = ({ // Clear all filters setFilterSelections({ selectedMWSValues: {}, - selectedVillageValues: {} + selectedVillageValues: {}, + selectedWaterbodyValues:{} }); }; diff --git a/src/pages/kyl_dashboard.jsx b/src/pages/kyl_dashboard.jsx index e42ce148..335914bb 100644 --- a/src/pages/kyl_dashboard.jsx +++ b/src/pages/kyl_dashboard.jsx @@ -214,6 +214,7 @@ const KYLDashboardPage = () => { processSelections(filterSelections.selectedMWSValues, "MWS"); processSelections(filterSelections.selectedVillageValues, "Village"); + processSelections(filterSelections.selectedWaterbodyValues, "Waterbody"); // Convert grouped object back to array Object.values(groupedSelections).forEach(group => { @@ -282,6 +283,8 @@ const KYLDashboardPage = () => { // Filter selection handlers const handleFilterSelection = (name, option, isChecked) => { + console.log("Filter Clicked:", name, option, isChecked); +console.log("Current filterSelections:", filterSelections); const sourceType = determineFilterSource(name); option = { ...option, @@ -350,6 +353,26 @@ const KYLDashboardPage = () => { }, }; }); + } else if (sourceType.name === "Waterbody") { + setFilterSelections((prev) => { + const currentArray = prev.selectedWaterbodyValues?.[name] || []; + + let newArray; + if (isChecked) { + const exists = currentArray.some(item => item.label === option.label); + newArray = exists ? currentArray : [...currentArray, option]; + } else { + newArray = currentArray.filter(item => item.label !== option.label); + } + + return { + ...prev, + selectedWaterbodyValues: { + ...(prev.selectedWaterbodyValues || {}), + [name]: newArray.length > 0 ? newArray : null, + }, + }; + }); } }; @@ -1444,6 +1467,7 @@ const KYLDashboardPage = () => { setFilterSelections({ selectedMWSValues: {}, selectedVillageValues: {}, + selectedWaterbodyValues:{} }); setIndicatorType(null); @@ -2297,6 +2321,71 @@ const KYLDashboardPage = () => { } }, [selectedMWS, showWB]); + useEffect(() => { + if (!waterbodiesLayerRef.current) return; + + const wbSource = waterbodiesLayerRef.current.getSource(); + const wbFeatures = wbSource.getFeatures(); + +console.log("Waterbody Features:", wbFeatures); +console.log("First Waterbody Props:", wbFeatures[0]?.getProperties()); + + if (!wbFeatures.length) return; + + const wbFilters = filterSelections.selectedWaterbodyValues || {}; + const filterKeys = Object.keys(wbFilters).filter(k => wbFilters[k]); + + if (filterKeys.length === 0) { + wbFeatures.forEach(f => f.setStyle(undefined)); + return; + } + + wbFeatures.forEach((feature) => { + const props = feature.getProperties(); + let matches = true; + + filterKeys.forEach((filterName) => { + const selectedOptions = wbFilters[filterName]; + if (!selectedOptions) return; + + if (filterName === "waterbody_size") { + const area = Number( + props.area_ored ?? + props.AREA_HA ?? + props.area ?? + props.Area ?? + 0 + ); + + const pass = selectedOptions.some(opt => + area >= opt.value.lower && area <= opt.value.upper + ); + + if (!pass) matches = false; + } + + if (filterName === "drainage_line") { + const value = props.drainage_line; + + const pass = selectedOptions.some(opt => value === opt.value); + + if (!pass) matches = false; + } + + if (filterName === "surface_water_trend") { + const trend = props.surface_water_trend; + + const pass = selectedOptions.some(opt => trend === opt.value); + + if (!pass) matches = false; + } + }); + + feature.setStyle(matches ? undefined : new Style({})); + }); + + }, [filterSelections.selectedWaterbodyValues, showWB]); + return (
diff --git a/src/store/locationStore.jsx b/src/store/locationStore.jsx index 0f2d9b84..71a85de3 100644 --- a/src/store/locationStore.jsx +++ b/src/store/locationStore.jsx @@ -27,6 +27,7 @@ export const filterSelectionsAtom = atom({ default: { selectedMWSValues: {}, // { filterName: [selectedOptions] } selectedVillageValues: {}, // { filterName: [selectedOptions] } + selectedWaterbodyValues:{} }, }); From 18237b3f5c6fd3270dc3e20eec07c2ee86044be7 Mon Sep 17 00:00:00 2001 From: manvi Date: Wed, 11 Mar 2026 16:15:41 +0530 Subject: [PATCH 5/9] Waterbody filters and chnages by taru(Reduction in tree cover --> deforestation, legends of dryspell and rainfall and legneds of surface water trend) --- package.json | 1 + src/components/data/Filters.json | 6 ++-- src/components/kyl_indicatorFilter.jsx | 12 +++++--- src/components/kyl_mapContainer.jsx | 14 +++++----- src/components/kyl_rightSidebar.jsx | 16 +++++++++-- src/pages/kyl_dashboard.jsx | 38 ++++++++++++++++++++++---- 6 files changed, 65 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index 1d1ebdb9..f55d3522 100755 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "chartjs-adapter-date-fns": "^3.0.0", "chartjs-plugin-annotation": "^3.1.0", "date-fns": "^4.1.0", + "dompurify": "^3.3.2", "dotenv": "^16.4.7", "file-saver": "^2.0.5", "html2canvas": "^1.4.1", diff --git a/src/components/data/Filters.json b/src/components/data/Filters.json index 6130cf21..6ae854a7 100644 --- a/src/components/data/Filters.json +++ b/src/components/data/Filters.json @@ -246,14 +246,14 @@ } }, { - "label": "Minimum one week of dry spell", + "label": "At least one week of dry spell", "value": { "lower": 1, "upper": 999999999 } }, { - "label": "Minimum two weeks of dry spells", + "label": "At least two weeks of dry spells", "value": { "lower": 2, "upper": 9999999999 @@ -691,7 +691,7 @@ "Restoration": [ { "name": "decrease_in_tree_cover", - "label": "Reduction in tree cover", + "label": "Deforestation", "type": 2, "values": [ { diff --git a/src/components/kyl_indicatorFilter.jsx b/src/components/kyl_indicatorFilter.jsx index 9d5ebea4..f3906919 100644 --- a/src/components/kyl_indicatorFilter.jsx +++ b/src/components/kyl_indicatorFilter.jsx @@ -17,10 +17,14 @@ const KYLIndicatorFilter = ({ filter, onFilterChange, isDisabled, getFormattedSe

{filter.label}

- handleLayerSelection(filter)} - /> + + {filter.category !== "Waterbody" && ( + handleLayerSelection(filter)} + /> + )} +
{filter.values.map((option) => { diff --git a/src/components/kyl_mapContainer.jsx b/src/components/kyl_mapContainer.jsx index f9770afd..c924e27a 100644 --- a/src/components/kyl_mapContainer.jsx +++ b/src/components/kyl_mapContainer.jsx @@ -221,8 +221,8 @@ const MapLegend = ({ showMWS, showVillages, currentLayer, mappedAssets, mappedDe ]; const rainfallLegendItems = [ - { color: "#B0E0E6", label: "Semi-arid" }, - { color: "#87CEFA", label: "Arid" }, + { color: "#B0E0E6", label: "Arid" }, + { color: "#87CEFA", label: "Semi-arid" }, { color: "#1E90FF", label: "Moderate" }, { color: "#0073E6", label: "High" }, { color: "#004080", label: "Very high" }, @@ -290,9 +290,9 @@ const MapLegend = ({ showMWS, showVillages, currentLayer, mappedAssets, mappedDe ]; const TrendLegendItems = [ - { color: "#B8860B", label: "Increasing trend of G" }, - { color: "#FFECB3", label: "Decreasing trend of G" }, - { color: "#FFD700", label: "No trend of G" }, + { color: "#B8860B", label: "Positive Trend" }, + { color: "#FFECB3", label: "Negative Trend" }, + { color: "#FFD700", label: "No Trend" }, ]; const CropDegradationItems = [ @@ -716,7 +716,7 @@ const MapLegend = ({ showMWS, showVillages, currentLayer, mappedAssets, mappedDe {isDryspellLayerActive && (

- Dryspell Vector + Dry spell Vector

{dryspellLengendItems.map((item, index) => (

- Groundwater Trend + Water balance Trend

{TrendLegendItems.map((item, index) => (
({ + ...prev, + selectedWaterbodyValues: { + ...prev.selectedWaterbodyValues, + [filter.name]: null, + }, + })); + } }; const toggleWaterbodies = () => { @@ -906,8 +915,11 @@ const KYLRightSidebar = ({
{/* LOADING OVERLAY */} - {isTehsilMode && loadingData && !activeSelectedWaterbody && ( -
+ {isTehsilMode && tehsilPageLoading && ( +

Loading waterbody data...

diff --git a/src/pages/kyl_dashboard.jsx b/src/pages/kyl_dashboard.jsx index 38d8a2ad..b8d461ea 100644 --- a/src/pages/kyl_dashboard.jsx +++ b/src/pages/kyl_dashboard.jsx @@ -2279,6 +2279,7 @@ console.log("Current filterSelections:", filterSelections); return result; }, [selectedMWS, dataJson, villageJson]); + // this is Mann–Kendall trend statistic (S) function calculateTrend(values) { let S = 0; @@ -2294,6 +2295,31 @@ console.log("Current filterSelections:", filterSelections); return 0; // steady } + //This is sen's slope + // function calculateTrend(values) { + // const slopes = []; + + // for (let i = 0; i < values.length - 1; i++) { + // for (let j = i + 1; j < values.length; j++) { + // slopes.push((values[j] - values[i]) / (j - i)); + // } + // } + + // // sort slopes + // slopes.sort((a, b) => a - b); + + // // median slope + // const mid = Math.floor(slopes.length / 2); + // const senSlope = + // slopes.length % 2 + // ? slopes[mid] + // : (slopes[mid - 1] + slopes[mid]) / 2; + + // if (senSlope > 0) return 1; // increasing + // if (senSlope < 0) return -1; // decreasing + // return 0; // steady + // } + useEffect(() => { if (!waterbodiesLayerRef.current || !mwsLayerRef.current) return; From b3d84fe55169f4c74d322db5b5e284ffd00b746f Mon Sep 17 00:00:00 2001 From: manvi Date: Fri, 13 Mar 2026 11:26:41 +0530 Subject: [PATCH 8/9] MWS connectivity layer should come on top. --- src/pages/kyl_dashboard.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/kyl_dashboard.jsx b/src/pages/kyl_dashboard.jsx index b8d461ea..05b06d3b 100644 --- a/src/pages/kyl_dashboard.jsx +++ b/src/pages/kyl_dashboard.jsx @@ -830,7 +830,7 @@ console.log("Current filterSelections:", filterSelections); } }, }); - + arrowLayer.setZIndex(9999); arrowLayer.setVisible(false); mapRef.current.addLayer(arrowLayer); mwsArrowLayerRef.current = arrowLayer; From 62d272248f20666d4b290378c61d77cb921785d6 Mon Sep 17 00:00:00 2001 From: Dharshini Date: Sat, 28 Mar 2026 00:27:00 +0530 Subject: [PATCH 9/9] Refined Ui Micro-Interactions --- src/App.jsx | 2 + src/components/buttons/select_button.jsx | 77 ++++++++--- src/components/landscape-explorer/map/Map.jsx | 26 ++-- .../landscape-explorer/map/MapControls.jsx | 28 ++-- .../sidebar/LeftSidebar.jsx | 53 ++++---- .../sidebar/RightSidebar.jsx | 89 +++++++------ .../utils/downloadHelper.js | 15 ++- src/components/ui/Loader.jsx | 47 +++++++ src/components/ui/ToastHandler.jsx | 40 ++++++ src/index.css | 121 +++++++++++++++++- src/pages/LandscapeExplorer.jsx | 91 +++++++++---- 11 files changed, 463 insertions(+), 126 deletions(-) create mode 100644 src/components/ui/Loader.jsx create mode 100644 src/components/ui/ToastHandler.jsx diff --git a/src/App.jsx b/src/App.jsx index e4d876e9..941f0372 100755 --- a/src/App.jsx +++ b/src/App.jsx @@ -6,10 +6,12 @@ import PlansPage from "./components/plansPage"; import PlanViewPage from "./components/plan_detailView"; import AgroHorticulture from "./pages/AgroHorticulture"; import RWBDashboard from "./pages/RWBDashboard"; +import ToastHandler from "./components/ui/ToastHandler"; function App() { return ( + } /> } /> diff --git a/src/components/buttons/select_button.jsx b/src/components/buttons/select_button.jsx index 6d632011..0f1f663e 100755 --- a/src/components/buttons/select_button.jsx +++ b/src/components/buttons/select_button.jsx @@ -1,7 +1,14 @@ -import { useMemo } from 'react'; -import Select from 'react-select'; +import { useMemo } from "react"; +import Select from "react-select"; -const SelectButton = ({ stateData, handleItemSelect, setState, currVal }) => { +const SelectButton = ({ + stateData, + handleItemSelect, + setState, + currVal, + className = "", + placeholder = "Select option", +}) => { // ---------- sort by label, keeping original untouched ---------- const sortedOptions = useMemo(() => { if (!stateData) return []; @@ -9,38 +16,76 @@ const SelectButton = ({ stateData, handleItemSelect, setState, currVal }) => { }, [stateData]); const customStyles = { - container: (provided) => ({ ...provided, width: '100%' }), + container: (provided) => ({ ...provided, width: "100%" }), control: (base, state) => ({ ...base, - borderColor: 'black', - backgroundColor: 'white', - textAlign: 'center', - width: '100%', + minHeight: 44, + borderRadius: 12, + borderColor: state.isFocused ? "#8B5CF6" : "#D1D5DB", + backgroundColor: state.isDisabled ? "#F9FAFB" : "white", + textAlign: "left", + width: "100%", + boxShadow: state.isFocused ? "0 0 0 3px rgba(139, 92, 246, 0.18)" : "none", + cursor: state.isDisabled ? "not-allowed" : "pointer", + transition: "border-color 180ms ease, box-shadow 180ms ease, transform 180ms ease", + "&:hover": { + borderColor: state.isFocused ? "#8B5CF6" : "#A78BFA", + }, + }), + valueContainer: (base) => ({ + ...base, + paddingLeft: 10, + paddingRight: 10, + }), + placeholder: (base) => ({ + ...base, + color: "#6B7280", + }), + singleValue: (base) => ({ + ...base, + color: "#111827", }), option: (styles, { isFocused, isSelected }) => ({ ...styles, - color: '#111827', + color: "#111827", backgroundColor: isSelected - ? '#11182732' + ? "#EDE9FE" : isFocused - ? '#11182717' + ? "#F5F3FF" : undefined, - ':active': { ...styles[':active'], backgroundColor: '#11182717' }, + cursor: "pointer", + transition: "background-color 180ms ease", + ":active": { ...styles[":active"], backgroundColor: "#DDD6FE" }, + }), + menu: (provided) => ({ + ...provided, + width: "100%", + borderRadius: 12, + overflow: "hidden", + boxShadow: "0 16px 32px rgba(15, 23, 42, 0.14)", + }), + indicatorSeparator: () => ({ display: "none" }), + dropdownIndicator: (base, state) => ({ + ...base, + color: state.isFocused ? "#8B5CF6" : "#6B7280", + transition: "color 180ms ease, transform 180ms ease", + transform: state.selectProps.menuIsOpen ? "rotate(180deg)" : "rotate(0deg)", }), - menu: (provided) => ({ ...provided, width: '100%' }), }; return ( -
+