90 lines
2.6 KiB
TypeScript
90 lines
2.6 KiB
TypeScript
/**
|
|
* useStore Hook
|
|
*
|
|
* Manages feature store interactions: loading catalog, activating/deactivating features.
|
|
* After each mutation, refreshes featureStore and dispatches 'features-changed' event
|
|
* so navigation and other components update in real-time.
|
|
*/
|
|
|
|
import { useState, useCallback, useEffect } from 'react';
|
|
import {
|
|
fetchStoreFeatures,
|
|
activateStoreFeature,
|
|
deactivateStoreFeature,
|
|
type StoreFeature,
|
|
} from '../api/storeApi';
|
|
import { useFeatureStore } from '../stores/featureStore';
|
|
|
|
interface UseStoreReturn {
|
|
features: StoreFeature[];
|
|
loading: boolean;
|
|
actionLoading: string | null;
|
|
error: string | null;
|
|
loadStore: () => Promise<void>;
|
|
activate: (featureCode: string) => Promise<void>;
|
|
deactivate: (featureCode: string) => Promise<void>;
|
|
}
|
|
|
|
export function useStore(): UseStoreReturn {
|
|
const [features, setFeatures] = useState<StoreFeature[]>([]);
|
|
const [loading, setLoading] = useState(true);
|
|
const [actionLoading, setActionLoading] = useState<string | null>(null);
|
|
const [error, setError] = useState<string | null>(null);
|
|
const featureStore = useFeatureStore();
|
|
|
|
const loadStore = useCallback(async () => {
|
|
setLoading(true);
|
|
setError(null);
|
|
try {
|
|
const data = await fetchStoreFeatures();
|
|
setFeatures(data);
|
|
} catch (err: unknown) {
|
|
const msg = err instanceof Error ? err.message : 'Failed to load store';
|
|
setError(msg);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
loadStore();
|
|
}, [loadStore]);
|
|
|
|
const _refreshAfterAction = useCallback(async () => {
|
|
await featureStore.loadFeatures();
|
|
window.dispatchEvent(new CustomEvent('features-changed'));
|
|
await loadStore();
|
|
}, [featureStore, loadStore]);
|
|
|
|
const activate = useCallback(async (featureCode: string) => {
|
|
setActionLoading(featureCode);
|
|
setError(null);
|
|
try {
|
|
await activateStoreFeature(featureCode);
|
|
await _refreshAfterAction();
|
|
} catch (err: unknown) {
|
|
const msg = err instanceof Error ? err.message : 'Activation failed';
|
|
setError(msg);
|
|
} finally {
|
|
setActionLoading(null);
|
|
}
|
|
}, [_refreshAfterAction]);
|
|
|
|
const deactivate = useCallback(async (featureCode: string) => {
|
|
setActionLoading(featureCode);
|
|
setError(null);
|
|
try {
|
|
await deactivateStoreFeature(featureCode);
|
|
await _refreshAfterAction();
|
|
} catch (err: unknown) {
|
|
const msg = err instanceof Error ? err.message : 'Deactivation failed';
|
|
setError(msg);
|
|
} finally {
|
|
setActionLoading(null);
|
|
}
|
|
}, [_refreshAfterAction]);
|
|
|
|
return { features, loading, actionLoading, error, loadStore, activate, deactivate };
|
|
}
|
|
|
|
export default useStore;
|