moved ConfigProvider up in the hierarchy (to main.jsx) to wrap the whole App
This commit is contained in:
@@ -6,6 +6,11 @@
|
||||
]
|
||||
},
|
||||
"appConfig": {
|
||||
"endpoints": {
|
||||
"baseUrl": "http://localhost:8080/api/v1",
|
||||
"sensors": "sensors",
|
||||
"sensor": "sensors/sensor"
|
||||
},
|
||||
"historyChartConfig": {
|
||||
"timeLabels": [
|
||||
"08:00",
|
||||
|
||||
@@ -3,16 +3,13 @@ import 'leaflet/dist/leaflet.css'
|
||||
import 'bootstrap/dist/css/bootstrap.min.css'
|
||||
import 'bootstrap/dist/js/bootstrap.bundle.min.js'
|
||||
|
||||
import { ThemeProvider } from '../contexts/ThemeContext.jsx'
|
||||
|
||||
import Home from '../pages/Home.jsx'
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<>
|
||||
<ThemeProvider>
|
||||
<Home />
|
||||
</ThemeProvider>
|
||||
{/* Planeo añadir un React Router */}
|
||||
<Home />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,16 +6,28 @@ import PropTypes from "prop-types";
|
||||
|
||||
import { useTheme } from "../contexts/ThemeContext.jsx";
|
||||
import { DataProvider, useData } from "../contexts/DataContext.jsx";
|
||||
import { ConfigProvider, useConfig } from "../contexts/ConfigContext.jsx";
|
||||
import { useConfig } from "../contexts/ConfigContext.jsx";
|
||||
|
||||
ChartJS.register(LineElement, PointElement, LinearScale, CategoryScale, Filler);
|
||||
|
||||
const HistoryCharts = () => {
|
||||
const { config, configLoading, configError } = useConfig();
|
||||
|
||||
if (configLoading) return <p>Cargando configuración...</p>;
|
||||
if (configError) return <p>Error al cargar configuración: {configError}</p>;
|
||||
if (!config) return <p>Configuración no disponible.</p>;
|
||||
|
||||
const BASE = config.appConfig.endpoints.baseUrl;
|
||||
const ENDPOINT = config.appConfig.endpoints.sensors;
|
||||
|
||||
const reqConfig = {
|
||||
baseUrl: `${BASE}/${ENDPOINT}`,
|
||||
params: {}
|
||||
}
|
||||
|
||||
return (
|
||||
<DataProvider apiUrl="https://contaminus.miarma.net/api/v1/sensors">
|
||||
<ConfigProvider>
|
||||
<HistoryChartsContent />
|
||||
</ConfigProvider>
|
||||
<DataProvider config={reqConfig}>
|
||||
<HistoryChartsContent />
|
||||
</DataProvider>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { MapContainer, TileLayer, Circle, Popup } from 'react-leaflet';
|
||||
|
||||
|
||||
import { ConfigProvider } from '../contexts/ConfigContext.jsx';
|
||||
import { useConfig } from '../contexts/ConfigContext.jsx';
|
||||
|
||||
import { DataProvider } from '../contexts/DataContext.jsx';
|
||||
@@ -41,23 +39,41 @@ const PollutionCircles = ({ data }) => {
|
||||
};
|
||||
|
||||
const PollutionMap = () => {
|
||||
const { config, configLoading, configError } = useConfig();
|
||||
|
||||
if (configLoading) return <p>Cargando configuración...</p>;
|
||||
if (configError) return <p>Error al cargar configuración: {configError}</p>;
|
||||
if (!config) return <p>Configuración no disponible.</p>;
|
||||
|
||||
const BASE = config.appConfig.endpoints.baseUrl;
|
||||
const ENDPOINT = config.appConfig.endpoints.sensors;
|
||||
|
||||
const reqConfig = {
|
||||
baseUrl: `${BASE}/${ENDPOINT}`,
|
||||
params: {}
|
||||
}
|
||||
|
||||
return (
|
||||
<DataProvider apiUrl="https://contaminus.miarma.net/api/v1/sensors">
|
||||
<ConfigProvider>
|
||||
<PollutionMapContent />
|
||||
</ConfigProvider>
|
||||
<DataProvider config={reqConfig}>
|
||||
<PollutionMapContent />
|
||||
</DataProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const PollutionMapContent = () => {
|
||||
const { config } = useConfig();
|
||||
const { config, configLoading, configError } = useConfig();
|
||||
const { data, dataLoading, dataError } = useData();
|
||||
|
||||
if (configLoading) return <p>Cargando configuración...</p>;
|
||||
if (configError) return <p>Error al cargar configuración: {configError}</p>;
|
||||
if (!config) return <p>Configuración no disponible.</p>;
|
||||
|
||||
if (dataLoading) return <p>Cargando datos...</p>;
|
||||
if (dataError) return <p>Error al cargar datos: {configError}</p>;
|
||||
if (!data) return <p>Datos no disponibles.</p>;
|
||||
|
||||
const SEVILLA = config?.userConfig.city;
|
||||
|
||||
const { data, loading } = useData();
|
||||
|
||||
if (loading) return <p>Cargando datos...</p>;
|
||||
|
||||
const pollutionData = data.map((sensor) => ({
|
||||
lat: sensor.lat,
|
||||
lng: sensor.lon,
|
||||
|
||||
@@ -4,9 +4,28 @@ import CardContainer from './CardContainer';
|
||||
import { DataProvider } from '../contexts/DataContext';
|
||||
import { useData } from '../contexts/DataContext';
|
||||
|
||||
import { useConfig } from '../contexts/ConfigContext';
|
||||
|
||||
const SummaryCards = () => {
|
||||
const { config, configLoading, configError } = useConfig();
|
||||
|
||||
if (configLoading) return <p>Cargando configuración...</p>;
|
||||
if (configError) return <p>Error al cargar configuración: {configError}</p>;
|
||||
if (!config) return <p>Configuración no disponible.</p>;
|
||||
|
||||
const BASE = config.appConfig.endpoints.baseUrl;
|
||||
const ENDPOINT = config.appConfig.endpoints.sensors;
|
||||
|
||||
const reqConfig = {
|
||||
baseUrl: `${BASE}/${ENDPOINT}`,
|
||||
params: {
|
||||
_sort: 'timestamp',
|
||||
_order: 'desc'
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<DataProvider apiUrl="https://contaminus.miarma.net/api/v1/sensors?_sort=timestamp&_order=desc">
|
||||
<DataProvider config={reqConfig}>
|
||||
<SummaryCardsContent />
|
||||
</DataProvider>
|
||||
);
|
||||
|
||||
@@ -5,8 +5,8 @@ const ConfigContext = createContext();
|
||||
|
||||
export const ConfigProvider = ({ children }) => {
|
||||
const [config, setConfig] = useState(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState(null);
|
||||
const [configLoading, setLoading] = useState(true);
|
||||
const [configError, setError] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchConfig = async () => {
|
||||
@@ -26,7 +26,7 @@ export const ConfigProvider = ({ children }) => {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<ConfigContext.Provider value={{ config, loading, error }}>
|
||||
<ConfigContext.Provider value={{ config, configLoading, configError }}>
|
||||
{children}
|
||||
</ConfigContext.Provider>
|
||||
);
|
||||
|
||||
@@ -3,15 +3,17 @@ import PropTypes from "prop-types";
|
||||
|
||||
const DataContext = createContext();
|
||||
|
||||
export const DataProvider = ({ children, apiUrl }) => {
|
||||
export const DataProvider = ({ children, config }) => {
|
||||
const [data, setData] = useState(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState(null);
|
||||
const [dataLoading, setLoading] = useState(true);
|
||||
const [dataError, setError] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const response = await fetch(apiUrl);
|
||||
const queryParams = new URLSearchParams(config.params).toString();
|
||||
const url = `${config.baseUrl}?${queryParams}`;
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) throw new Error("Error al obtener datos");
|
||||
const result = await response.json();
|
||||
setData(result);
|
||||
@@ -23,10 +25,10 @@ export const DataProvider = ({ children, apiUrl }) => {
|
||||
};
|
||||
|
||||
fetchData();
|
||||
}, [apiUrl]);
|
||||
}, [config]);
|
||||
|
||||
return (
|
||||
<DataContext.Provider value={{ data, loading, error }}>
|
||||
<DataContext.Provider value={{ data, dataLoading, dataError }}>
|
||||
{children}
|
||||
</DataContext.Provider>
|
||||
);
|
||||
@@ -34,7 +36,10 @@ export const DataProvider = ({ children, apiUrl }) => {
|
||||
|
||||
DataProvider.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
apiUrl: PropTypes.string.isRequired,
|
||||
config: PropTypes.shape({
|
||||
baseUrl: PropTypes.string.isRequired,
|
||||
params: PropTypes.object,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export const useData = () => useContext(DataContext);
|
||||
@@ -39,6 +39,7 @@
|
||||
color: var(--primary-color);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
p.card-text {
|
||||
|
||||
@@ -3,8 +3,15 @@ import { createRoot } from 'react-dom/client'
|
||||
import './css/index.css'
|
||||
import App from './components/App.jsx'
|
||||
|
||||
import { ThemeProvider } from './contexts/ThemeContext.jsx'
|
||||
import { ConfigProvider } from './contexts/ConfigContext.jsx'
|
||||
|
||||
createRoot(document.getElementById('root')).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
<ThemeProvider>
|
||||
<ConfigProvider>
|
||||
<App />
|
||||
</ConfigProvider>
|
||||
</ThemeProvider>
|
||||
</StrictMode>,
|
||||
)
|
||||
|
||||
@@ -12,7 +12,6 @@ const Home = () => {
|
||||
<Dashboard>
|
||||
<SummaryCards />
|
||||
<PollutionMap />
|
||||
{/* */}
|
||||
<HistoryCharts />
|
||||
</Dashboard>
|
||||
<ThemeButton />
|
||||
|
||||
Reference in New Issue
Block a user