| @@ -1,6 +1,6 @@ | |||||
| import { SearchParams } from "@/app/utils/fetchUtil"; | import { SearchParams } from "@/app/utils/fetchUtil"; | ||||
| import { TypeEnum } from "@/app/utils/typeEnum"; | import { TypeEnum } from "@/app/utils/typeEnum"; | ||||
| import CreateProductMaterial from "@/components/CreateProductMaterial"; | |||||
| import CreateProductMaterial from "@/components/CreateItem"; | |||||
| import { I18nProvider, getServerI18n } from "@/i18n"; | import { I18nProvider, getServerI18n } from "@/i18n"; | ||||
| import { Typography } from "@mui/material"; | import { Typography } from "@mui/material"; | ||||
| import { isString } from "lodash"; | import { isString } from "lodash"; | ||||
| @@ -15,7 +15,7 @@ const byProductSetting: React.FC<Props> = async ({ searchParams }) => { | |||||
| return ( | return ( | ||||
| <> | <> | ||||
| {/* <Typography variant="h4">{t("Create Material")}</Typography> */} | {/* <Typography variant="h4">{t("Create Material")}</Typography> */} | ||||
| <I18nProvider namespaces={[type]}> | |||||
| <I18nProvider namespaces={[type.toString()]}> | |||||
| <CreateProductMaterial type={type} /> | <CreateProductMaterial type={type} /> | ||||
| </I18nProvider> | </I18nProvider> | ||||
| </> | </> | ||||
| @@ -1,6 +1,6 @@ | |||||
| import { SearchParams } from "@/app/utils/fetchUtil"; | import { SearchParams } from "@/app/utils/fetchUtil"; | ||||
| import { TypeEnum } from "@/app/utils/typeEnum"; | import { TypeEnum } from "@/app/utils/typeEnum"; | ||||
| import CreateProductMaterial from "@/components/CreateProductMaterial"; | |||||
| import CreateProductMaterial from "@/components/CreateItem"; | |||||
| import { I18nProvider, getServerI18n } from "@/i18n"; | import { I18nProvider, getServerI18n } from "@/i18n"; | ||||
| import { Typography } from "@mui/material"; | import { Typography } from "@mui/material"; | ||||
| import { isString } from "lodash"; | import { isString } from "lodash"; | ||||
| @@ -1,5 +1,5 @@ | |||||
| import { TypeEnum } from "@/app/utils/typeEnum"; | import { TypeEnum } from "@/app/utils/typeEnum"; | ||||
| import MaterialSearch from "@/components/ProductMaterialSearch"; | |||||
| import MaterialSearch from "@/components/ItemsSearch"; | |||||
| import { getServerI18n } from "@/i18n"; | import { getServerI18n } from "@/i18n"; | ||||
| import Add from "@mui/icons-material/Add"; | import Add from "@mui/icons-material/Add"; | ||||
| import Button from "@mui/material/Button"; | import Button from "@mui/material/Button"; | ||||
| @@ -1,6 +1,6 @@ | |||||
| import { SearchParams } from "@/app/utils/fetchUtil"; | import { SearchParams } from "@/app/utils/fetchUtil"; | ||||
| import { TypeEnum } from "@/app/utils/typeEnum"; | import { TypeEnum } from "@/app/utils/typeEnum"; | ||||
| import CreateProductMaterial from "@/components/CreateProductMaterial"; | |||||
| import CreateProductMaterial from "@/components/CreateItem"; | |||||
| import { I18nProvider, getServerI18n } from "@/i18n"; | import { I18nProvider, getServerI18n } from "@/i18n"; | ||||
| import { Typography } from "@mui/material"; | import { Typography } from "@mui/material"; | ||||
| import { isString } from "lodash"; | import { isString } from "lodash"; | ||||
| @@ -1,6 +1,6 @@ | |||||
| import { SearchParams } from "@/app/utils/fetchUtil"; | import { SearchParams } from "@/app/utils/fetchUtil"; | ||||
| import { TypeEnum } from "@/app/utils/typeEnum"; | import { TypeEnum } from "@/app/utils/typeEnum"; | ||||
| import CreateProductMaterial from "@/components/CreateProductMaterial"; | |||||
| import CreateProductMaterial from "@/components/CreateItem"; | |||||
| import { I18nProvider, getServerI18n } from "@/i18n"; | import { I18nProvider, getServerI18n } from "@/i18n"; | ||||
| import { Typography } from "@mui/material"; | import { Typography } from "@mui/material"; | ||||
| import { isString } from "lodash"; | import { isString } from "lodash"; | ||||
| @@ -22,7 +22,7 @@ const materialSetting: React.FC<Props> = async ({ searchParams }) => { | |||||
| return ( | return ( | ||||
| <> | <> | ||||
| {/* <Typography variant="h4">{t("Create Material")}</Typography> */} | {/* <Typography variant="h4">{t("Create Material")}</Typography> */} | ||||
| <I18nProvider namespaces={[type]}> | |||||
| <I18nProvider namespaces={[type.toString()]}> | |||||
| <CreateProductMaterial type={type} id={id} /> | <CreateProductMaterial type={type} id={id} /> | ||||
| </I18nProvider> | </I18nProvider> | ||||
| </> | </> | ||||
| @@ -1,5 +1,5 @@ | |||||
| import { TypeEnum } from "@/app/utils/typeEnum"; | import { TypeEnum } from "@/app/utils/typeEnum"; | ||||
| import MaterialSearch from "@/components/ProductMaterialSearch"; | |||||
| import MaterialSearch from "@/components/ItemsSearch"; | |||||
| import { getServerI18n } from "@/i18n"; | import { getServerI18n } from "@/i18n"; | ||||
| import Add from "@mui/icons-material/Add"; | import Add from "@mui/icons-material/Add"; | ||||
| import Button from "@mui/material/Button"; | import Button from "@mui/material/Button"; | ||||
| @@ -15,7 +15,7 @@ export const metadata: Metadata = { | |||||
| const materialSetting: React.FC = async () => { | const materialSetting: React.FC = async () => { | ||||
| const material = TypeEnum.MATERIAL | const material = TypeEnum.MATERIAL | ||||
| const { t } = await getServerI18n(material); | |||||
| const { t } = await getServerI18n("material"); | |||||
| // preloadClaims(); | // preloadClaims(); | ||||
| return ( | return ( | ||||
| @@ -1,6 +1,6 @@ | |||||
| import { SearchParams } from "@/app/utils/fetchUtil"; | import { SearchParams } from "@/app/utils/fetchUtil"; | ||||
| import { TypeEnum } from "@/app/utils/typeEnum"; | import { TypeEnum } from "@/app/utils/typeEnum"; | ||||
| import CreateProductMaterial from "@/components/CreateProductMaterial"; | |||||
| import CreateProductMaterial from "@/components/CreateItem"; | |||||
| import { I18nProvider, getServerI18n } from "@/i18n"; | import { I18nProvider, getServerI18n } from "@/i18n"; | ||||
| import { Typography } from "@mui/material"; | import { Typography } from "@mui/material"; | ||||
| import isString from "lodash/isString"; | import isString from "lodash/isString"; | ||||
| @@ -1,6 +1,6 @@ | |||||
| import { SearchParams } from "@/app/utils/fetchUtil"; | import { SearchParams } from "@/app/utils/fetchUtil"; | ||||
| import { TypeEnum } from "@/app/utils/typeEnum"; | import { TypeEnum } from "@/app/utils/typeEnum"; | ||||
| import CreateProductMaterial from "@/components/CreateProductMaterial"; | |||||
| import CreateProductMaterial from "@/components/CreateItem"; | |||||
| import { I18nProvider, getServerI18n } from "@/i18n"; | import { I18nProvider, getServerI18n } from "@/i18n"; | ||||
| import { Typography } from "@mui/material"; | import { Typography } from "@mui/material"; | ||||
| import isString from "lodash/isString"; | import isString from "lodash/isString"; | ||||
| @@ -1,5 +1,5 @@ | |||||
| import { TypeEnum } from "@/app/utils/typeEnum"; | import { TypeEnum } from "@/app/utils/typeEnum"; | ||||
| import MaterialSearch from "@/components/ProductMaterialSearch"; | |||||
| import MaterialSearch from "@/components/ItemsSearch"; | |||||
| import { getServerI18n } from "@/i18n"; | import { getServerI18n } from "@/i18n"; | ||||
| import Add from "@mui/icons-material/Add"; | import Add from "@mui/icons-material/Add"; | ||||
| import Button from "@mui/material/Button"; | import Button from "@mui/material/Button"; | ||||
| @@ -1,39 +0,0 @@ | |||||
| "use server"; | |||||
| import { ServerFetchError, serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil"; | |||||
| import { revalidateTag } from "next/cache"; | |||||
| import { BASE_API_URL } from "@/config/api"; | |||||
| import { TypeInputs, UomInputs, WeightUnitInputs } from "../material/actions"; | |||||
| import { CreateItemResponse } from "../../utils"; | |||||
| export type CreateByProductInputs = { | |||||
| id?: string | number | |||||
| code: string; | |||||
| name: string; | |||||
| // same goes for other props | |||||
| // change backend for null or not null | |||||
| description?: string | undefined; | |||||
| remarks?: string | undefined; | |||||
| shelfLife?: Number | undefined; | |||||
| countryOfOrigin?: string | undefined; | |||||
| minHumid?: number | undefined; | |||||
| maxHumid?: number | undefined; | |||||
| minTemp?: number | undefined; | |||||
| maxTemp?: number | undefined; | |||||
| sampleRate?: number | undefined; | |||||
| passingRate?: number | undefined; | |||||
| netWeight?: number | undefined; | |||||
| type?: TypeInputs[]; | |||||
| uom?: UomInputs[]; | |||||
| weightUnit?: WeightUnitInputs[]; | |||||
| } | |||||
| export const saveByProduct = async (data: CreateByProductInputs) => { | |||||
| // try { | |||||
| const byProduct = await serverFetchJson<CreateItemResponse<CreateByProductInputs>>(`${BASE_API_URL}/byProduct/new`, { | |||||
| method: "POST", | |||||
| body: JSON.stringify(data), | |||||
| headers: { "Content-Type": "application/json" }, | |||||
| }); | |||||
| revalidateTag("byProduct"); | |||||
| return byProduct | |||||
| }; | |||||
| @@ -1,40 +0,0 @@ | |||||
| import { cache } from "react"; | |||||
| import "server-only"; | |||||
| import { serverFetchJson } from "@/app/utils/fetchUtil"; | |||||
| import { BASE_API_URL } from "@/config/api"; | |||||
| import { TypeInputs, UomInputs, WeightUnitInputs } from "../material/actions"; | |||||
| export type ByProductResult = { | |||||
| id: string | number | |||||
| code: string; | |||||
| name: string; | |||||
| description: string | undefined; | |||||
| remarks: string | undefined; | |||||
| shelfLife: Number | undefined; | |||||
| countryOfOrigin: string | undefined; | |||||
| minHumid: number | undefined; | |||||
| maxHumid: number | undefined; | |||||
| minTemp: number | undefined; | |||||
| maxTemp: number | undefined; | |||||
| sampleRate: number | undefined; | |||||
| passingRate: number | undefined; | |||||
| netWeight: number | undefined; | |||||
| uom: UomInputs[]; | |||||
| weightUnit: WeightUnitInputs[]; | |||||
| type: TypeInputs[]; | |||||
| action?: any; | |||||
| } | |||||
| export const fetchAllByProduct = cache(async () => { | |||||
| return serverFetchJson<ByProductResult[]>(`${BASE_API_URL}/byProduct`, { | |||||
| next: { tags: ["byProduct"] }, | |||||
| }); | |||||
| }); | |||||
| export const fetchByProduct = cache(async (id: number) => { | |||||
| return serverFetchJson<ByProductResult>(`${BASE_API_URL}/byProduct/details/${id}`, { | |||||
| next: { tags: ["byProduct"] }, | |||||
| }); | |||||
| }); | |||||
| @@ -6,7 +6,8 @@ import { HTMLInputTypeAttribute } from "react"; | |||||
| import { CreateItemResponse } from "../../utils"; | import { CreateItemResponse } from "../../utils"; | ||||
| export type TypeInputs = { | export type TypeInputs = { | ||||
| type: string | |||||
| id: number; | |||||
| name: string | |||||
| } | } | ||||
| export type UomInputs = { | export type UomInputs = { | ||||
| uom: string | uom: string | ||||
| @@ -15,13 +16,10 @@ export type WeightUnitInputs = { | |||||
| weightUnit: string | weightUnit: string | ||||
| conversion: number | conversion: number | ||||
| } | } | ||||
| export type CreateMaterialInputs = { | |||||
| export type CreateItemInputs = { | |||||
| id?: string | number | id?: string | number | ||||
| code: string; | code: string; | ||||
| name: string; | name: string; | ||||
| isConsumables: boolean; | |||||
| // same goes for other props | |||||
| // change backend for null or not null | |||||
| description?: string | undefined; | description?: string | undefined; | ||||
| remarks?: string | undefined; | remarks?: string | undefined; | ||||
| shelfLife?: Number | undefined; | shelfLife?: Number | undefined; | ||||
| @@ -32,19 +30,17 @@ export type CreateMaterialInputs = { | |||||
| maxTemp?: number | undefined; | maxTemp?: number | undefined; | ||||
| sampleRate?: number | undefined; | sampleRate?: number | undefined; | ||||
| passingRate?: number | undefined; | passingRate?: number | undefined; | ||||
| netWeight?: number | undefined; | |||||
| type?: TypeInputs[]; | |||||
| uom?: UomInputs[]; | |||||
| weightUnit?: WeightUnitInputs[]; | |||||
| netWeight: number; | |||||
| typeId: number; | |||||
| } | } | ||||
| export const saveMaterial = async (data: CreateMaterialInputs) => { | |||||
| export const saveItem = async (data: CreateItemInputs) => { | |||||
| // try { | // try { | ||||
| const material = await serverFetchJson<CreateItemResponse<CreateMaterialInputs>>(`${BASE_API_URL}/material/new`, { | |||||
| const item = await serverFetchJson<CreateItemResponse<CreateItemInputs>>(`${BASE_API_URL}/items/new`, { | |||||
| method: "POST", | method: "POST", | ||||
| body: JSON.stringify(data), | body: JSON.stringify(data), | ||||
| headers: { "Content-Type": "application/json" }, | headers: { "Content-Type": "application/json" }, | ||||
| }); | }); | ||||
| revalidateTag("material"); | |||||
| return material | |||||
| revalidateTag("items"); | |||||
| return item | |||||
| }; | }; | ||||
| @@ -4,11 +4,10 @@ import { serverFetchJson } from "@/app/utils/fetchUtil"; | |||||
| import { BASE_API_URL } from "@/config/api"; | import { BASE_API_URL } from "@/config/api"; | ||||
| import { TypeInputs, UomInputs, WeightUnitInputs } from "./actions"; | import { TypeInputs, UomInputs, WeightUnitInputs } from "./actions"; | ||||
| export type MaterialResult = { | |||||
| export type ItemsResult = { | |||||
| id: string | number | id: string | number | ||||
| code: string; | code: string; | ||||
| name: string; | name: string; | ||||
| isConsumables: boolean; | |||||
| description: string | undefined; | description: string | undefined; | ||||
| remarks: string | undefined; | remarks: string | undefined; | ||||
| shelfLife: Number | undefined; | shelfLife: Number | undefined; | ||||
| @@ -20,22 +19,22 @@ export type MaterialResult = { | |||||
| sampleRate: number | undefined; | sampleRate: number | undefined; | ||||
| passingRate: number | undefined; | passingRate: number | undefined; | ||||
| netWeight: number | undefined; | netWeight: number | undefined; | ||||
| uom: UomInputs[]; | |||||
| weightUnit: WeightUnitInputs[]; | |||||
| type: TypeInputs[]; | |||||
| // uom: UomInputs[]; | |||||
| // weightUnit: WeightUnitInputs[]; | |||||
| type: TypeInputs; | |||||
| action?: any | action?: any | ||||
| } | } | ||||
| export const fetchAllMaterials = cache(async () => { | |||||
| return serverFetchJson<MaterialResult[]>(`${BASE_API_URL}/material`, { | |||||
| next: { tags: ["material"] }, | |||||
| export const fetchAllItems = cache(async () => { | |||||
| return serverFetchJson<ItemsResult[]>(`${BASE_API_URL}/items`, { | |||||
| next: { tags: ["items"] }, | |||||
| }); | }); | ||||
| }); | }); | ||||
| export const fetchMaterial = cache(async (id: number) => { | |||||
| return serverFetchJson<MaterialResult>(`${BASE_API_URL}/material/details/${id}`, { | |||||
| next: { tags: ["material"] }, | |||||
| export const fetchItem = cache(async (id: number) => { | |||||
| return serverFetchJson<ItemsResult>(`${BASE_API_URL}/items/details/${id}`, { | |||||
| next: { tags: ["items"] }, | |||||
| }); | }); | ||||
| }); | }); | ||||
| @@ -1,37 +0,0 @@ | |||||
| "use server"; | |||||
| import { ServerFetchError, serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil"; | |||||
| import { revalidateTag } from "next/cache"; | |||||
| import { BASE_API_URL } from "@/config/api"; | |||||
| import { TypeInputs, UomInputs, WeightUnitInputs } from "../material/actions"; | |||||
| import { CreateItemResponse } from "../../utils"; | |||||
| export type CreateProductInputs = { | |||||
| id?: string | number | |||||
| code: string; | |||||
| name: string; | |||||
| description?: string | undefined; | |||||
| remarks?: string | undefined; | |||||
| shelfLife?: number | undefined; | |||||
| countryOfOrigin?: string | undefined; | |||||
| minHumid?: number | undefined; | |||||
| maxHumid?: number | undefined; | |||||
| minTemp?: number | undefined; | |||||
| maxTemp?: number | undefined; | |||||
| sampleRate?: number | undefined; | |||||
| passingRate?: number | undefined; | |||||
| netWeight?: number | undefined; | |||||
| type?: TypeInputs[]; | |||||
| uom?: UomInputs[]; | |||||
| weightUnit?: WeightUnitInputs[]; | |||||
| } | |||||
| export const saveProduct = async (data: CreateProductInputs) => { | |||||
| // try { | |||||
| const product = await serverFetchJson<CreateItemResponse<CreateProductInputs>>(`${BASE_API_URL}/product/new`, { | |||||
| method: "POST", | |||||
| body: JSON.stringify(data), | |||||
| headers: { "Content-Type": "application/json" }, | |||||
| }); | |||||
| revalidateTag("product"); | |||||
| return product | |||||
| }; | |||||
| @@ -1,40 +0,0 @@ | |||||
| import { cache } from "react"; | |||||
| import "server-only"; | |||||
| import { serverFetchJson } from "@/app/utils/fetchUtil"; | |||||
| import { BASE_API_URL } from "@/config/api"; | |||||
| import { TypeInputs, UomInputs, WeightUnitInputs } from "../material/actions"; | |||||
| export type ProductResult = { | |||||
| id: string | number | |||||
| code: string; | |||||
| name: string; | |||||
| description: string | undefined; | |||||
| remarks: string | undefined; | |||||
| shelfLife: Number | undefined; | |||||
| countryOfOrigin: string | undefined; | |||||
| minHumid: number | undefined; | |||||
| maxHumid: number | undefined; | |||||
| minTemp: number | undefined; | |||||
| maxTemp: number | undefined; | |||||
| sampleRate: number | undefined; | |||||
| passingRate: number | undefined; | |||||
| netWeight: number | undefined; | |||||
| uom: UomInputs[]; | |||||
| weightUnit: WeightUnitInputs[]; | |||||
| type: TypeInputs[]; | |||||
| action?: any; | |||||
| } | |||||
| export const fetchAllProduct = cache(async () => { | |||||
| return serverFetchJson<ProductResult[]>(`${BASE_API_URL}/product`, { | |||||
| next: { tags: ["product"] }, | |||||
| }); | |||||
| }); | |||||
| export const fetchProduct = cache(async (id: number) => { | |||||
| return serverFetchJson<ProductResult>(`${BASE_API_URL}/product/details/${id}`, { | |||||
| next: { tags: ["product"] }, | |||||
| }); | |||||
| }); | |||||
| @@ -1,5 +1,10 @@ | |||||
| export enum TypeEnum { | export enum TypeEnum { | ||||
| PRODUCT = "product", | |||||
| MATERIAL = "material", | MATERIAL = "material", | ||||
| MATERIAL_ID = 1, | |||||
| PRODUCT = "product", | |||||
| PRODUCT_ID = 2, | |||||
| BYPRODUCT = "byProduct", | BYPRODUCT = "byProduct", | ||||
| } | |||||
| BYPRODUCT_ID = 3, | |||||
| CONSUMABLE = "consumables", | |||||
| CONSUMABLE_ID = 4, | |||||
| } | |||||
| @@ -1,5 +1,5 @@ | |||||
| "use client"; | "use client"; | ||||
| import { CreateMaterialInputs } from "@/app/api/settings/material/actions"; | |||||
| import { CreateItemInputs } from "@/app/api/settings/item/actions"; | |||||
| import { | import { | ||||
| Box, | Box, | ||||
| Card, | Card, | ||||
| @@ -12,27 +12,24 @@ import { | |||||
| import { useFormContext } from "react-hook-form"; | import { useFormContext } from "react-hook-form"; | ||||
| import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
| import InputDataGrid from "../InputDataGrid"; | import InputDataGrid from "../InputDataGrid"; | ||||
| import { useCallback, useMemo, useState } from "react"; | |||||
| import { useCallback, useEffect, useMemo, useState } from "react"; | |||||
| import { GridColDef, GridRowModel } from "@mui/x-data-grid"; | import { GridColDef, GridRowModel } from "@mui/x-data-grid"; | ||||
| import { InputDataGridProps, TableRow } from "../InputDataGrid/InputDataGrid"; | import { InputDataGridProps, TableRow } from "../InputDataGrid/InputDataGrid"; | ||||
| import { TypeEnum } from "@/app/utils/typeEnum"; | import { TypeEnum } from "@/app/utils/typeEnum"; | ||||
| import { CreateByProductInputs } from "@/app/api/settings/byProduct/actions"; | |||||
| import { NumberInputProps } from "./NumberInputProps"; | import { NumberInputProps } from "./NumberInputProps"; | ||||
| type Props = { | type Props = { | ||||
| // isEditMode: boolean; | |||||
| // type: TypeEnum; | |||||
| // isEditMode: boolean; | |||||
| // type: TypeEnum; | |||||
| }; | }; | ||||
| export type EntryError = | export type EntryError = | ||||
| | { | | { | ||||
| [field in keyof CreateByProductInputs]?: string; | |||||
| [field in keyof CreateItemInputs]?: string; | |||||
| } | } | ||||
| | undefined; | | undefined; | ||||
| const ByProductDetails: React.FC<Props> = ({ | |||||
| }) => { | |||||
| const ByProductDetails: React.FC<Props> = ({}) => { | |||||
| const { | const { | ||||
| t, | t, | ||||
| i18n: { language }, | i18n: { language }, | ||||
| @@ -49,7 +46,7 @@ const ByProductDetails: React.FC<Props> = ({ | |||||
| resetField, | resetField, | ||||
| setError, | setError, | ||||
| clearErrors, | clearErrors, | ||||
| } = useFormContext<CreateByProductInputs>(); | |||||
| } = useFormContext<CreateItemInputs>(); | |||||
| const typeColumns = useMemo<GridColDef[]>( | const typeColumns = useMemo<GridColDef[]>( | ||||
| () => [ | () => [ | ||||
| { | { | ||||
| @@ -93,7 +90,7 @@ const ByProductDetails: React.FC<Props> = ({ | |||||
| const validationTest = useCallback( | const validationTest = useCallback( | ||||
| ( | ( | ||||
| newRow: GridRowModel<TableRow<Partial<CreateByProductInputs>, EntryError>> | |||||
| newRow: GridRowModel<TableRow<Partial<CreateItemInputs>, EntryError>> | |||||
| ): EntryError => { | ): EntryError => { | ||||
| const error: EntryError = {}; | const error: EntryError = {}; | ||||
| console.log(newRow); | console.log(newRow); | ||||
| @@ -102,6 +99,22 @@ const ByProductDetails: React.FC<Props> = ({ | |||||
| [] | [] | ||||
| ); | ); | ||||
| const validateUom = useCallback( | |||||
| ( | |||||
| newRow: GridRowModel<TableRow<Partial<CreateItemInputs>, EntryError>> | |||||
| ): EntryError => { | |||||
| const error: EntryError = {}; | |||||
| console.log(newRow); | |||||
| // if (!newRow.uom) { | |||||
| // error.uom = "Uom cannot be empty"; | |||||
| // } | |||||
| return Object.keys(error).length > 0 ? error : undefined; | |||||
| }, | |||||
| [] | |||||
| ); | |||||
| useEffect(() => { | |||||
| console.log(errors) | |||||
| }, [errors]) | |||||
| return ( | return ( | ||||
| <Card sx={{ display: "block" }}> | <Card sx={{ display: "block" }}> | ||||
| <CardContent component={Stack} spacing={4}> | <CardContent component={Stack} spacing={4}> | ||||
| @@ -272,27 +285,6 @@ const ByProductDetails: React.FC<Props> = ({ | |||||
| helperText={errors.netWeight?.message} | helperText={errors.netWeight?.message} | ||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={6}> | |||||
| <InputDataGrid<CreateByProductInputs, EntryError> | |||||
| _formKey={"type"} | |||||
| columns={typeColumns} | |||||
| validateRow={validationTest} | |||||
| /> | |||||
| </Grid> | |||||
| <Grid item xs={6}> | |||||
| <InputDataGrid<CreateByProductInputs, EntryError> | |||||
| _formKey={"uom"} | |||||
| columns={uomColumns} | |||||
| validateRow={validationTest} | |||||
| /> | |||||
| </Grid> | |||||
| <Grid item xs={12}> | |||||
| <InputDataGrid<CreateByProductInputs, EntryError> | |||||
| _formKey={"weightUnit"} | |||||
| columns={weightUnitColumns} | |||||
| validateRow={validationTest} | |||||
| /> | |||||
| </Grid> | |||||
| </Grid> | </Grid> | ||||
| </Box> | </Box> | ||||
| </CardContent> | </CardContent> | ||||
| @@ -4,9 +4,9 @@ import { useCallback, useEffect, useMemo, useState } from "react"; | |||||
| import { useRouter, useSearchParams } from "next/navigation"; | import { useRouter, useSearchParams } from "next/navigation"; | ||||
| import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
| import { | import { | ||||
| CreateMaterialInputs, | |||||
| saveMaterial, | |||||
| } from "@/app/api/settings/material/actions"; | |||||
| CreateItemInputs, | |||||
| saveItem, | |||||
| } from "@/app/api/settings/item/actions"; | |||||
| import { | import { | ||||
| FormProvider, | FormProvider, | ||||
| SubmitErrorHandler, | SubmitErrorHandler, | ||||
| @@ -17,67 +17,69 @@ import { deleteDialog } from "../Swal/CustomAlerts"; | |||||
| import { Box, Button, Grid, Stack, Typography } from "@mui/material"; | import { Box, Button, Grid, Stack, Typography } from "@mui/material"; | ||||
| import { Check, Close, EditNote } from "@mui/icons-material"; | import { Check, Close, EditNote } from "@mui/icons-material"; | ||||
| import { TypeEnum } from "@/app/utils/typeEnum"; | import { TypeEnum } from "@/app/utils/typeEnum"; | ||||
| import { | |||||
| CreateProductInputs, | |||||
| saveProduct, | |||||
| } from "@/app/api/settings/product/actions"; | |||||
| import { CreateInputsFields } from "./CreateProductMaterialWrapper"; | |||||
| import MaterialDetails from "./MaterialDetails"; | import MaterialDetails from "./MaterialDetails"; | ||||
| import ProductDetails from "./ProductDetails"; | import ProductDetails from "./ProductDetails"; | ||||
| import { CreateItemResponse } from "@/app/api/utils"; | import { CreateItemResponse } from "@/app/api/utils"; | ||||
| import { CreateByProductInputs, saveByProduct } from "@/app/api/settings/byProduct/actions"; | |||||
| import ByProductDetails from "./ByProductDetails"; | import ByProductDetails from "./ByProductDetails"; | ||||
| type Props = { | type Props = { | ||||
| isEditMode: boolean; | isEditMode: boolean; | ||||
| type: TypeEnum; | type: TypeEnum; | ||||
| defaultValues: Partial<CreateInputsFields> | undefined; | |||||
| defaultValues: Partial<CreateItemInputs> | undefined; | |||||
| }; | }; | ||||
| const CreateProductMaterial: React.FC<Props> = ({ | |||||
| const CreateItem: React.FC<Props> = ({ | |||||
| isEditMode, | isEditMode, | ||||
| type, | type, | ||||
| defaultValues, | defaultValues, | ||||
| }) => { | }) => { | ||||
| console.log(type) | |||||
| const [serverError, setServerError] = useState(""); | const [serverError, setServerError] = useState(""); | ||||
| const [tabIndex, setTabIndex] = useState(0); | const [tabIndex, setTabIndex] = useState(0); | ||||
| const { t } = useTranslation(); | const { t } = useTranslation(); | ||||
| const router = useRouter(); | const router = useRouter(); | ||||
| const [title, mode, redirPath] = useMemo(() => { | |||||
| const [typeId, title, mode, redirPath] = useMemo(() => { | |||||
| var typeId = TypeEnum.CONSUMABLE_ID | |||||
| var title = ""; | var title = ""; | ||||
| var mode = ""; | var mode = ""; | ||||
| var redirPath = ""; | var redirPath = ""; | ||||
| if (type === TypeEnum.MATERIAL) { | if (type === TypeEnum.MATERIAL) { | ||||
| typeId = TypeEnum.MATERIAL_ID | |||||
| title = "Material"; | title = "Material"; | ||||
| redirPath = "/material"; | |||||
| redirPath = "/settings/material"; | |||||
| } | } | ||||
| if (type === TypeEnum.PRODUCT) { | if (type === TypeEnum.PRODUCT) { | ||||
| typeId = TypeEnum.PRODUCT_ID | |||||
| title = "Product"; | title = "Product"; | ||||
| redirPath = "/product"; | |||||
| redirPath = "/settings/product"; | |||||
| } | } | ||||
| if (type === TypeEnum.BYPRODUCT) { | if (type === TypeEnum.BYPRODUCT) { | ||||
| typeId = TypeEnum.BYPRODUCT_ID | |||||
| title = "By-Product"; | title = "By-Product"; | ||||
| redirPath = "/byProduct"; | |||||
| redirPath = "/settings/byProduct"; | |||||
| } | } | ||||
| if (isEditMode) { | if (isEditMode) { | ||||
| mode = "Edit"; | mode = "Edit"; | ||||
| } else { | } else { | ||||
| mode = "Create"; | mode = "Create"; | ||||
| } | } | ||||
| return [title, mode, redirPath]; | |||||
| return [typeId, title, mode, redirPath]; | |||||
| }, [type, isEditMode]); | }, [type, isEditMode]); | ||||
| const formProps = useForm<CreateInputsFields>({ | |||||
| defaultValues: defaultValues ? defaultValues : {}, | |||||
| console.log(typeId) | |||||
| const formProps = useForm<CreateItemInputs>({ | |||||
| defaultValues: defaultValues ? defaultValues : { | |||||
| typeId: typeId | |||||
| }, | |||||
| }); | }); | ||||
| const errors = formProps.formState.errors; | const errors = formProps.formState.errors; | ||||
| const handleCancel = () => { | const handleCancel = () => { | ||||
| router.replace(`/settings/${type}`); | router.replace(`/settings/${type}`); | ||||
| }; | }; | ||||
| const onSubmit = useCallback<SubmitHandler<CreateInputsFields>>( | |||||
| const onSubmit = useCallback<SubmitHandler<CreateItemInputs>>( | |||||
| async (data, event) => { | async (data, event) => { | ||||
| let hasErrors = false; | let hasErrors = false; | ||||
| console.log("dasasdasd") | |||||
| try { | try { | ||||
| // checking humid input | // checking humid input | ||||
| if (data.maxHumid && data.minHumid!! > data.maxHumid!!) { | if (data.maxHumid && data.minHumid!! > data.maxHumid!!) { | ||||
| @@ -135,31 +137,19 @@ const CreateProductMaterial: React.FC<Props> = ({ | |||||
| } | } | ||||
| console.log("data posted"); | console.log("data posted"); | ||||
| console.log(data); | console.log(data); | ||||
| // do api | |||||
| var response; | |||||
| if (type === TypeEnum.MATERIAL) { | |||||
| response = await saveMaterial(data as CreateMaterialInputs); | |||||
| } else if (type === TypeEnum.PRODUCT) { | |||||
| response = await saveProduct(data as CreateProductInputs); | |||||
| } else if (type === TypeEnum.BYPRODUCT) { | |||||
| // response = await saveByProduct(data as CreateByProductInputs); | |||||
| } else { | |||||
| // Handle unexpected type | |||||
| throw new Error("Invalid type provided"); | |||||
| } | |||||
| // return | |||||
| // do api | |||||
| var response = await saveItem(data); | |||||
| if (response) { | if (response) { | ||||
| if (!Boolean(response.id)) { | if (!Boolean(response.id)) { | ||||
| formProps.setError(response.errorPosition!! as keyof CreateInputsFields, { | |||||
| formProps.setError(response.errorPosition!! as keyof CreateItemInputs, { | |||||
| message: response.message!!, | message: response.message!!, | ||||
| type: "required", | type: "required", | ||||
| }); | }); | ||||
| throw response; | |||||
| } else if (Boolean(response.id)) { | } else if (Boolean(response.id)) { | ||||
| router.replace(redirPath); | router.replace(redirPath); | ||||
| } | } | ||||
| } else { | |||||
| throw "no response"; | |||||
| } | } | ||||
| } catch (e) { | } catch (e) { | ||||
| // backend error | // backend error | ||||
| @@ -171,7 +161,7 @@ const CreateProductMaterial: React.FC<Props> = ({ | |||||
| ); | ); | ||||
| // multiple tabs | // multiple tabs | ||||
| const onSubmitError = useCallback<SubmitErrorHandler<CreateInputsFields>>( | |||||
| const onSubmitError = useCallback<SubmitErrorHandler<CreateItemInputs>>( | |||||
| (errors) => {}, | (errors) => {}, | ||||
| [] | [] | ||||
| ); | ); | ||||
| @@ -220,4 +210,4 @@ const CreateProductMaterial: React.FC<Props> = ({ | |||||
| </> | </> | ||||
| ); | ); | ||||
| }; | }; | ||||
| export default CreateProductMaterial; | |||||
| export default CreateItem; | |||||
| @@ -5,7 +5,7 @@ import Stack from "@mui/material/Stack"; | |||||
| import React from "react"; | import React from "react"; | ||||
| // Can make this nicer | // Can make this nicer | ||||
| export const CreateProductMaterialLoading: React.FC = () => { | |||||
| export const CreateItemLoading: React.FC = () => { | |||||
| return ( | return ( | ||||
| <> | <> | ||||
| <Card> | <Card> | ||||
| @@ -37,4 +37,4 @@ export const CreateProductMaterialLoading: React.FC = () => { | |||||
| ); | ); | ||||
| }; | }; | ||||
| export default CreateProductMaterialLoading; | |||||
| export default CreateItemLoading; | |||||
| @@ -0,0 +1,53 @@ | |||||
| import { TypeEnum } from "@/app/utils/typeEnum"; | |||||
| import CreateItem from "./CreateItem"; | |||||
| import CreateItemLoading from "./CreateItemLoading"; | |||||
| import { CreateItemInputs } from "@/app/api/settings/item/actions"; | |||||
| import { notFound } from "next/navigation"; | |||||
| import { fetchItem } from "@/app/api/settings/item"; | |||||
| interface SubComponents { | |||||
| Loading: typeof CreateItemLoading; | |||||
| } | |||||
| type Props = { | |||||
| id?: number | |||||
| type: TypeEnum; | |||||
| }; | |||||
| const CreateItemWrapper: React.FC<Props> & | |||||
| SubComponents = async ({ type, id }) => { | |||||
| var result | |||||
| var defaultValues: Partial<CreateItemInputs> | undefined | |||||
| console.log(type) | |||||
| if (id) { | |||||
| result = await fetchItem(id); | |||||
| console.log(result) | |||||
| defaultValues = { | |||||
| typeId: result?.type.id, | |||||
| id: result?.id, | |||||
| code: result?.code, | |||||
| name: result?.name, | |||||
| description: result?.description, | |||||
| remarks: result?.remarks, | |||||
| shelfLife: result?.shelfLife, | |||||
| countryOfOrigin: result?.countryOfOrigin, | |||||
| minHumid: result?.minHumid, | |||||
| maxHumid: result?.maxHumid, | |||||
| minTemp: result?.minTemp, | |||||
| maxTemp: result?.maxTemp, | |||||
| sampleRate: result?.sampleRate, | |||||
| passingRate: result?.passingRate, | |||||
| netWeight: result?.netWeight | |||||
| }; | |||||
| } | |||||
| return ( | |||||
| <CreateItem | |||||
| isEditMode={Boolean(id)} | |||||
| type={type} | |||||
| defaultValues={defaultValues} | |||||
| /> | |||||
| ); | |||||
| }; | |||||
| CreateItemWrapper.Loading = CreateItemLoading; | |||||
| export default CreateItemWrapper; | |||||
| @@ -1,5 +1,5 @@ | |||||
| "use client"; | "use client"; | ||||
| import { CreateMaterialInputs } from "@/app/api/settings/material/actions"; | |||||
| import { CreateItemInputs } from "@/app/api/settings/item/actions"; | |||||
| import { | import { | ||||
| Box, | Box, | ||||
| Card, | Card, | ||||
| @@ -31,7 +31,7 @@ type Props = { | |||||
| export type EntryError = | export type EntryError = | ||||
| | { | | { | ||||
| [field in keyof CreateMaterialInputs]?: string; | |||||
| [field in keyof CreateItemInputs]?: string; | |||||
| } | } | ||||
| | undefined; | | undefined; | ||||
| @@ -52,8 +52,9 @@ const MaterialDetails: React.FC<Props> = ({}) => { | |||||
| resetField, | resetField, | ||||
| setError, | setError, | ||||
| clearErrors, | clearErrors, | ||||
| } = useFormContext<CreateMaterialInputs>(); | |||||
| } = useFormContext<CreateItemInputs>(); | |||||
| // textfield error msg locale problem | // textfield error msg locale problem | ||||
| console.log(defaultValues) | |||||
| const typeColumns = useMemo<GridColDef[]>( | const typeColumns = useMemo<GridColDef[]>( | ||||
| () => [ | () => [ | ||||
| { | { | ||||
| @@ -97,7 +98,7 @@ const MaterialDetails: React.FC<Props> = ({}) => { | |||||
| const validationTest = useCallback( | const validationTest = useCallback( | ||||
| ( | ( | ||||
| newRow: GridRowModel<TableRow<Partial<CreateMaterialInputs>, EntryError>> | |||||
| newRow: GridRowModel<TableRow<Partial<CreateItemInputs>, EntryError>> | |||||
| ): EntryError => { | ): EntryError => { | ||||
| const error: EntryError = {}; | const error: EntryError = {}; | ||||
| console.log(newRow); | console.log(newRow); | ||||
| @@ -117,15 +118,20 @@ const MaterialDetails: React.FC<Props> = ({}) => { | |||||
| <FormControlLabel | <FormControlLabel | ||||
| control={ | control={ | ||||
| <Controller | <Controller | ||||
| name={"isConsumables"} | |||||
| name={"typeId"} | |||||
| control={control} | control={control} | ||||
| render={({ field: props }) => ( | |||||
| render={({ field: props }) => { | |||||
| console.log(props) | |||||
| return ( | |||||
| <Checkbox | <Checkbox | ||||
| {...props} | {...props} | ||||
| checked={props.value} | |||||
| onChange={(e) => props.onChange(e.target.checked)} | |||||
| checked={props.value === TypeEnum.CONSUMABLE_ID} | |||||
| onChange={(e) => { | |||||
| const newValue = e.target.checked ? TypeEnum.CONSUMABLE_ID : TypeEnum.MATERIAL_ID; | |||||
| props.onChange(newValue); | |||||
| }} | |||||
| /> | /> | ||||
| )} | |||||
| )}} | |||||
| /> | /> | ||||
| } | } | ||||
| label={ | label={ | ||||
| @@ -310,27 +316,6 @@ const MaterialDetails: React.FC<Props> = ({}) => { | |||||
| helperText={errors.netWeight?.message} | helperText={errors.netWeight?.message} | ||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={6}> | |||||
| <InputDataGrid<CreateMaterialInputs, EntryError> | |||||
| _formKey={"type"} | |||||
| columns={typeColumns} | |||||
| validateRow={validationTest} | |||||
| /> | |||||
| </Grid> | |||||
| <Grid item xs={6}> | |||||
| <InputDataGrid<CreateMaterialInputs, EntryError> | |||||
| _formKey={"uom"} | |||||
| columns={uomColumns} | |||||
| validateRow={validationTest} | |||||
| /> | |||||
| </Grid> | |||||
| <Grid item xs={12}> | |||||
| <InputDataGrid<CreateMaterialInputs, EntryError> | |||||
| _formKey={"weightUnit"} | |||||
| columns={weightUnitColumns} | |||||
| validateRow={validationTest} | |||||
| /> | |||||
| </Grid> | |||||
| </Grid> | </Grid> | ||||
| </Box> | </Box> | ||||
| </CardContent> | </CardContent> | ||||
| @@ -1,5 +1,4 @@ | |||||
| "use client"; | "use client"; | ||||
| import { CreateMaterialInputs } from "@/app/api/settings/material/actions"; | |||||
| import { | import { | ||||
| Box, | Box, | ||||
| Card, | Card, | ||||
| @@ -16,8 +15,8 @@ import { useCallback, useMemo, useState } from "react"; | |||||
| import { GridColDef, GridRowModel } from "@mui/x-data-grid"; | import { GridColDef, GridRowModel } from "@mui/x-data-grid"; | ||||
| import { InputDataGridProps, TableRow } from "../InputDataGrid/InputDataGrid"; | import { InputDataGridProps, TableRow } from "../InputDataGrid/InputDataGrid"; | ||||
| import { TypeEnum } from "@/app/utils/typeEnum"; | import { TypeEnum } from "@/app/utils/typeEnum"; | ||||
| import { CreateProductInputs } from "@/app/api/settings/product/actions"; | |||||
| import { NumberInputProps } from "./NumberInputProps"; | import { NumberInputProps } from "./NumberInputProps"; | ||||
| import { CreateItemInputs } from "@/app/api/settings/item/actions"; | |||||
| type Props = { | type Props = { | ||||
| // isEditMode: boolean; | // isEditMode: boolean; | ||||
| @@ -26,7 +25,7 @@ type Props = { | |||||
| export type EntryError = | export type EntryError = | ||||
| | { | | { | ||||
| [field in keyof CreateProductInputs]?: string; | |||||
| [field in keyof CreateItemInputs]?: string; | |||||
| } | } | ||||
| | undefined; | | undefined; | ||||
| @@ -49,7 +48,7 @@ const ProductDetails: React.FC<Props> = ({ | |||||
| resetField, | resetField, | ||||
| setError, | setError, | ||||
| clearErrors, | clearErrors, | ||||
| } = useFormContext<CreateProductInputs>(); | |||||
| } = useFormContext<CreateItemInputs>(); | |||||
| const typeColumns = useMemo<GridColDef[]>( | const typeColumns = useMemo<GridColDef[]>( | ||||
| () => [ | () => [ | ||||
| { | { | ||||
| @@ -93,7 +92,7 @@ const ProductDetails: React.FC<Props> = ({ | |||||
| const validationTest = useCallback( | const validationTest = useCallback( | ||||
| ( | ( | ||||
| newRow: GridRowModel<TableRow<Partial<CreateProductInputs>, EntryError>> | |||||
| newRow: GridRowModel<TableRow<Partial<CreateItemInputs>, EntryError>> | |||||
| ): EntryError => { | ): EntryError => { | ||||
| const error: EntryError = {}; | const error: EntryError = {}; | ||||
| console.log(newRow); | console.log(newRow); | ||||
| @@ -276,28 +275,28 @@ const ProductDetails: React.FC<Props> = ({ | |||||
| helperText={errors.netWeight?.message} | helperText={errors.netWeight?.message} | ||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={6}> | |||||
| <InputDataGrid<CreateProductInputs, EntryError> | |||||
| {/* <Grid item xs={6}> | |||||
| <InputDataGrid<CreateItemInputs, EntryError> | |||||
| _formKey={"type"} | _formKey={"type"} | ||||
| columns={typeColumns} | columns={typeColumns} | ||||
| validateRow={validationTest} | validateRow={validationTest} | ||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={6}> | <Grid item xs={6}> | ||||
| <InputDataGrid<CreateProductInputs, EntryError> | |||||
| <InputDataGrid<CreateItemInputs, EntryError> | |||||
| _formKey={"uom"} | _formKey={"uom"} | ||||
| columns={uomColumns} | columns={uomColumns} | ||||
| validateRow={validationTest} | validateRow={validationTest} | ||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12}> | <Grid item xs={12}> | ||||
| <InputDataGrid<CreateProductInputs, EntryError> | |||||
| <InputDataGrid<CreateItemInputs, EntryError> | |||||
| _formKey={"weightUnit"} | _formKey={"weightUnit"} | ||||
| columns={weightUnitColumns} | columns={weightUnitColumns} | ||||
| validateRow={validationTest} | validateRow={validationTest} | ||||
| /> | /> | ||||
| </Grid> | |||||
| </Grid> | |||||
| </Grid>*/} | |||||
| </Grid> | |||||
| </Box> | </Box> | ||||
| </CardContent> | </CardContent> | ||||
| </Card> | </Card> | ||||
| @@ -0,0 +1 @@ | |||||
| export { default } from "./CreateItemWrapper"; | |||||
| @@ -1,67 +0,0 @@ | |||||
| import { TypeEnum } from "@/app/utils/typeEnum"; | |||||
| import CreateProductMaterial from "./CreateProductMaterial"; | |||||
| import CreateMaterialLoading from "./CreateProductMaterialLoading"; | |||||
| import { CreateMaterialInputs } from "@/app/api/settings/material/actions"; | |||||
| import { CreateProductInputs } from "@/app/api/settings/product/actions"; | |||||
| import { fetchMaterial } from "@/app/api/settings/material"; | |||||
| import { fetchProduct } from "@/app/api/settings/product"; | |||||
| import { fetchByProduct } from "@/app/api/settings/byProduct"; | |||||
| import { notFound } from "next/navigation"; | |||||
| import { CreateByProductInputs } from "@/app/api/settings/byProduct/actions"; | |||||
| interface SubComponents { | |||||
| Loading: typeof CreateMaterialLoading; | |||||
| } | |||||
| type Props = { | |||||
| id?: number | |||||
| type: TypeEnum; | |||||
| }; | |||||
| export type CreateInputsFields = CreateMaterialInputs | CreateProductInputs | CreateByProductInputs; | |||||
| const CreateProductMaterialWrapper: React.FC<Props> & | |||||
| SubComponents = async ({ type, id }) => { | |||||
| var defaultValues: Partial<CreateInputsFields> = {}; | |||||
| var result | |||||
| if (id && type === TypeEnum.MATERIAL) { | |||||
| result = await fetchMaterial(id); | |||||
| defaultValues = { | |||||
| isConsumables: result.isConsumables | |||||
| } | |||||
| } else if (id && type === TypeEnum.PRODUCT) { | |||||
| result = await fetchProduct(id); | |||||
| } else if (id && type === TypeEnum.BYPRODUCT) { | |||||
| result = await fetchByProduct(id); | |||||
| } | |||||
| defaultValues = { | |||||
| ...defaultValues, | |||||
| id: result?.id, | |||||
| code: result?.code, | |||||
| name: result?.name, | |||||
| description: result?.description, | |||||
| type: result?.type, | |||||
| remarks: result?.remarks, | |||||
| shelfLife: result?.shelfLife, | |||||
| countryOfOrigin: result?.countryOfOrigin, | |||||
| minHumid: result?.minHumid, | |||||
| maxHumid: result?.maxHumid, | |||||
| minTemp: result?.minTemp, | |||||
| maxTemp: result?.maxTemp, | |||||
| sampleRate: result?.sampleRate, | |||||
| passingRate: result?.passingRate, | |||||
| netWeight: result?.netWeight, | |||||
| uom: result?.uom, | |||||
| weightUnit: result?.weightUnit, | |||||
| }; | |||||
| return ( | |||||
| <CreateProductMaterial | |||||
| isEditMode={Boolean(id)} | |||||
| type={type} | |||||
| defaultValues={defaultValues} | |||||
| /> | |||||
| ); | |||||
| }; | |||||
| CreateProductMaterialWrapper.Loading = CreateMaterialLoading; | |||||
| export default CreateProductMaterialWrapper; | |||||
| @@ -1 +0,0 @@ | |||||
| export { default } from "./CreateProductMaterialWrapper"; | |||||
| @@ -151,7 +151,7 @@ function InputDataGrid<T, E>({ | |||||
| const reset = useCallback(() => { | const reset = useCallback(() => { | ||||
| setRowModesModel({}) | setRowModesModel({}) | ||||
| setRows([]) | |||||
| setRows(originalRows) | |||||
| }, []); | }, []); | ||||
| const handleCancel = useCallback( | const handleCancel = useCallback( | ||||
| @@ -239,7 +239,7 @@ function InputDataGrid<T, E>({ | |||||
| <Button | <Button | ||||
| disableRipple | disableRipple | ||||
| variant="outlined" | variant="outlined" | ||||
| startIcon={<Add />} | |||||
| startIcon={<Add />} | |||||
| onClick={addRow} | onClick={addRow} | ||||
| size="small" | size="small" | ||||
| > | > | ||||
| @@ -2,26 +2,24 @@ | |||||
| import { useCallback, useMemo, useState } from "react"; | import { useCallback, useMemo, useState } from "react"; | ||||
| import SearchBox, { Criterion } from "../SearchBox"; | import SearchBox, { Criterion } from "../SearchBox"; | ||||
| import { MaterialResult } from "@/app/api/settings/material"; | |||||
| import { ItemsResult } from "@/app/api/settings/item"; | |||||
| import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
| import SearchResults, { Column } from "../SearchResults"; | import SearchResults, { Column } from "../SearchResults"; | ||||
| import { EditNote } from "@mui/icons-material"; | import { EditNote } from "@mui/icons-material"; | ||||
| import { useRouter, useSearchParams } from "next/navigation"; | import { useRouter, useSearchParams } from "next/navigation"; | ||||
| import { GridDeleteIcon } from "@mui/x-data-grid"; | import { GridDeleteIcon } from "@mui/x-data-grid"; | ||||
| import { TypeEnum } from "@/app/utils/typeEnum"; | import { TypeEnum } from "@/app/utils/typeEnum"; | ||||
| import { ProductResult } from "@/app/api/settings/product"; | |||||
| export type ListResult = MaterialResult | ProductResult; | |||||
| type Props = { | type Props = { | ||||
| productMaterial: ListResult[]; | |||||
| items: ItemsResult[]; | |||||
| type: TypeEnum; | type: TypeEnum; | ||||
| }; | }; | ||||
| type SearchQuery = Partial<Omit<ListResult, "id">>; | |||||
| type SearchQuery = Partial<Omit<ItemsResult, "id">>; | |||||
| type SearchParamNames = keyof SearchQuery; | type SearchParamNames = keyof SearchQuery; | ||||
| const MaterialSearch: React.FC<Props> = ({ productMaterial, type }) => { | |||||
| const [filteredItems, setFilteredItems] = useState<ListResult[]>(productMaterial); | |||||
| const { t } = useTranslation(type); | |||||
| const ItemsSearch: React.FC<Props> = ({ items, type }) => { | |||||
| const [filteredItems, setFilteredItems] = useState<ItemsResult[]>(items); | |||||
| const { t } = useTranslation(type.toString()); | |||||
| const router = useRouter(); | const router = useRouter(); | ||||
| const searchCriteria: Criterion<SearchParamNames>[] = useMemo( | const searchCriteria: Criterion<SearchParamNames>[] = useMemo( | ||||
| @@ -38,22 +36,22 @@ const MaterialSearch: React.FC<Props> = ({ productMaterial, type }) => { | |||||
| } | } | ||||
| return searchCriteria | return searchCriteria | ||||
| }, | }, | ||||
| [t, productMaterial] | |||||
| [t, items] | |||||
| ); | ); | ||||
| const onDetailClick = useCallback( | const onDetailClick = useCallback( | ||||
| (productMaterial: ListResult) => { | |||||
| router.push(`/settings/${type}/edit?id=${productMaterial.id}`); | |||||
| (item: ItemsResult) => { | |||||
| router.push(`/settings/${type}/edit?id=${item.id}`); | |||||
| }, | }, | ||||
| [type, router] | [type, router] | ||||
| ); | ); | ||||
| const onDeleteClick = useCallback( | const onDeleteClick = useCallback( | ||||
| (productMaterial: ListResult) => {}, | |||||
| (item: ItemsResult) => {}, | |||||
| [router] | [router] | ||||
| ); | ); | ||||
| const columns = useMemo<Column<ListResult>[]>( | |||||
| const columns = useMemo<Column<ItemsResult>[]>( | |||||
| () => [ | () => [ | ||||
| { | { | ||||
| name: "id", | name: "id", | ||||
| @@ -80,8 +78,8 @@ const MaterialSearch: React.FC<Props> = ({ productMaterial, type }) => { | |||||
| ); | ); | ||||
| const onReset = useCallback(() => { | const onReset = useCallback(() => { | ||||
| setFilteredItems(productMaterial); | |||||
| }, [productMaterial]); | |||||
| setFilteredItems(items); | |||||
| }, [items]); | |||||
| return ( | return ( | ||||
| <> | <> | ||||
| @@ -89,7 +87,7 @@ const MaterialSearch: React.FC<Props> = ({ productMaterial, type }) => { | |||||
| criteria={searchCriteria} | criteria={searchCriteria} | ||||
| onSearch={(query) => { | onSearch={(query) => { | ||||
| setFilteredItems( | setFilteredItems( | ||||
| productMaterial.filter((pm) => { | |||||
| items.filter((pm) => { | |||||
| if (type === TypeEnum.MATERIAL) { | if (type === TypeEnum.MATERIAL) { | ||||
| return ( | return ( | ||||
| pm.code.toLowerCase().includes(query.code.toLowerCase()) && | pm.code.toLowerCase().includes(query.code.toLowerCase()) && | ||||
| @@ -111,9 +109,9 @@ const MaterialSearch: React.FC<Props> = ({ productMaterial, type }) => { | |||||
| }} | }} | ||||
| onReset={onReset} | onReset={onReset} | ||||
| /> | /> | ||||
| <SearchResults<ListResult> items={filteredItems} columns={columns} /> | |||||
| <SearchResults<ItemsResult> items={filteredItems} columns={columns} /> | |||||
| </> | </> | ||||
| ); | ); | ||||
| }; | }; | ||||
| export default MaterialSearch; | |||||
| export default ItemsSearch; | |||||
| @@ -5,7 +5,7 @@ import Stack from "@mui/material/Stack"; | |||||
| import React from "react"; | import React from "react"; | ||||
| // Can make this nicer | // Can make this nicer | ||||
| export const ProductMaterialSearchLoading: React.FC = () => { | |||||
| export const ItemsSearchLoading: React.FC = () => { | |||||
| return ( | return ( | ||||
| <> | <> | ||||
| <Card> | <Card> | ||||
| @@ -37,4 +37,4 @@ export const ProductMaterialSearchLoading: React.FC = () => { | |||||
| ); | ); | ||||
| }; | }; | ||||
| export default ProductMaterialSearchLoading; | |||||
| export default ItemsSearchLoading; | |||||
| @@ -0,0 +1,26 @@ | |||||
| import { fetchAllItems, } from "@/app/api/settings/item"; | |||||
| import ItemsSearch from "./ItemsSearch"; | |||||
| import ItemsSearchLoading from "./ItemsSearchLoading"; | |||||
| import { SearchParams } from "@/app/utils/fetchUtil"; | |||||
| import { TypeEnum } from "@/app/utils/typeEnum"; | |||||
| import { notFound } from "next/navigation"; | |||||
| interface SubComponents { | |||||
| Loading: typeof ItemsSearchLoading; | |||||
| } | |||||
| type Props = { | |||||
| type: TypeEnum; | |||||
| }; | |||||
| const ItemsSearchWrapper: React.FC<Props> & SubComponents = async ({ | |||||
| type, | |||||
| }) => { | |||||
| console.log(type) | |||||
| var result = await fetchAllItems() | |||||
| return <ItemsSearch items={result} type={type} />; | |||||
| }; | |||||
| ItemsSearchWrapper.Loading = ItemsSearchLoading; | |||||
| export default ItemsSearchWrapper; | |||||
| @@ -0,0 +1 @@ | |||||
| export { default } from "./ItemsSearchWrapper"; | |||||
| @@ -1,35 +0,0 @@ | |||||
| import { fetchAllMaterials, MaterialResult } from "@/app/api/settings/material"; | |||||
| import ProductMaterialSearch, { ListResult } from "./ProductMaterialSearch"; | |||||
| import MaterialSearchLoading from "./ProductMaterialSearchLoading"; | |||||
| import { SearchParams } from "@/app/utils/fetchUtil"; | |||||
| import { TypeEnum } from "@/app/utils/typeEnum"; | |||||
| import { notFound } from "next/navigation"; | |||||
| interface SubComponents { | |||||
| Loading: typeof MaterialSearchLoading; | |||||
| } | |||||
| type Props = { | |||||
| type: TypeEnum; | |||||
| }; | |||||
| const ProductMaterialSearchWrapper: React.FC<Props> & SubComponents = async ({ | |||||
| type, | |||||
| }) => { | |||||
| var result: ListResult[] = []; | |||||
| if (TypeEnum.PRODUCT === type) { | |||||
| result = []; | |||||
| } else if (TypeEnum.MATERIAL === type) { | |||||
| result = await fetchAllMaterials(); | |||||
| } else if (TypeEnum.BYPRODUCT === type) { | |||||
| result = []; | |||||
| } else { | |||||
| notFound(); | |||||
| } | |||||
| return <ProductMaterialSearch productMaterial={result} type={type} />; | |||||
| }; | |||||
| ProductMaterialSearchWrapper.Loading = MaterialSearchLoading; | |||||
| export default ProductMaterialSearchWrapper; | |||||
| @@ -1 +0,0 @@ | |||||
| export { default } from "./ProductMaterialSearchWrapper"; | |||||