grocery-app/frontend/src/context/StoreContext.jsx
2026-05-26 00:38:53 -07:00

142 lines
4.1 KiB
JavaScript

import { createContext, useContext, useEffect, useState } from 'react';
import { isTransientApiError } from '../api/offlineCache';
import { getHouseholdStores, getLocationZones } from '../api/stores';
import { AuthContext } from './AuthContext';
import { HouseholdContext } from './HouseholdContext';
export const StoreContext = createContext({
stores: [],
activeStore: null,
zones: [],
loading: false,
zonesLoading: false,
error: null,
setActiveStore: () => { },
refreshStores: () => { },
refreshZones: () => { },
});
export const StoreProvider = ({ children }) => {
const { token } = useContext(AuthContext);
const { activeHousehold } = useContext(HouseholdContext);
const [stores, setStores] = useState([]);
const [activeStore, setActiveStoreState] = useState(null);
const [zones, setZones] = useState([]);
const [loading, setLoading] = useState(false);
const [zonesLoading, setZonesLoading] = useState(false);
const [error, setError] = useState(null);
// Load stores when household changes
useEffect(() => {
if (token && activeHousehold) {
loadStores();
} else {
// Clear state when logged out or no household
setStores([]);
setActiveStoreState(null);
setZones([]);
}
}, [token, activeHousehold?.id]);
// Load active store from localStorage on mount (per household)
useEffect(() => {
if (!activeHousehold || stores.length === 0) return;
console.log('[StoreContext] Setting active store from:', stores);
const storageKey = `activeStoreId_${activeHousehold.id}`;
const savedStoreId = localStorage.getItem(storageKey);
if (savedStoreId) {
const store = stores.find(s => String(s.id) === String(savedStoreId));
if (store) {
console.log('[StoreContext] Found saved store:', store);
setActiveStoreState(store);
return;
}
}
// No saved store or not found, use default or first one
const defaultStore = stores.find(s => s.is_default) || stores[0];
console.log('[StoreContext] Using store:', defaultStore);
setActiveStoreState(defaultStore);
localStorage.setItem(storageKey, defaultStore.id);
}, [stores, activeHousehold]);
useEffect(() => {
if (token && activeHousehold?.id && activeStore?.id) {
loadZones();
} else {
setZones([]);
}
}, [token, activeHousehold?.id, activeStore?.id]);
const loadStores = async () => {
if (!token || !activeHousehold) return;
setLoading(true);
setError(null);
try {
console.log('[StoreContext] Loading stores for household:', activeHousehold.id);
const response = await getHouseholdStores(activeHousehold.id);
console.log('[StoreContext] Loaded stores:', response.data);
setStores(response.data);
} catch (err) {
console.error('[StoreContext] Failed to load stores:', err);
setError(
err.response?.data?.error?.message ||
err.response?.data?.message ||
'Failed to load stores'
);
if (!isTransientApiError(err)) {
setStores([]);
setActiveStoreState(null);
}
} finally {
setLoading(false);
}
};
const setActiveStore = (store) => {
setActiveStoreState(store);
if (store && activeHousehold) {
const storageKey = `activeStoreId_${activeHousehold.id}`;
localStorage.setItem(storageKey, String(store.id));
}
};
const loadZones = async () => {
if (!token || !activeHousehold?.id || !activeStore?.id) return;
setZonesLoading(true);
try {
const response = await getLocationZones(activeHousehold.id, activeStore.id);
setZones(response.data?.zones || []);
} catch (err) {
console.error('[StoreContext] Failed to load zones:', err);
if (!isTransientApiError(err)) {
setZones([]);
}
} finally {
setZonesLoading(false);
}
};
const value = {
stores,
activeStore,
zones,
loading,
zonesLoading,
error,
setActiveStore,
refreshStores: loadStores,
refreshZones: loadZones,
};
return (
<StoreContext.Provider value={value}>
{children}
</StoreContext.Provider>
);
};