u
This commit is contained in:
83
src/api/storageManager.jsx
Normal file
83
src/api/storageManager.jsx
Normal file
@@ -0,0 +1,83 @@
|
||||
import { createContext, useContext, useRef } from 'react';
|
||||
|
||||
export const StorageManagerContext = createContext(null);
|
||||
|
||||
function createStorageManager() {
|
||||
/** Fetch /articleIndex on construction and convert to the row shape the search page renders. */
|
||||
const articleIndexPromise = fetch('/api/articleIndex')
|
||||
.then(async (res) => {
|
||||
const data = await res.json();
|
||||
const articles = Array.isArray(data) ? data : (data?.articles ?? []);
|
||||
console.log('[storageMgr] GET /articleIndex', {
|
||||
status: res.status,
|
||||
count: articles.length,
|
||||
sampleKeys:
|
||||
articles.slice(0, 3).map((a) => (a && typeof a === 'object' ? Object.keys(a) : null)),
|
||||
});
|
||||
// Map backend article rows to the recordset shape used by the result list.
|
||||
// `categories` is a comma-joined string (formatCategoryList splits on ',').
|
||||
return articles.map((a) => ({
|
||||
id: a.id,
|
||||
sku: a.sku,
|
||||
name: a.name,
|
||||
eans: a.eans ?? [],
|
||||
categories: Array.isArray(a.categoryIds) ? a.categoryIds.join(',') : null,
|
||||
}));
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('[storageMgr] GET /articleIndex failed', err);
|
||||
return [];
|
||||
});
|
||||
|
||||
async function doSearch({ target, filter, offset, maxCount, onUpdate }) {
|
||||
const articles = await articleIndexPromise;
|
||||
const query = target.trim().toLowerCase();
|
||||
const matches = articles.filter(
|
||||
(p) =>
|
||||
p.name.toLowerCase().includes(query) ||
|
||||
p.sku.toLowerCase().includes(query) ||
|
||||
(p.eans ?? []).some((ean) => String(ean).includes(query)),
|
||||
);
|
||||
onUpdate({
|
||||
categoryFacets: {},
|
||||
totalCount: matches.length,
|
||||
recordset: matches,
|
||||
error: null,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
doSearch,
|
||||
// Expose so callers can await if they want the loaded index.
|
||||
articleIndexPromise,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Provider — mount once near the top of the tree.
|
||||
*/
|
||||
export function StorageManagerProvider({ children }) {
|
||||
const mgrRef = useRef(null);
|
||||
if (!mgrRef.current) {
|
||||
mgrRef.current = createStorageManager();
|
||||
}
|
||||
|
||||
return (
|
||||
<StorageManagerContext.Provider value={mgrRef.current}>
|
||||
{children}
|
||||
</StorageManagerContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for function components that need the store manager.
|
||||
*/
|
||||
export function useStorageManager() {
|
||||
const ctx = useContext(StorageManagerContext);
|
||||
if (!ctx) {
|
||||
throw new Error('useStorageManager must be used within a <StorageManagerProvider>');
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
export default StorageManagerContext;
|
||||
Reference in New Issue
Block a user