import { PlusIcon, Trash2Icon } from "lucide-react"; import { useMemo, useState } from "react"; import { NutritionnalValues } from "@/back/types/products"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; export type NutrientKey = keyof Omit; export interface NutrientDefinition { key: NutrientKey; label: string; defaultUnit: "g" | "kcal" | "kj"; unitLabel: string; } export const NUTRIENT_DEFINITIONS: readonly NutrientDefinition[] = [ { key: "kcal", label: "Énergie (Kilocalorie)", defaultUnit: "kcal", unitLabel: "Kcal", }, { key: "kj", label: "Énergie (Kilojoule)", defaultUnit: "kj", unitLabel: "Kj", }, { key: "proteinG", label: "Protéines", defaultUnit: "g", unitLabel: "g", }, { key: "carbG", label: "Glucides", defaultUnit: "g", unitLabel: "g", }, { key: "sugarG", label: "Sucres", defaultUnit: "g", unitLabel: "g", }, { key: "fatG", label: "Matières grasses", defaultUnit: "g", unitLabel: "g", }, { key: "satFatG", label: "Acides gras saturés", defaultUnit: "g", unitLabel: "g", }, { key: "fiberG", label: "Fibres alimentaires", defaultUnit: "g", unitLabel: "g", }, { key: "saltG", label: "Sel", defaultUnit: "g", unitLabel: "g", }, ] as const; interface NutritionalValuesInputProps { value: NutritionnalValues | null | undefined; setData: (key: string, value: unknown) => void; parentErrors?: Record | null; } export default function NutritionalValuesInput({ value, setData, parentErrors, }: Readonly) { const initialKeys = useMemo(() => { if (!value) return []; return NUTRIENT_DEFINITIONS.filter( (def) => value[def.key] !== null && value[def.key] !== undefined && (value[def.key]?.value !== "" || value[def.key]?.value !== undefined), ).map((def) => def.key); }, [value]); const [activeKeys, setActiveKeys] = useState(initialKeys); const refWeight = value?.refWeightG?.value ?? "100"; const refWeightUnit = value?.refWeightG?.unit ?? "g"; const handleRefWeightChange = (newVal: string) => { setData("nutritional_values", { ...value, refWeightG: { value: newVal, unit: refWeightUnit, }, }); }; const handleAddLine = () => { const nextDef = NUTRIENT_DEFINITIONS.find( (def) => !activeKeys.includes(def.key), ); if (!nextDef) return; setActiveKeys((prev) => [...prev, nextDef.key]); setData("nutritional_values", { ...value, refWeightG: value?.refWeightG ?? { value: refWeight, unit: "g" }, [nextDef.key]: { value: "", unit: nextDef.defaultUnit, }, }); }; const handleRemoveLine = (keyToRemove: NutrientKey) => { setActiveKeys((prev) => prev.filter((k) => k !== keyToRemove)); const updatedValues = { ...value }; delete updatedValues[keyToRemove]; setData("nutritional_values", updatedValues); }; const handleNutrientChange = (oldKey: NutrientKey, newKeyString: string) => { const newKey = newKeyString as NutrientKey; if (oldKey === newKey) return; const newDef = NUTRIENT_DEFINITIONS.find((def) => def.key === newKey); if (!newDef) return; const prevNutrientVal = value?.[oldKey]?.value ?? ""; setActiveKeys((prev) => prev.map((k) => (k === oldKey ? newKey : k))); const updatedValues = { ...value }; delete updatedValues[oldKey]; updatedValues[newKey] = { value: prevNutrientVal, unit: newDef.defaultUnit, }; setData("nutritional_values", updatedValues); }; const handleValueChange = (key: NutrientKey, val: string) => { const def = NUTRIENT_DEFINITIONS.find((d) => d.key === key); if (!def) return; const currentUnit = value?.[key]?.unit ?? def.defaultUnit; setData("nutritional_values", { ...(value ?? {}), refWeightG: value?.refWeightG ?? { value: refWeight, unit: "g" }, [key]: { value: val, unit: currentUnit, }, }); }; const hasAvailableNutrients = activeKeys.length < NUTRIENT_DEFINITIONS.length; return (
{/* Poids de référence */}
handleRefWeightChange(e.target.value)} className="w-32" /> {refWeightUnit}
{/* Gestion des lignes */}

Valeurs de référence

{hasAvailableNutrients && ( )}
{activeKeys.length === 0 ? (

Aucune ligne nutritionnelle renseignée. Cliquez sur "Ajouter une ligne" pour en ajouter une.

) : (
{activeKeys.map((key) => { const def = NUTRIENT_DEFINITIONS.find((d) => d.key === key); if (!def) return null; const nutrientVal = value?.[key]?.value ?? ""; const unitLabel = def.unitLabel; return (
{/* Select Libellé valeur / Unité */}
{/* Champ Valeur */}
handleValueChange(key, e.target.value)} className="bg-white pr-14" /> {unitLabel}
); })}
)}
{parentErrors?.nutritional_values && (

{parentErrors.nutritional_values}

)}
); }