refactor(product page, api): improve error handling and enhance type safety
- Refactored error handling in the product page to simplify catch block. - Updated type definitions in openFoodFactsApi for better type safety. - Introduced utility functions for search type detection and barcode validation.
This commit is contained in:
1 parent
f98c648311
commit
c99c82c837
2 files changed
+29
-13
No files matched your search
@@ -4,21 +4,21 @@ import React, { useState, useEffect, useCallback } from "react";
|
|||||||
import { useParams, useRouter } from "next/navigation";
|
import { useParams, useRouter } from "next/navigation";
|
||||||
import { motion, AnimatePresence } from "framer-motion";
|
import { motion, AnimatePresence } from "framer-motion";
|
||||||
import {
|
import {
|
||||||
ArrowLeft, AlertCircle, AlertTriangle,
|
ArrowLeft,
|
||||||
Database, Globe, ShieldCheck, Beaker, ClipboardList
|
AlertCircle,
|
||||||
|
AlertTriangle,
|
||||||
|
Database,
|
||||||
|
Globe,
|
||||||
|
ShieldCheck,
|
||||||
|
Beaker,
|
||||||
|
ClipboardList,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import {
|
import { searchByBarcode, Product, formatNutritionData } from "@/lib/openFoodFactsApi";
|
||||||
searchByBarcode,
|
|
||||||
Product,
|
|
||||||
formatNutritionData,
|
|
||||||
} from "@/lib/openFoodFactsApi";
|
|
||||||
import Link from "next/link";
|
|
||||||
import { NutriScoreBadge, NovaBadge } from "@/app/components/NutriScoreBadge";
|
import { NutriScoreBadge, NovaBadge } from "@/app/components/NutriScoreBadge";
|
||||||
import { NutritionGrid } from "@/app/components/NutritionBar";
|
import { NutritionGrid } from "@/app/components/NutritionBar";
|
||||||
import { ProductSkeleton } from "@/app/components/ProductSkeleton";
|
import { ProductSkeleton } from "@/app/components/ProductSkeleton";
|
||||||
import { cn } from "@/lib/utils";
|
|
||||||
|
|
||||||
export default function ProdutoPage() {
|
export default function ProdutoPage() {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
@@ -36,7 +36,7 @@ export default function ProdutoPage() {
|
|||||||
const result = await searchByBarcode(barcode);
|
const result = await searchByBarcode(barcode);
|
||||||
if (result) setProduct(result);
|
if (result) setProduct(result);
|
||||||
else setError("Produto não catalogado na base ODbL.");
|
else setError("Produto não catalogado na base ODbL.");
|
||||||
} catch (err) {
|
} catch {
|
||||||
setError("Falha crítica na sincronização de dados.");
|
setError("Falha crítica na sincronização de dados.");
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
|||||||
+19
-3
@@ -17,7 +17,7 @@ export interface Product {
|
|||||||
sugars_100g?: number;
|
sugars_100g?: number;
|
||||||
fiber_100g?: number;
|
fiber_100g?: number;
|
||||||
sodium_100g?: number;
|
sodium_100g?: number;
|
||||||
[key: string]: any; // Flexibilidade para outros nutrientes
|
[key: string]: number | undefined; // Flexibilidade para outros nutrientes mantendo tipagem segura
|
||||||
};
|
};
|
||||||
nutrition_grades?: string;
|
nutrition_grades?: string;
|
||||||
nova_group?: number;
|
nova_group?: number;
|
||||||
@@ -240,8 +240,11 @@ export function formatNutritionData(p: Product) {
|
|||||||
const n = p.nutriments;
|
const n = p.nutriments;
|
||||||
if (!n) return null;
|
if (!n) return null;
|
||||||
|
|
||||||
const fmt = (v: any, d: number = 1) => {
|
const fmt = (v: unknown, d: number = 1) => {
|
||||||
const num = parseFloat(v);
|
const num =
|
||||||
|
typeof v === "number"
|
||||||
|
? v
|
||||||
|
: parseFloat(typeof v === "string" ? v : String(v));
|
||||||
return isNaN(num) ? "N/A" : num.toFixed(d);
|
return isNaN(num) ? "N/A" : num.toFixed(d);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -254,3 +257,16 @@ export function formatNutritionData(p: Product) {
|
|||||||
sodium: n.sodium_100g ? `${fmt(n.sodium_100g, 2)}g` : "N/A",
|
sodium: n.sodium_100g ? `${fmt(n.sodium_100g, 2)}g` : "N/A",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utilitários de detecção e validação de busca
|
||||||
|
*/
|
||||||
|
export function detectSearchType(input: string): "barcode" | "name" {
|
||||||
|
const cleaned = input.replace(/\D/g, "");
|
||||||
|
return cleaned.length >= 8 && cleaned.length <= 13 ? "barcode" : "name";
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isValidBarcode(barcode: string): boolean {
|
||||||
|
const cleaned = barcode.replace(/\D/g, "");
|
||||||
|
return cleaned.length >= 8 && cleaned.length <= 13 && /^\d+$/.test(cleaned);
|
||||||
|
}
|
||||||
Reference in new issue
Block a user