Skip to content
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

Show data from OFF #1089

Merged
merged 4 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 37 additions & 15 deletions src/pages/nutrition/NutrimentCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,24 @@ interface NutrimentCellProps {
tabIndex: number;
value?: string;
unit?: string;
productValue?: number;
productUnit?: string;
displayOFFValue: boolean;
setValues: (object) => void;
}

export const NutrimentCell = (props: NutrimentCellProps) => {
const { nutrimentId, nutrimentKey, tabIndex, value, unit, setValues } = props;
const {
nutrimentId,
nutrimentKey,
tabIndex,
value,
unit,
setValues,
productValue,
productUnit,
displayOFFValue,
} = props;

return (
<td
Expand All @@ -34,20 +47,29 @@ export const NutrimentCell = (props: NutrimentCellProps) => {
element.classList.remove("focused");
}}
>
<input
style={{ marginRight: 4, maxWidth: 100 }}
value={value ?? ""}
tabIndex={tabIndex}
onChange={(event) =>
setValues((p) => ({
...p,
[nutrimentKey]: {
...p[nutrimentKey],
value: event.target.value,
},
}))
}
/>
<div style={{ display: "inline-table" }}>
<input
style={{ marginRight: 4, maxWidth: 80 }}
value={value ?? ""}
tabIndex={tabIndex}
onChange={(event) =>
setValues((p) => ({
...p,
[nutrimentKey]: {
...p[nutrimentKey],
value: event.target.value,
},
}))
}
/>
<br />
{displayOFFValue && (
<legend style={{ fontSize: 13, textAlign: "end" }}>
{productValue}
{productUnit}
</legend>
)}
</div>

{isValidUnit(unit) ? (
<select
Expand Down
267 changes: 175 additions & 92 deletions src/pages/nutrition/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import {
TransformComponent,
TransformWrapper,
} from "react-zoom-pan-pinch";
import { Box, Button } from "@mui/material";
import { Box, Button, Checkbox, FormControlLabel } from "@mui/material";
import Stack from "@mui/material/Stack";
import {
deleteRobotoff,
getImageId,
NUTRIMENTS,
postRobotoff,
skipRobotoff,
Expand All @@ -21,7 +22,13 @@ import LinksToProduct from "./LinksToProduct";
import { NutrimentCell } from "./NutrimentCell";

export default function Nutrition() {
const { isLoading, insight, nextItem, count } = useRobotoffPredicitions();
const [partiallyFilled, setPartiallyFilled] = React.useState(false);
const [displayOFFValue, setDisplayOFFValue] = React.useState(false);
const handlePartiallyFilled = (_, checked) => setPartiallyFilled(checked);
const handleDisplayOFFValue = (_, checked) => setDisplayOFFValue(checked);

const { isLoading, insight, nextItem, count, product } =
useRobotoffPredicitions(partiallyFilled);

const [values, setValues] = React.useState<
Record<string, Pick<NutrimentPrediction, "value" | "unit">>
Expand Down Expand Up @@ -67,11 +74,29 @@ export default function Nutrition() {
}

const nutrimentsDetected = structurePredictions(values);

const imageId = getImageId(insight.source_image);

const imageTimestamp = product?.images?.[imageId]?.uploaded_t;

return (
<React.Suspense>
<ErrorBoundary>
<Stack direction="row">
<Box sx={{ width: "50%" }}>
<p>
Photo upload:{" "}
{imageTimestamp
? new Date(imageTimestamp * 1000).toLocaleDateString(
undefined,
{
day: "2-digit",
month: "long",
year: "numeric",
},
)
: "..."}
</p>
<TransformWrapper limitToBounds={false} ref={apiRef}>
<TransformComponent>
<img
Expand All @@ -87,6 +112,27 @@ export default function Nutrition() {
</TransformWrapper>
</Box>
<Stack direction="column" sx={{ width: "50%", p: 2 }}>
<Box>
<FormControlLabel
control={
<Checkbox
checked={partiallyFilled}
onChange={handlePartiallyFilled}
/>
}
label="Tableau partielement rempli"
/>
<FormControlLabel
disabled={!partiallyFilled}
control={
<Checkbox
checked={partiallyFilled ? displayOFFValue : false}
onChange={handleDisplayOFFValue}
/>
}
label="afficher le valeurs OFF"
/>
</Box>
<LinksToProduct
barcode={insight.barcode}
count={count}
Expand All @@ -96,106 +142,143 @@ export default function Nutrition() {
<Box
sx={(theme) => ({
width: "fit-content",
"& tr": { verticalAlign: "top" },
"& .focused": {
backgroundColor: theme.palette.divider,
fontWeight: "bold",
},
})}
>
<table>
<tr>
<td>Nutriments</td>
<td>100g</td>
<td>
serving{" "}
<input
tabIndex={2}
value={insight.data.nutrients?.serving_size?.value ?? ""}
style={{ maxWidth: 100 }}
/>
</td>
</tr>
{nutrimentsDetected.map((nutrimentId) => {
const key100g = `${nutrimentId}_100g`;
const { value: value100g, unit: unit100g } =
values[key100g] ?? {};
<thead>
<tr>
<td>Nutriments</td>
<td>100g</td>
<td>
serving{" "}
<div style={{ display: "inline-table" }}>
<input
tabIndex={2}
value={
insight.data.nutrients?.serving_size?.value ?? ""
}
onChange={(event) =>
setValues((p) => ({
...p,
serving_size: {
...p.serving_size,
value: event.target.value,
},
}))
}
style={{ width: 100 }}
/>
<br />
{displayOFFValue && (
<legend style={{ fontSize: 13, textAlign: "end" }}>
{product?.serving_size}
</legend>
)}
</div>
</td>
</tr>
</thead>
<tbody>
{nutrimentsDetected.map((nutrimentId) => {
const key100g = `${nutrimentId}_100g`;
const { value: value100g, unit: unit100g } =
values[key100g] ?? {};

const keyServing = `${nutrimentId}_serving`;
const { value: valueServing, unit: unitServing } =
values[keyServing] ?? {};

const keyServing = `${nutrimentId}_serving`;
const { value: valueServing, unit: unitServing } =
values[keyServing] ?? {};
const product100g = product?.nutriments?.[key100g];
const productServing = product?.nutriments?.[keyServing];
const productUnit =
product?.nutriments?.[`${nutrimentId}_unit`];

return (
<tr
key={nutrimentId}
// Attributes used to highlight when focusing
data-label-id={nutrimentId}
>
<td style={{ paddingLeft: 10, paddingRight: 4 }}>
{NUTRIMENTS[nutrimentId] ?? nutrimentId}
</td>
<NutrimentCell
return (
<tr
key={nutrimentId}
// Attributes used to highlight when focusing
data-label-id={nutrimentId}
>
<td style={{ paddingLeft: 10, paddingRight: 4 }}>
{NUTRIMENTS[nutrimentId] ?? nutrimentId}
</td>
<NutrimentCell
tabIndex={1}
nutrimentId={nutrimentId}
nutrimentKey={key100g}
value={value100g}
unit={unit100g}
setValues={setValues}
productValue={product100g}
productUnit={productUnit}
displayOFFValue={displayOFFValue}
/>
<NutrimentCell
tabIndex={2}
nutrimentId={nutrimentId}
nutrimentKey={keyServing}
value={valueServing}
unit={unitServing}
setValues={setValues}
productValue={productServing}
productUnit={productUnit}
displayOFFValue={displayOFFValue}
/>
</tr>
);
})}
</tbody>
<tfoot>
<tr>
<td></td>
<td>
<Button
tabIndex={1}
nutrimentId={nutrimentId}
nutrimentKey={key100g}
value={value100g}
unit={unit100g}
setValues={setValues}
/>
<NutrimentCell
variant="contained"
color="success"
sx={{
ml: 1,
mt: 2,
}}
onClick={() => {
postRobotoff({
insightId: insight.id,
data: values,
type: "100g",
});
nextItem();
apiRef.current.resetTransform();
}}
>
Valider (100g)
</Button>
</td>
<td>
<Button
tabIndex={2}
nutrimentId={nutrimentId}
nutrimentKey={keyServing}
value={valueServing}
unit={unitServing}
setValues={setValues}
/>
</tr>
);
})}

<tr>
<td></td>
<td>
<Button
tabIndex={1}
variant="contained"
color="success"
sx={{
ml: 1,
mt: 2,
}}
onClick={() => {
postRobotoff({
insightId: insight.id,
data: values,
type: "100g",
});
nextItem();
apiRef.current.resetTransform();
}}
>
Valider (100g)
</Button>
</td>
<td>
<Button
tabIndex={2}
variant="contained"
color="success"
sx={{ ml: 1, mt: 2 }}
onClick={() => {
postRobotoff({
insightId: insight.id,
data: values,
type: "serving",
});
nextItem();
apiRef.current.resetTransform();
}}
>
Valider (serving)
</Button>
</td>
</tr>
variant="contained"
color="success"
sx={{ ml: 1, mt: 2 }}
onClick={() => {
postRobotoff({
insightId: insight.id,
data: values,
type: "serving",
});
nextItem();
apiRef.current.resetTransform();
}}
>
Valider (serving)
</Button>
</td>
</tr>
</tfoot>
</table>
</Box>

Expand Down
Loading
Loading