This commit is contained in:
seb
2026-08-03 23:43:57 +02:00
parent d47f0ffa0d
commit 8f371749c6
4 changed files with 122 additions and 75 deletions

View 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;