demeter

Autonomous Hydroponic Intelligence

frontend/src/hooks/useFarmData.js (1747B)


 1import React, { useState, useEffect, createContext, useContext } from "react";
 2import { fetchDashboardData, fetchAllCropHistories } from "../api/farmApi";
 3import { normalizeMongoCrop } from "../utils/dataUtils";
 4
 5const FarmDataContext = createContext();
 6
 7export const FarmDataProvider = ({ children }) => {
 8  const [dashboard, setDashboard] = useState([]);
 9  const [history, setHistory] = useState([]);
10  const [loading, setLoading] = useState(true);
11
12  const refreshData = async () => {
13    setLoading(true);
14    try {
15      // fetchDashboardData now returns raw MongoDB docs (or MOCK_DASHBOARD)
16      const raw = await fetchDashboardData();
17
18      // Normalize each MongoDB doc into { id, payload: {...} } shape
19      // so all downstream components (Dashboard, Alerts, Analytics, Sidebar) work unchanged
20      const normalized = (raw || [])
21        .map((doc) => {
22          // If doc already has a payload key (mock data in old shape), passthrough
23          if (doc && doc.payload) return doc;
24          return normalizeMongoCrop(doc);
25        })
26        .filter(Boolean);
27
28      setDashboard(normalized);
29
30      // Fetch Qdrant history using the normalized array (farmApi handles both shapes)
31      const hist = await fetchAllCropHistories(normalized);
32      setHistory(hist || []);
33    } catch (error) {
34      console.error("Failed to fetch farm data", error);
35    } finally {
36      setLoading(false);
37    }
38  };
39
40  useEffect(() => {
41    refreshData();
42  }, []); // eslint-disable-line react-hooks/exhaustive-deps
43
44  return (
45    <FarmDataContext.Provider
46      value={{ dashboard, history, loading, refreshData }}
47    >
48      {children}
49    </FarmDataContext.Provider>
50  );
51};
52
53export const useFarmData = () => useContext(FarmDataContext);