diff --git a/app/[locale]/library/LibraryClient.tsx b/app/[locale]/library/LibraryClient.tsx index fc9004b..5bd43d4 100644 --- a/app/[locale]/library/LibraryClient.tsx +++ b/app/[locale]/library/LibraryClient.tsx @@ -123,7 +123,7 @@ export default function LibraryClient({ initial }: { initial: InitialData }) { />
- {items.map((item) => { + {items.map((item, idx) => { const anyItem = item as any; // Normalização de categoria para os ícones do ItemCard const normalizeCategory = (c: string | undefined): string => { @@ -163,8 +163,27 @@ export default function LibraryClient({ initial }: { initial: InitialData }) { typeof anyItem.categoria === "string" ? anyItem.categoria : undefined; - const category = normalizeCategory(item.category ?? categoryPt); - const name = item.name ?? anyItem.nome ?? String(item.id); + const rawCategory = item.category ?? anyItem.category ?? categoryPt; + const category = normalizeCategory(rawCategory || "other"); + + const idSafe = + typeof item.id === "string" || typeof item.id === "number" + ? String(item.id) + : typeof anyItem.item_id === "number" + ? String(anyItem.item_id) + : typeof anyItem.id === "number" + ? String(anyItem.id) + : undefined; + + const name = + (typeof item.name === "string" && item.name + ? item.name + : typeof anyItem.item_name === "string" && anyItem.item_name + ? anyItem.item_name + : typeof anyItem.nome === "string" && anyItem.nome + ? anyItem.nome + : idSafe) || "Sem nome"; + const image = item.image ?? anyItem.image_url ?? ""; // Campos numéricos normalizados @@ -221,12 +240,31 @@ export default function LibraryClient({ initial }: { initial: InitialData }) { ? anyItem.voc : undefined; + const sourceTag = [anyItem.source_table_name, anyItem.source_table_id] + .filter((v) => v !== undefined && v !== null && String(v).length > 0) + .join(":"); + + const fallbackKey = `${page}-${idx}`; + const safeKey = [category, idSafe ?? sourceTag ?? name ?? fallbackKey, name] + .map((v) => String(v || "")) + .join("::"); + + // Log de integridade de dados + if (!idSafe && (!name || name === "Sem nome")) { + console.error("[Library] Item inválido sem id/nome", { + index: idx, + page, + category: rawCategory, + itemSnapshot: anyItem, + }); + } + return ( { - const img = (item.image_url || item.image_local_path || "").toString(); - if (/^https?:\/\//i.test(img)) { - return { ...item, image_url: img, image: img }; + const imgRaw = (item.image_url || item.image_local_path || "").toString(); + const categorySafe = item.category || "other"; + + const idSafe = typeof item.item_id === "number" ? item.item_id : undefined; + const nameSafe = + typeof (item as any).item_name === "string" && (item as any).item_name + ? (item as any).item_name + : undefined; + + const base = { + ...item, + // Aliases usados pelos clientes públicos (Library, etc.) + id: idSafe, + name: nameSafe, + category: categorySafe, + } as any; + + if (/^https?:\/\//i.test(imgRaw)) { + return { ...base, image_url: imgRaw, image: imgRaw }; } - if (img.startsWith("data/")) { + if (imgRaw.startsWith("data/")) { return { - ...item, - image_url: img, - image: `/api/images?path=${encodeURIComponent(img)}`, + ...base, + image_url: imgRaw, + image: `/api/images?path=${encodeURIComponent(imgRaw)}`, }; } - const category = item.category || "other"; return { - ...item, + ...base, image_url: item.image_url, - image: buildPublicItemImageUrl(category, img), + image: buildPublicItemImageUrl(categorySafe, imgRaw), }; });