import { useEffect, useState } from "react"; import { ArrowLeft } from "lucide-react"; import { api } from "../api"; import type { Product } from "../types"; import { NUTRIMENT_LABELS } from "../types"; function Row({ label, value }: { label: string; value: React.ReactNode }) { if (value === null || value === undefined || value === "") return null; return (
{label}
{value}
); } export default function ProductView({ id, onBack }: { id: string; onBack: () => void }) { const [p, setP] = useState(null); const [error, setError] = useState(""); useEffect(() => { api.product(id).then(setP).catch((e) => setError(e.message)); }, [id]); if (error) { return (
{error}
); } if (!p) return
加载中…
; const basisLabel: Record = { per_100g: "每 100g", per_100ml: "每 100ml", per_serving: "每份", }; const nutriEntries = Object.entries(p.nutriments || {}).filter( ([, v]) => v !== null && v !== undefined, ); const latestMsrp = (p.msrp || [])[0]; const msrpText = latestMsrp ? latestMsrp.currency === "CNY" ? `¥${latestMsrp.amount.toFixed(2)}` : `${latestMsrp.amount.toFixed(2)} ${latestMsrp.currency}` : null; return (

{p.name}

质量分 {Math.round(p.quality_score * 100)}
{(() => { const others = (p.barcodes || []).filter( (b) => !b.is_primary && b.gtin !== p.gtin, ); return others.length ? ( {others.map((b) => ( {b.gtin} ))}
} /> ) : null; })()} {msrpText} 厂商建议,仅供参考 ) : null } />
{p.specs && p.specs.length > 0 && (

规格参数

{p.specs.map((s) => (
{s.label}
{s.value} {s.unit ? ` ${s.unit}` : ""}
))}
)} {nutriEntries.length > 0 && (

营养成分 {p.nutrition_basis ? `(${basisLabel[p.nutrition_basis] || p.nutrition_basis})` : ""}

{nutriEntries.map(([k, v]) => (
{NUTRIMENT_LABELS[k] || k}
{String(v)}
))}
)} ); }