From 4dd4a0ab396739d50ade9fd6e96b73c2bd94e145 Mon Sep 17 00:00:00 2001 From: "K. Allagbe" Date: Tue, 17 Dec 2024 11:56:23 -0500 Subject: [PATCH] issue #202: label data store --- src/app/label-data-confirmation/page.tsx | 13 ++++++ src/components/LabelDataValidator.tsx | 8 +++- .../__tests__/LabelDataValidator.test.tsx | 43 ++++++++++++++++++- src/stores/labelDataStore.ts | 16 +++++++ src/utils/client/constants.ts | 39 +++++++++++++++++ 5 files changed, 115 insertions(+), 4 deletions(-) create mode 100644 src/app/label-data-confirmation/page.tsx create mode 100644 src/stores/labelDataStore.ts create mode 100644 src/utils/client/constants.ts diff --git a/src/app/label-data-confirmation/page.tsx b/src/app/label-data-confirmation/page.tsx new file mode 100644 index 00000000..eb5a7131 --- /dev/null +++ b/src/app/label-data-confirmation/page.tsx @@ -0,0 +1,13 @@ +"use client"; +import useLabelDataStore from "@/stores/labelDataStore"; + +const LabelDataConfirmationPage = () => { + // use label data from store + const { labelData } = useLabelDataStore(); + + return ( +
{labelData ? JSON.stringify(labelData) : "No data available"}
+ ); +}; + +export default LabelDataConfirmationPage; diff --git a/src/components/LabelDataValidator.tsx b/src/components/LabelDataValidator.tsx index 63152956..61571ef7 100644 --- a/src/components/LabelDataValidator.tsx +++ b/src/components/LabelDataValidator.tsx @@ -11,6 +11,7 @@ import { StepperControls, StepStatus, } from "@/components/stepper"; +import useLabelDataStore from "@/stores/labelDataStore"; import { FormComponentProps, LabelData } from "@/types/types"; import { checkFieldArray, @@ -18,6 +19,7 @@ import { } from "@/utils/client/fieldValidation"; import useBreakpoints from "@/utils/client/useBreakpoints"; import { Box, Container, Typography } from "@mui/material"; +import { useRouter } from "next/navigation"; import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -34,7 +36,6 @@ function LabelDataValidator({ files, labelData, setLabelData, - inspectionId, }: LabelDataValidatorProps) { const { t } = useTranslation("labelDataValidator"); const imageFiles = files; @@ -56,6 +57,8 @@ function LabelDataValidator({ useState(StepStatus.Incomplete); const [ingredientsStepStatus, setIngredientsStepStatus] = useState(StepStatus.Incomplete); + const { setLabelData: storeLabelData } = useLabelDataStore(); + const router = useRouter(); const createStep = ( title: string, @@ -117,7 +120,8 @@ function LabelDataValidator({ ]; const submit = () => { - console.log("inspectionId:", inspectionId, "labelData", labelData); + storeLabelData(labelData); + router.push("/label-data-confirmation"); }; useEffect(() => { diff --git a/src/components/__tests__/LabelDataValidator.test.tsx b/src/components/__tests__/LabelDataValidator.test.tsx index 2d78696d..4c3b9981 100644 --- a/src/components/__tests__/LabelDataValidator.test.tsx +++ b/src/components/__tests__/LabelDataValidator.test.tsx @@ -1,7 +1,9 @@ import LabelDataValidator from "@/components/LabelDataValidator"; import { DEFAULT_LABEL_DATA } from "@/types/types"; +import { VERIFIED_LABEL_DATA } from "@/utils/client/constants"; import { act, fireEvent, render, screen } from "@testing-library/react"; import { useState } from "react"; +import useLabelDataStore from "@/stores/labelDataStore"; jest.mock("@/components/ImageViewer", () => ({ __esModule: true, @@ -10,6 +12,19 @@ jest.mock("@/components/ImageViewer", () => ({ )), })); +const mockedRouterPush = jest.fn(); +jest.mock("next/navigation", () => ({ + useRouter() { + return { + route: "/", + pathname: "", + query: "", + asPath: "", + push: mockedRouterPush, + }; + }, +})); + const mockFiles = [new File(["mock-content"], "file1.png")]; const Wrapper: React.FC<{ @@ -19,8 +34,9 @@ const Wrapper: React.FC<{ React.SetStateAction >; }) => JSX.Element; -}> = ({ children }) => { - const [labelData, setLabelData] = useState(DEFAULT_LABEL_DATA); + defaultLabelData?: typeof DEFAULT_LABEL_DATA; +}> = ({ children, defaultLabelData = DEFAULT_LABEL_DATA }) => { + const [labelData, setLabelData] = useState(defaultLabelData); return children({ labelData, setLabelData }); }; @@ -401,4 +417,27 @@ describe("LabelDataValidator and Forms Integration", () => { expect(targetSpan).not.toHaveClass("Mui-completed"); }); + + it("stores the label data and navigates to the next page when the 'Submit' button is clicked", async () => { + render( + + {({ labelData, setLabelData }) => ( + + )} + , + ); + + const submitButton = screen.getByText("stepper.submit"); + await act(async () => { + fireEvent.click(submitButton); + }); + + expect(mockedRouterPush).toHaveBeenCalledTimes(1); + expect(useLabelDataStore.getState().labelData).toStrictEqual(VERIFIED_LABEL_DATA); + expect(mockedRouterPush).toHaveBeenCalledWith("/label-data-confirmation"); + }); }); diff --git a/src/stores/labelDataStore.ts b/src/stores/labelDataStore.ts new file mode 100644 index 00000000..31298b42 --- /dev/null +++ b/src/stores/labelDataStore.ts @@ -0,0 +1,16 @@ +import { LabelData } from "@/types/types"; +import { create } from "zustand"; + +interface LabelDataState { + labelData: LabelData | null; + setLabelData: (newData: LabelData) => void; + resetLabelData: () => void; +} + +const useLabelDataStore = create((set) => ({ + labelData: null, + setLabelData: (newData) => set({ labelData: newData }), + resetLabelData: () => set({ labelData: null }), +})); + +export default useLabelDataStore; diff --git a/src/utils/client/constants.ts b/src/utils/client/constants.ts new file mode 100644 index 00000000..2097cfce --- /dev/null +++ b/src/utils/client/constants.ts @@ -0,0 +1,39 @@ +import { LabelData } from "@/types/types"; + +export const VERIFIED_LABEL_DATA: LabelData = { + organizations: [ + { + name: { value: "", verified: true }, + address: { value: "", verified: true }, + website: { value: "", verified: true }, + phoneNumber: { value: "", verified: true }, + }, + ], + baseInformation: { + name: { value: "", verified: true }, + registrationNumber: { value: "", verified: true }, + lotNumber: { value: "", verified: true }, + npk: { value: "", verified: true }, + weight: { + verified: true, + quantities: [{ value: "", unit: "" }], + }, + density: { + verified: true, + quantities: [{ value: "", unit: "" }], + }, + volume: { + verified: true, + quantities: [{ value: "", unit: "" }], + }, + }, + cautions: [{ en: "", fr: "", value: "", unit: "", verified: true }], + instructions: [{ en: "", fr: "", value: "", unit: "", verified: true }], + guaranteedAnalysis: { + titleEn: { value: "", verified: true }, + titleFr: { value: "", verified: true }, + isMinimal: { value: false, verified: true }, + nutrients: [{ en: "", fr: "", value: "", unit: "", verified: true }], + }, + ingredients: [{ en: "", fr: "", value: "", unit: "", verified: true }], +};