Skip to content

Commit

Permalink
Merge pull request #359 from ai-cfia/328-ingredients-form
Browse files Browse the repository at this point in the history
issue #328: ingredients form
  • Loading branch information
k-allagbe authored Dec 4, 2024
2 parents 260cc58 + 60643d4 commit c25b78d
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 11 deletions.
3 changes: 3 additions & 0 deletions public/locales/en/labelDataValidationPage.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
"instructions": {
"stepTitle": "Instructions"
},
"ingredients": {
"stepTitle": "Ingredients"
},
"guaranteedAnalysis": {
"stepTitle": "Guaranteed Analysis",
"title": "Title",
Expand Down
3 changes: 3 additions & 0 deletions public/locales/fr/labelDataValidationPage.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
"instructions": {
"stepTitle": "Instructions"
},
"ingredients": {
"stepTitle": "Ingrédients"
},
"guaranteedAnalysis": {
"stepTitle": "Analyse Garantie",
"title": "Titre",
Expand Down
46 changes: 40 additions & 6 deletions src/app/label-data-validation/__tests__/page.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,10 @@ describe("LabelDataValidationPage Functionality", () => {
fireEvent.click(backButton);
expect(screen.getByTestId("base-information-form")).toBeInTheDocument();

fireEvent.click(nextButton);
fireEvent.click(nextButton);
fireEvent.click(nextButton);
fireEvent.click(nextButton);
fireEvent.click(nextButton);
expect(screen.getByTestId("guaranteed-analysis-form")).toBeInTheDocument();
for (let i = 0; i < 10; i++) {
fireEvent.click(nextButton);
}
expect(screen.getByTestId("ingredients-form")).toBeInTheDocument();
});

it("renders the mocked Image Viewer", () => {
Expand Down Expand Up @@ -243,4 +241,40 @@ describe("LabelDataValidationPage and Forms Integration", () => {

expect(targetSpan).not.toHaveClass("Mui-completed");
});

it("marks the Ingredients step as Completed or Incomplete when fields are Verified", async () => {
render(<LabelDataValidationPage />);

const spans = screen.getAllByText("ingredients.stepTitle", {
exact: true,
});
const targetSpan = spans.find((span) =>
span.classList.contains("MuiStepLabel-label"),
);
expect(targetSpan).not.toHaveClass("Mui-completed");

const button = targetSpan!.closest("button");
await act(async () => {
fireEvent.click(button!);
});

const verifyButtons = screen.getAllByTestId(
/verify-row-btn-ingredients-\d+/,
);
expect(verifyButtons.length).toBeGreaterThanOrEqual(1);

for (const button of verifyButtons) {
await act(async () => {
fireEvent.click(button);
});
}

expect(targetSpan).toHaveClass("Mui-completed");

await act(async () => {
fireEvent.click(verifyButtons[0]);
});

expect(targetSpan).not.toHaveClass("Mui-completed");
});
});
20 changes: 18 additions & 2 deletions src/app/label-data-validation/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import BaseInformationForm from "@/components/BaseInformationForm";
import CautionsForm from "@/components/CautionsForm";
import GuaranteedAnalysisForm from "@/components/GuaranteedAnalysisForm";
import ImageViewer from "@/components/ImageViewer";
import IngredientsForm from "@/components/IngredientsForm";
import InstructionsForm from "@/components/InstructionsForm";
import OrganizationsForm from "@/components/OrganizationsForm";
import {
Expand Down Expand Up @@ -42,6 +43,8 @@ function LabelDataValidationPage() {
useState<StepStatus>(StepStatus.Incomplete);
const [guaranteedAnalysisStepStatus, setGuaranteedAnalysisStepStatus] =
useState<StepStatus>(StepStatus.Incomplete);
const [ingredientsStepStatus, setIngredientsStepStatus] =
useState<StepStatus>(StepStatus.Incomplete);
const { showAlert } = useAlertStore();

const createStep = (
Expand Down Expand Up @@ -91,6 +94,12 @@ function LabelDataValidationPage() {
guaranteedAnalysisStepStatus,
setGuaranteedAnalysisStepStatus,
),
createStep(
t("ingredients.stepTitle"),
IngredientsForm,
ingredientsStepStatus,
setIngredientsStepStatus,
),
];

const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
Expand Down Expand Up @@ -145,9 +154,16 @@ function LabelDataValidationPage() {
);
}, [labelData.guaranteedAnalysis, setGuaranteedAnalysisStepStatus]);

useEffect(() => {
const verified = checkFieldArray(labelData.ingredients);
setIngredientsStepStatus(
verified ? StepStatus.Completed : StepStatus.Incomplete,
);
}, [labelData.ingredients, setIngredientsStepStatus]);

return (
<Container
className="flex flex-col max-w-[1920px] bg-gray-100 "
className="flex flex-col max-w-[1920px] bg-gray-100 text-black"
maxWidth={false}
data-testid="container"
>
Expand Down Expand Up @@ -190,7 +206,7 @@ function LabelDataValidationPage() {
>
<Typography
variant="h6"
className="text-lg font-bold"
className="text-lg !font-bold"
data-testid="form-title"
>
{steps[activeStep].title}
Expand Down
41 changes: 41 additions & 0 deletions src/components/IngredientsForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { FormComponentProps, LabelData, UNITS } from "@/types/types";
import { Box } from "@mui/material";
import { useEffect } from "react";
import { FormProvider, useForm, useWatch } from "react-hook-form";
import VerifiedBilingualTable from "./VerifiedBilingualTable";

function IngredientsForm({ labelData, setLabelData }: FormComponentProps) {
const methods = useForm<LabelData>({
defaultValues: labelData,
});

const { control } = methods;

const watchedIngredients = useWatch({
control,
name: "ingredients",
});

useEffect(() => {
if (watchedIngredients) {
setLabelData((prevLabelData) => ({
...prevLabelData,
ingredients: watchedIngredients,
}));
}
}, [watchedIngredients, setLabelData]);

return (
<FormProvider {...methods}>
<Box className="p-4" data-testid="ingredients-form">
<VerifiedBilingualTable
path={"ingredients"}
unitOptions={UNITS.ingredients}
valueColumn
/>
</Box>
</FormProvider>
);
}

export default IngredientsForm;
41 changes: 41 additions & 0 deletions src/components/__tests__/IngredientsForm.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { DEFAULT_LABEL_DATA, LabelData } from "@/types/types";
import { render, screen } from "@testing-library/react";
import { useEffect, useState } from "react";
import { FormProvider, useForm } from "react-hook-form";
import IngredientsForm from "../IngredientsForm";

const Wrapper = ({
initialData,
onStateChange,
}: {
initialData: LabelData;
onStateChange?: (data: LabelData) => void;
}) => {
const [labelData, setLabelData] = useState(initialData);
const methods = useForm({
defaultValues: labelData,
});

useEffect(() => {
if (onStateChange) {
onStateChange(labelData);
}
}, [labelData, onStateChange]);

return (
<FormProvider {...methods}>
<IngredientsForm labelData={labelData} setLabelData={setLabelData} />
</FormProvider>
);
};

describe("IngredientsForm Rendering", () => {
it("should render the title input fields and nutrients table", () => {
render(<Wrapper initialData={DEFAULT_LABEL_DATA} />);

expect(screen.getByTestId("ingredients-form")).toBeInTheDocument();
expect(
screen.getByTestId("table-container-ingredients"),
).toBeInTheDocument();
});
});
8 changes: 5 additions & 3 deletions src/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ export const DEFAULT_ORGANIZATION: Organization = {
phoneNumber: DEFAULT_TEXT_FIELD,
};


// Quantity
export type Quantity = {
value: string;
Expand All @@ -112,6 +111,7 @@ export const UNITS = {
volume: ["L", "mL", "gal", "ft³"],
density: ["lb/ft³", "g/cm³", "kg/m³", "lb/gal"],
guaranteedAnalysis: ["%", "ppm"],
ingredients: ["%", "ppm"],
};

const DEFAULT_QUANTITY_FIELD = (unit: string): VerifiedQuantityField => ({
Expand Down Expand Up @@ -153,7 +153,7 @@ export const DEFAULT_BILINGUAL_FIELD: BilingualField = {
verified: false,
};

export const DEFAULT_GA_NUTRIENT: BilingualField = {
export const FULL_BILINGUAL_FIELD: BilingualField = {
en: "",
fr: "",
value: "",
Expand All @@ -172,7 +172,7 @@ export const DEFAULT_GUARANTEED_ANALYSIS: GuaranteedAnalysis = {
titleEn: DEFAULT_TEXT_FIELD,
titleFr: DEFAULT_TEXT_FIELD,
isMinimal: DEFAULT_BOOLEAN_FIELD,
nutrients: [DEFAULT_GA_NUTRIENT],
nutrients: [FULL_BILINGUAL_FIELD],
};

// LabelData
Expand All @@ -182,6 +182,7 @@ export type LabelData = {
cautions: BilingualField[];
instructions: BilingualField[];
guaranteedAnalysis: GuaranteedAnalysis;
ingredients: BilingualField[];
};

export const DEFAULT_LABEL_DATA: LabelData = {
Expand All @@ -190,6 +191,7 @@ export const DEFAULT_LABEL_DATA: LabelData = {
cautions: [DEFAULT_BILINGUAL_FIELD],
instructions: [DEFAULT_BILINGUAL_FIELD],
guaranteedAnalysis: DEFAULT_GUARANTEED_ANALYSIS,
ingredients: [FULL_BILINGUAL_FIELD],
};

// Form
Expand Down

0 comments on commit c25b78d

Please sign in to comment.