-
Notifications
You must be signed in to change notification settings - Fork 0
fix(catalog): exibe o nome real da categoria em vez de "Sem categoria" #40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ import { useQuery, useInfiniteQuery } from '@tanstack/react-query'; | |
| import { | ||
| fetchPromobrindProductsLightweight, | ||
| invokeBatchBridge, | ||
| fetchPromobrindCategories, | ||
| type LightweightProduct, | ||
| } from '@/lib/external-db'; | ||
|
|
||
|
|
@@ -38,17 +39,24 @@ function getStockStatus(stock: number): 'in-stock' | 'low-stock' | 'out-of-stock | |
| return 'in-stock'; | ||
| } | ||
|
|
||
| export function mapLightweightToProduct(p: LightweightProduct): Product { | ||
| export function mapLightweightToProduct( | ||
| p: LightweightProduct, | ||
| categoriesById?: ReadonlyMap<string, string>, | ||
| ): Product { | ||
| const imageUrl = p.primary_image_url || p.image_url || '/placeholder.svg'; | ||
| const price = p.sale_price ?? p.cost_price ?? 0; | ||
| const stock = p.stock_quantity || 0; | ||
| const resolvedCategoryId = p.category_id || p.main_category_id; | ||
| const resolvedCategoryName = resolvedCategoryId | ||
| ? (categoriesById?.get(resolvedCategoryId) ?? null) | ||
| : null; | ||
|
|
||
| return { | ||
| id: p.id, | ||
| name: p.name, | ||
| description: '', | ||
| category_id: p.category_id || p.main_category_id, | ||
| category_name: null, | ||
| category_id: resolvedCategoryId, | ||
| category_name: resolvedCategoryName, | ||
| price: typeof price === 'number' ? price : 0, | ||
| image_url: imageUrl, | ||
| images: [imageUrl], | ||
|
|
@@ -67,8 +75,8 @@ export function mapLightweightToProduct(p: LightweightProduct): Product { | |
| isKit: p.is_kit ?? false, | ||
| gender: p.gender || null, | ||
| category: { | ||
| id: p.category_id || p.main_category_id || '0', | ||
| name: 'Sem categoria', | ||
| id: resolvedCategoryId || '0', | ||
| name: resolvedCategoryName ?? 'Sem categoria', | ||
| }, | ||
| supplier: { | ||
| id: p.supplier_id || p.brand || 'unknown', | ||
|
|
@@ -113,6 +121,15 @@ interface CatalogPage { | |
| * First call fetches 4 pages (2000 products) via batch bridge. | ||
| * Subsequent calls fetch 1 page (500 products) each. | ||
| */ | ||
| async function loadCategoriesMap(): Promise<ReadonlyMap<string, string>> { | ||
| try { | ||
| const categories = await fetchPromobrindCategories(); | ||
| return new Map(categories.map((c) => [String(c.id), c.name])); | ||
| } catch { | ||
| return new Map(); | ||
| } | ||
| } | ||
|
|
||
| async function fetchCatalogPage(offset: number, search?: string): Promise<CatalogPage> { | ||
| const filters: Record<string, unknown> = { active: true }; | ||
| if (search) filters._search = search; | ||
|
|
@@ -132,32 +149,40 @@ async function fetchCatalogPage(offset: number, search?: string): Promise<Catalo | |
| ...(i === 0 && isFirstLoad ? { countMode: 'exact' } : {}), | ||
| })); | ||
|
|
||
| const categoriesPromise = loadCategoriesMap(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Useful? React with 👍 / 👎. |
||
|
|
||
| let batchResults; | ||
| try { | ||
| batchResults = await invokeBatchBridge(batchQueries); | ||
| } catch { | ||
| const fallbackProducts = await fetchPromobrindProductsLightweight({ | ||
| search, | ||
| limit: CATALOG_PAGE_SIZE, | ||
| offset, | ||
| orderBy, | ||
| filters: { active: true }, | ||
| }); | ||
| const [fallbackProducts, categoriesById] = await Promise.all([ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When Useful? React with 👍 / 👎. |
||
| fetchPromobrindProductsLightweight({ | ||
| search, | ||
| limit: CATALOG_PAGE_SIZE, | ||
| offset, | ||
| orderBy, | ||
| filters: { active: true }, | ||
| }), | ||
| categoriesPromise, | ||
| ]); | ||
|
|
||
| return { | ||
| products: fallbackProducts.map(mapLightweightToProduct), | ||
| products: fallbackProducts.map((p) => mapLightweightToProduct(p, categoriesById)), | ||
| nextOffset: fallbackProducts.length === CATALOG_PAGE_SIZE ? offset + CATALOG_PAGE_SIZE : null, | ||
| totalEstimate: null, | ||
| }; | ||
| } | ||
|
|
||
| const categoriesById = await categoriesPromise; | ||
| const products: Product[] = []; | ||
| let totalEstimate: number | null = null; | ||
| let lastPageSize = 0; | ||
|
|
||
| for (const result of batchResults) { | ||
| if (result.success && result.data?.records) { | ||
| const mapped = (result.data.records as LightweightProduct[]).map(mapLightweightToProduct); | ||
| const mapped = (result.data.records as LightweightProduct[]).map((p) => | ||
| mapLightweightToProduct(p, categoriesById), | ||
| ); | ||
| products.push(...mapped); | ||
| lastPageSize = result.data.records.length; | ||
| if (result.data.count !== null && totalEstimate === null) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The prefetch path swallows category lookup failures with
fetchPromobrindCategories().catch(() => []), so a transient categories error still stores a successful catalog response with unresolved names (Sem categoria). Because this same query key is prefetched withstaleTime: 30 * 60 * 1000,useProductsCatalogwill treat that degraded result as fresh and skip refetching for up to 30 minutes, leaving users with incorrect category labels after a temporary backend hiccup.Useful? React with 👍 / 👎.