@@ -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"; |