diff --git a/src/pages/nutrition/PictureSection.tsx b/src/pages/nutrition/PictureSection.tsx index 18910ccdf..7ffc7f76d 100644 --- a/src/pages/nutrition/PictureSection.tsx +++ b/src/pages/nutrition/PictureSection.tsx @@ -1,4 +1,7 @@ import * as React from "react"; +import IconButton from "@mui/material/IconButton"; +import RotateRightIcon from "@mui/icons-material/RotateRight"; +import RotateLeftIcon from "@mui/icons-material/RotateLeft"; import { InsightType } from "./insight.types"; import { ProductType } from "./useRobotoffPredictions"; import { getImageId } from "./utils"; @@ -19,6 +22,11 @@ interface PictureSectionProps { export default function PictureSection(props: PictureSectionProps) { const { isLoading, insight, product, apiRef } = props; + const [rotationIndex, setRotationIndex] = React.useState(0); + + React.useEffect(() => { + setRotationIndex(0); + }, [insight]); if (isLoading) { return

Loading ....

; } @@ -42,6 +50,12 @@ export default function PictureSection(props: PictureSectionProps) { }) : "..."}

+ setRotationIndex((p) => p - 1)}> + + + setRotationIndex((p) => p + 1)}> + + diff --git a/src/pages/nutrition/config.ts b/src/pages/nutrition/config.ts index 9360ba960..c998769a5 100644 --- a/src/pages/nutrition/config.ts +++ b/src/pages/nutrition/config.ts @@ -1 +1,153 @@ export const UNITS = ["", "g", "mg", "µg"]; + +export const OFF_NUTRIMENTS_TO_IGNORE = [ + "serving", + "energy", // Already available with energy kj and kcal. + "fruits-vegetables-legumes-estimate-from-ingredients", + "fruits-vegetables-nuts-estimate-from-ingredients", + "nova-group", + "nutrition-score-fr", +]; +export const NUTRIMENTS_ORDER = [ + // Energy + "energy-kj", + "energy-kcal", + + // Fat + "fat", + "saturated-fat", + "unsaturated-fat", + "monounsaturated-fat", + "polyunsaturated-fat", + "trans-fat", + "butyric-acid", + "caproic-acid", + "caprylic-acid", + "capric-acid", + "lauric-acid", + "myristic-acid", + "palmitic-acid", + "stearic-acid", + "arachidic-acid", + "behenic-acid", + "lignoceric-acid", + "cerotic-acid", + "montanic-acid", + "melissic-acid", + + // Sucres + "carbohydrates", + "sugars", + "added-sugars", + "sucrose", + "glucose", + "fructose", + "lactose", + "maltose", + "maltodextrins", + + "fiber", + "soluble-fiber", + "insoluble-fiber", + + "proteins", + "casein", + "serum-proteins", + + "salt", + "added-salt", + "sodium", + + "cholesterol", + + "alpha-linolenic-acid", + "eicosapentaenoic-acid", + "docosahexaenoic-acid", + "omega-3-fat", + "omega-6-fat", + "linoleic-acid", + "arachidonic-acid", + "gamma-linolenic-acid", + "dihomo-gamma-linolenic-acid", + "omega-9-fat", + "oleic-acid", + "elaidic-acid", + "gondoic-acid", + "mead-acid", + "erucic-acid", + "nervonic-acid", + + "oligosaccharide", + + "galactose", + "starch", + "Polydextrose", + "polyols", + "erythritol", + + "nucleotides", + "alcohol", + "vitamin-a", + "beta-carotene", + "vitamin-d", + "vitamin-e", + "vitamin-k", + "vitamin-c", + "vitamin-b1", + "vitamin-b2", + "vitamin-pp", + "vitamin-b6", + "vitamin-b9", + "folates", + "vitamin-b12", + "biotin", + "pantothenic-acid", + "silica", + "bicarbonate", + "Sulphate", + "Nitrate", + "Hydrogencarbonate", + "Nitrite", + "potassium", + "chloride", + "calcium", + "phosphorus", + "iron", + "magnesium", + "zinc", + "copper", + "manganese", + "fluoride", + "selenium", + "chromium", + "molybdenum", + "iodine", + "caffeine", + "taurine", + "ph", + "collagen-meat-protein-ratio", + "cocoa", + "chlorophyl", + "glycemic-index", + "water-hardness", + "choline", + "phylloquinone", + "beta-glucan", + "inositol", + "carnitine", + "spermidine", + "water", + "acidity", + "dry-residue", + "beta-alanine", + "creatine", + "l-citrulline", + "l-glutamine", + "bcaa", + "l-valine", + "l-leucine", + "l-isoleucine", + "l-arginine", + "l-cysteine", + "l-Glutathione", +]; diff --git a/src/pages/nutrition/index.tsx b/src/pages/nutrition/index.tsx index 8b97c4b20..19a5228d1 100644 --- a/src/pages/nutrition/index.tsx +++ b/src/pages/nutrition/index.tsx @@ -15,6 +15,7 @@ import { ErrorBoundary } from "../taxonomyWalk/Error"; import LinksToProduct from "./LinksToProduct"; import { NutrimentCell } from "./NutrimentCell"; import PictureSection from "./PictureSection"; +import { NUTRIMENTS_ORDER } from "./config"; export default function Nutrition() { const [partiallyFilled, setPartiallyFilled] = React.useState(false); @@ -22,7 +23,8 @@ export default function Nutrition() { const handlePartiallyFilled = (_, checked) => setPartiallyFilled(checked); const handleDisplayOFFValue = (_, checked) => setDisplayOFFValue(checked); - console.log({ partiallyFilled }); + const [additionalIds, setAdditionalIds] = React.useState([]); + const { isLoading, insight, nextItem, count, product } = useRobotoffPredictions(partiallyFilled); @@ -32,6 +34,7 @@ export default function Nutrition() { const apiRef = React.useRef(); React.useEffect(() => { + setAdditionalIds([]); if (!insight || typeof insight === "string") { setValues({}); return; @@ -62,8 +65,15 @@ export default function Nutrition() { })); }, [insight]); - const nutrimentsDetected = structurePredictions(values); + const nutrimentsDetected = React.useMemo( + () => structurePredictions(values, product, additionalIds), + [values, product, additionalIds], + ); + const notUsedNutriments = React.useMemo( + () => NUTRIMENTS_ORDER.filter((id) => !nutrimentsDetected.includes(id)), + [nutrimentsDetected], + ); return ( @@ -195,6 +205,29 @@ export default function Nutrition() { ); })} + + + + + + + diff --git a/src/pages/nutrition/utils.ts b/src/pages/nutrition/utils.ts index c8ff42652..e4f919e78 100644 --- a/src/pages/nutrition/utils.ts +++ b/src/pages/nutrition/utils.ts @@ -1,5 +1,5 @@ import axios from "axios"; -import { UNITS } from "./config"; +import { OFF_NUTRIMENTS_TO_IGNORE, UNITS } from "./config"; import { NutrimentPrediction } from "./insight.types"; import { ROBOTOFF_API_URL } from "../../const"; @@ -15,6 +15,7 @@ export const NUTRIMENTS = { fiber: "fiber", proteins: "proteins", salt: "salt", + sodium: "sodium", }; export function isValidUnit(unit: string | null) { @@ -23,21 +24,34 @@ export function isValidUnit(unit: string | null) { export function structurePredictions( predictions: Record>, + productValue?: { nutriments?: Record }, + additionalIds?: string[], ) { const nurimentsIds = Object.keys(NUTRIMENTS); Object.keys(predictions).forEach((key) => { - if (key === "serving_size") { + const id = key.split("_")[0]; // split 'energy-kj_100g' to only get 'energy-kj' + + if (OFF_NUTRIMENTS_TO_IGNORE.includes(id)) { return; } + if (!nurimentsIds.includes(id)) { + nurimentsIds.push(id); + } + }); + + Object.keys(productValue?.nutriments ?? {}).forEach((key) => { const id = key.split("_")[0]; // split 'energy-kj_100g' to only get 'energy-kj' + if (OFF_NUTRIMENTS_TO_IGNORE.includes(id)) { + return; + } if (!nurimentsIds.includes(id)) { nurimentsIds.push(id); } }); - return nurimentsIds; + return [...nurimentsIds, ...additionalIds]; } interface PostRobotoffParams {