@@ -0,0 +1,24 @@ | |||
import { SearchParams } from "@/app/utils/fetchUtil"; | |||
import { TypeEnum } from "@/app/utils/typeEnum"; | |||
import CreateProductMaterial from "@/components/CreateProductMaterial"; | |||
import { I18nProvider, getServerI18n } from "@/i18n"; | |||
import { Typography } from "@mui/material"; | |||
import { isString } from "lodash"; | |||
type Props = {} & SearchParams; | |||
const byProductSetting: React.FC<Props> = async ({ searchParams }) => { | |||
const type = TypeEnum.BYPRODUCT; | |||
const { t } = await getServerI18n(type); | |||
console.log(searchParams); | |||
return ( | |||
<> | |||
{/* <Typography variant="h4">{t("Create Material")}</Typography> */} | |||
<I18nProvider namespaces={[type]}> | |||
<CreateProductMaterial type={type} /> | |||
</I18nProvider> | |||
</> | |||
); | |||
}; | |||
export default byProductSetting; |
@@ -0,0 +1,24 @@ | |||
import { SearchParams } from "@/app/utils/fetchUtil"; | |||
import { TypeEnum } from "@/app/utils/typeEnum"; | |||
import CreateProductMaterial from "@/components/CreateProductMaterial"; | |||
import { I18nProvider, getServerI18n } from "@/i18n"; | |||
import { Typography } from "@mui/material"; | |||
import { isString } from "lodash"; | |||
type Props = {} & SearchParams; | |||
const byProductSetting: React.FC<Props> = async ({ searchParams }) => { | |||
const type = TypeEnum.BYPRODUCT; | |||
const { t } = await getServerI18n(type); | |||
console.log(searchParams); | |||
return ( | |||
<> | |||
{/* <Typography variant="h4">{t("Create Material")}</Typography> */} | |||
<I18nProvider namespaces={[type]}> | |||
<CreateProductMaterial type={type} /> | |||
</I18nProvider> | |||
</> | |||
); | |||
}; | |||
export default byProductSetting; |
@@ -0,0 +1,48 @@ | |||
import { TypeEnum } from "@/app/utils/typeEnum"; | |||
import MaterialSearch from "@/components/ProductMaterialSearch"; | |||
import { getServerI18n } from "@/i18n"; | |||
import Add from "@mui/icons-material/Add"; | |||
import Button from "@mui/material/Button"; | |||
import Stack from "@mui/material/Stack"; | |||
import Typography from "@mui/material/Typography"; | |||
import { Metadata } from "next"; | |||
import Link from "next/link"; | |||
import { Suspense } from "react"; | |||
export const metadata: Metadata = { | |||
title: "ByProduct", | |||
}; | |||
const materialSetting: React.FC = async () => { | |||
const byProduct = TypeEnum.BYPRODUCT | |||
const { t } = await getServerI18n(byProduct); | |||
// preloadClaims(); | |||
return ( | |||
<> | |||
<Stack | |||
direction="row" | |||
justifyContent="space-between" | |||
flexWrap="wrap" | |||
rowGap={2} | |||
> | |||
<Typography variant="h4" marginInlineEnd={2}> | |||
{t("ByProduct")} | |||
</Typography> | |||
<Button | |||
variant="contained" | |||
startIcon={<Add />} | |||
LinkComponent={Link} | |||
href="byProduct/create" | |||
> | |||
{t("Create by-Product")} | |||
</Button> | |||
</Stack> | |||
<Suspense fallback={<MaterialSearch.Loading />}> | |||
<MaterialSearch type={byProduct} /> | |||
</Suspense> | |||
</> | |||
); | |||
}; | |||
export default materialSetting; |
@@ -0,0 +1,39 @@ | |||
"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 | |||
}; |
@@ -0,0 +1,40 @@ | |||
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"] }, | |||
}); | |||
}); |
@@ -3,6 +3,7 @@ import { ServerFetchError, serverFetchJson, serverFetchWithNoContent } from "@/a | |||
import { revalidateTag } from "next/cache"; | |||
import { BASE_API_URL } from "@/config/api"; | |||
import { HTMLInputTypeAttribute } from "react"; | |||
import { CreateItemResponse } from "../../utils"; | |||
export type TypeInputs = { | |||
type: string | |||
@@ -36,17 +37,10 @@ export type CreateMaterialInputs = { | |||
uom?: UomInputs[]; | |||
weightUnit?: WeightUnitInputs[]; | |||
} | |||
export interface CreateProductMaterialResponse { | |||
id: number | null; | |||
name: string; | |||
code: string; | |||
message: string | null; | |||
errorPosition: keyof CreateMaterialInputs; | |||
} | |||
export const saveMaterial = async (data: CreateMaterialInputs) => { | |||
// try { | |||
const material = await serverFetchJson<CreateProductMaterialResponse>(`${BASE_API_URL}/material/new`, { | |||
const material = await serverFetchJson<CreateItemResponse<CreateMaterialInputs>>(`${BASE_API_URL}/material/new`, { | |||
method: "POST", | |||
body: JSON.stringify(data), | |||
headers: { "Content-Type": "application/json" }, | |||
@@ -2,7 +2,8 @@ | |||
import { ServerFetchError, serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil"; | |||
import { revalidateTag } from "next/cache"; | |||
import { BASE_API_URL } from "@/config/api"; | |||
import { CreateProductMaterialResponse, TypeInputs, UomInputs, WeightUnitInputs } from "../material/actions"; | |||
import { TypeInputs, UomInputs, WeightUnitInputs } from "../material/actions"; | |||
import { CreateItemResponse } from "../../utils"; | |||
export type CreateProductInputs = { | |||
id?: string | number | |||
@@ -26,11 +27,11 @@ export type CreateProductInputs = { | |||
export const saveProduct = async (data: CreateProductInputs) => { | |||
// try { | |||
const material = await serverFetchJson<CreateProductMaterialResponse>(`${BASE_API_URL}/product/new`, { | |||
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 material | |||
return product | |||
}; |
@@ -2,14 +2,13 @@ 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; | |||
isConsumables: boolean; | |||
description: string | undefined; | |||
type: string | undefined; | |||
remarks: string | undefined; | |||
shelfLife: Number | undefined; | |||
countryOfOrigin: string | undefined; | |||
@@ -20,20 +19,21 @@ export type ProductResult = { | |||
sampleRate: number | undefined; | |||
passingRate: number | undefined; | |||
netWeight: number | undefined; | |||
uom: string[] | any[]; | |||
weightUnit: string[] | any[]; | |||
uom: UomInputs[]; | |||
weightUnit: WeightUnitInputs[]; | |||
type: TypeInputs[]; | |||
action?: any; | |||
} | |||
export const fetchAllMaterials = cache(async () => { | |||
export const fetchAllProduct = cache(async () => { | |||
return serverFetchJson<ProductResult[]>(`${BASE_API_URL}/product`, { | |||
next: { tags: ["product"] }, | |||
}); | |||
}); | |||
export const fetchMaterial = cache(async (id: number) => { | |||
export const fetchProduct = cache(async (id: number) => { | |||
return serverFetchJson<ProductResult>(`${BASE_API_URL}/product/details/${id}`, { | |||
next: { tags: ["product"] }, | |||
}); |
@@ -0,0 +1,7 @@ | |||
export interface CreateItemResponse<T> { | |||
id: number | null; | |||
name: string; | |||
code: string; | |||
message: string | null; | |||
errorPosition: string | keyof T; | |||
} |
@@ -1,4 +1,5 @@ | |||
export enum TypeEnum { | |||
PRODUCT = "product", | |||
MATERIAL = "material", | |||
BYPRODUCT = "byProduct", | |||
} |
@@ -0,0 +1,302 @@ | |||
"use client"; | |||
import { CreateMaterialInputs } from "@/app/api/settings/material/actions"; | |||
import { | |||
Box, | |||
Card, | |||
CardContent, | |||
Grid, | |||
Stack, | |||
TextField, | |||
Typography, | |||
} from "@mui/material"; | |||
import { useFormContext } from "react-hook-form"; | |||
import { useTranslation } from "react-i18next"; | |||
import InputDataGrid from "../InputDataGrid"; | |||
import { useCallback, useMemo, useState } from "react"; | |||
import { GridColDef, GridRowModel } from "@mui/x-data-grid"; | |||
import { InputDataGridProps, TableRow } from "../InputDataGrid/InputDataGrid"; | |||
import { TypeEnum } from "@/app/utils/typeEnum"; | |||
import { CreateByProductInputs } from "@/app/api/settings/byProduct/actions"; | |||
import { NumberInputProps } from "./NumberInputProps"; | |||
type Props = { | |||
// isEditMode: boolean; | |||
// type: TypeEnum; | |||
}; | |||
export type EntryError = | |||
| { | |||
[field in keyof CreateByProductInputs]?: string; | |||
} | |||
| undefined; | |||
const ByProductDetails: React.FC<Props> = ({ | |||
}) => { | |||
const { | |||
t, | |||
i18n: { language }, | |||
} = useTranslation(); | |||
const { | |||
register, | |||
formState: { errors, defaultValues, touchedFields }, | |||
watch, | |||
control, | |||
setValue, | |||
getValues, | |||
reset, | |||
resetField, | |||
setError, | |||
clearErrors, | |||
} = useFormContext<CreateByProductInputs>(); | |||
const typeColumns = useMemo<GridColDef[]>( | |||
() => [ | |||
{ | |||
field: "type", | |||
headerName: "type", | |||
flex: 1, | |||
editable: true, | |||
}, | |||
], | |||
[] | |||
); | |||
const weightUnitColumns = useMemo<GridColDef[]>( | |||
() => [ | |||
{ | |||
field: "weightUnit", | |||
headerName: "Weight Unit", | |||
flex: 1, | |||
editable: true, | |||
}, | |||
{ | |||
field: "conversion", | |||
headerName: "conversion", // show base unit | |||
flex: 1, | |||
type: "number", | |||
editable: true, | |||
}, | |||
], | |||
[] | |||
); | |||
const uomColumns = useMemo<GridColDef[]>( | |||
() => [ | |||
{ | |||
field: "uom", | |||
headerName: "uom", | |||
flex: 1, | |||
editable: true, | |||
}, | |||
], | |||
[] | |||
); | |||
const validationTest = useCallback( | |||
( | |||
newRow: GridRowModel<TableRow<Partial<CreateByProductInputs>, EntryError>> | |||
): EntryError => { | |||
const error: EntryError = {}; | |||
console.log(newRow); | |||
return Object.keys(error).length > 0 ? error : undefined; | |||
}, | |||
[] | |||
); | |||
return ( | |||
<Card sx={{ display: "block" }}> | |||
<CardContent component={Stack} spacing={4}> | |||
<Box> | |||
<Typography variant="overline" display="block" marginBlockEnd={1}> | |||
{t("Product Details")} | |||
</Typography> | |||
<Grid container spacing={2} columns={{ xs: 6, sm: 12 }}> | |||
<Grid item xs={6}> | |||
<TextField | |||
label={t("Name")} | |||
fullWidth | |||
{...register("name", { | |||
required: "name required!", | |||
})} | |||
error={Boolean(errors.name)} | |||
helperText={errors.name?.message} | |||
/> | |||
</Grid> | |||
<Grid item xs={6}> | |||
<TextField | |||
label={t("Code")} | |||
fullWidth | |||
{...register("code", { | |||
required: "code required!", | |||
})} | |||
error={Boolean(errors.code)} | |||
helperText={errors.code?.message} | |||
/> | |||
</Grid> | |||
<Grid item xs={6}> | |||
<TextField | |||
label={t("description")} | |||
fullWidth | |||
{...register("description")} | |||
/> | |||
</Grid> | |||
<Grid item xs={6}> | |||
<TextField | |||
label={t("shelfLife")} | |||
type="number" | |||
fullWidth | |||
{...register("shelfLife", { | |||
valueAsNumber: true, | |||
required: "shelfLife required!", | |||
})} | |||
error={Boolean(errors.shelfLife)} | |||
helperText={errors.shelfLife?.message} | |||
/> | |||
</Grid> | |||
<Grid item xs={6}> | |||
<TextField | |||
label={t("countryOfOrigin")} | |||
fullWidth | |||
{...register("countryOfOrigin", { | |||
required: "countryOfOrigin required!", | |||
})} | |||
error={Boolean(errors.countryOfOrigin)} | |||
helperText={errors.countryOfOrigin?.message} | |||
/> | |||
</Grid> | |||
<Grid item xs={6}> | |||
<TextField | |||
label={t("minHumid")} | |||
type="number" | |||
fullWidth | |||
inputProps={NumberInputProps} | |||
{...register("minHumid", { | |||
valueAsNumber: true, | |||
required: "minHumid required!", | |||
})} | |||
error={Boolean(errors.minHumid)} | |||
helperText={errors.minHumid?.message} | |||
/> | |||
</Grid> | |||
<Grid item xs={6}> | |||
<TextField | |||
label={t("maxHumid")} | |||
type="number" | |||
fullWidth | |||
inputProps={NumberInputProps} | |||
{...register("maxHumid", { | |||
valueAsNumber: true, | |||
})} | |||
error={Boolean(errors.maxHumid)} | |||
helperText={errors.maxHumid?.message} | |||
/> | |||
</Grid> | |||
<Grid item xs={6}> | |||
<TextField | |||
label={t("minTemp")} | |||
type="number" | |||
fullWidth | |||
inputProps={NumberInputProps} | |||
{...register("minTemp", { | |||
valueAsNumber: true, | |||
required: "minTemp required!", | |||
})} | |||
error={Boolean(errors.minTemp)} | |||
helperText={errors.minTemp?.message} | |||
/> | |||
</Grid> | |||
<Grid item xs={6}> | |||
<TextField | |||
label={t("maxTemp")} | |||
type="number" | |||
fullWidth | |||
inputProps={NumberInputProps} | |||
{...register("maxTemp", { | |||
valueAsNumber: true, | |||
required: "maxTemp required!", | |||
})} | |||
error={Boolean(errors.maxTemp)} | |||
helperText={errors.maxTemp?.message} | |||
/> | |||
</Grid> | |||
<Grid item xs={6}> | |||
<TextField | |||
label={t("sampleRate")} | |||
type="number" | |||
fullWidth | |||
inputProps={NumberInputProps} | |||
{...register("sampleRate", { | |||
valueAsNumber: true, | |||
required: "sampleRate required!", | |||
})} | |||
error={Boolean(errors.sampleRate)} | |||
helperText={errors.sampleRate?.message} | |||
/> | |||
</Grid> | |||
<Grid item xs={6}> | |||
<TextField | |||
label={t("passingRate")} | |||
type="number" | |||
fullWidth | |||
inputProps={NumberInputProps} | |||
{...register("passingRate", { | |||
valueAsNumber: true, | |||
required: "passingRate required!", | |||
})} | |||
error={Boolean(errors.passingRate)} // change backend for null or not null | |||
helperText={errors.passingRate?.message} | |||
/> | |||
</Grid> | |||
<Grid item xs={6} /> | |||
<Grid item xs={6}> | |||
<TextField | |||
label={t("remarks")} | |||
fullWidth | |||
{...register("remarks", { | |||
// required: "remarks required!", | |||
})} | |||
error={Boolean(errors.remarks)} | |||
helperText={errors.remarks?.message} | |||
/> | |||
</Grid> | |||
<Grid item xs={6}> | |||
<TextField | |||
label={t("netWeight")} | |||
type="number" | |||
fullWidth | |||
inputProps={NumberInputProps} | |||
{...register("netWeight", { | |||
valueAsNumber: true, | |||
required: "netWeight required!", | |||
})} | |||
error={Boolean(errors.netWeight)} | |||
helperText={errors.netWeight?.message} | |||
/> | |||
</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> | |||
</Box> | |||
</CardContent> | |||
</Card> | |||
); | |||
}; | |||
export default ByProductDetails; |
@@ -5,7 +5,6 @@ import { useRouter, useSearchParams } from "next/navigation"; | |||
import { useTranslation } from "react-i18next"; | |||
import { | |||
CreateMaterialInputs, | |||
CreateProductMaterialResponse, | |||
saveMaterial, | |||
} from "@/app/api/settings/material/actions"; | |||
import { | |||
@@ -25,6 +24,9 @@ import { | |||
import { CreateInputsFields } from "./CreateProductMaterialWrapper"; | |||
import MaterialDetails from "./MaterialDetails"; | |||
import ProductDetails from "./ProductDetails"; | |||
import { CreateItemResponse } from "@/app/api/utils"; | |||
import { CreateByProductInputs, saveByProduct } from "@/app/api/settings/byProduct/actions"; | |||
import ByProductDetails from "./ByProductDetails"; | |||
type Props = { | |||
isEditMode: boolean; | |||
@@ -53,6 +55,10 @@ const CreateProductMaterial: React.FC<Props> = ({ | |||
title = "Product"; | |||
redirPath = "/product"; | |||
} | |||
if (type === TypeEnum.BYPRODUCT) { | |||
title = "By-Product"; | |||
redirPath = "/byProduct"; | |||
} | |||
if (isEditMode) { | |||
mode = "Edit"; | |||
} else { | |||
@@ -99,8 +105,16 @@ const CreateProductMaterial: React.FC<Props> = ({ | |||
}); | |||
hasErrors = true; | |||
} | |||
// checking temp input | |||
if (data.netWeight && data.netWeight < 0) { | |||
const message = "netWeight should not be greater than 0"; | |||
formProps.setError("netWeight", { | |||
message: message, | |||
type: "required", | |||
}); | |||
} | |||
// checking passing rate | |||
if (data.passingRate && data.passingRate > 100) { | |||
if (data.passingRate && (data.passingRate < 0 || data.passingRate > 100)) { | |||
const message = "passingRate should not be greater than 100%"; | |||
formProps.setError("passingRate", { | |||
message: message, | |||
@@ -108,7 +122,7 @@ const CreateProductMaterial: React.FC<Props> = ({ | |||
}); | |||
} | |||
// checking sampling rate | |||
if (data.sampleRate && data.sampleRate > 100) { | |||
if (data.sampleRate && (data.sampleRate < 0 || data.sampleRate > 100)) { | |||
const message = "sampleRate should not be greater than 100%"; | |||
formProps.setError("sampleRate", { | |||
message: message, | |||
@@ -122,15 +136,21 @@ const CreateProductMaterial: React.FC<Props> = ({ | |||
console.log("data posted"); | |||
console.log(data); | |||
// do api | |||
var response: CreateProductMaterialResponse | undefined; | |||
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"); | |||
} | |||
if (response) { | |||
if (!Boolean(response.id)) { | |||
formProps.setError(response.errorPosition!!, { | |||
formProps.setError(response.errorPosition!! as keyof CreateInputsFields, { | |||
message: response.message!!, | |||
type: "required", | |||
}); | |||
@@ -176,6 +196,7 @@ const CreateProductMaterial: React.FC<Props> = ({ | |||
)} | |||
{type === TypeEnum.MATERIAL && <MaterialDetails />} | |||
{type === TypeEnum.PRODUCT && <ProductDetails />} | |||
{type === TypeEnum.BYPRODUCT && <ByProductDetails />} | |||
<Stack direction="row" justifyContent="flex-end" gap={1}> | |||
<Button | |||
name="submit" | |||
@@ -3,67 +3,57 @@ 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, MaterialResult } from "@/app/api/settings/material"; | |||
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 CreateMaterialProps = { | |||
// isEditMode: false; | |||
type Props = { | |||
id?: number | |||
type: TypeEnum; | |||
}; | |||
type EditMaterialProps = { | |||
// isEditMode: true; | |||
type: TypeEnum; | |||
}; | |||
type CreateProductProps = { | |||
// isEditMode: false; | |||
type: TypeEnum; | |||
}; | |||
type EditProductProps = { | |||
// isEditMode: true; | |||
type: TypeEnum; | |||
}; | |||
type Props = | |||
| CreateMaterialProps | |||
| EditMaterialProps | |||
| CreateProductProps | |||
| EditProductProps; | |||
export type CreateInputsFields = CreateMaterialInputs | CreateProductInputs; | |||
export type CreateInputsFields = CreateMaterialInputs | CreateProductInputs | CreateByProductInputs; | |||
const CreateProductMaterialWrapper: React.FC<Props & { id?: number }> & | |||
const CreateProductMaterialWrapper: React.FC<Props> & | |||
SubComponents = async ({ type, id }) => { | |||
var defaultValues: Partial<CreateInputsFields> = {}; | |||
var result | |||
if (id && type === TypeEnum.MATERIAL) { | |||
const result = await fetchMaterial(id); | |||
console.log(result) | |||
result = await fetchMaterial(id); | |||
defaultValues = { | |||
id: result.id, | |||
code: result.name, | |||
name: result.name, | |||
isConsumables: result.isConsumables, | |||
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, | |||
}; | |||
isConsumables: result.isConsumables | |||
} | |||
} else if (id && type === TypeEnum.PRODUCT) { | |||
result = await fetchProduct(id); | |||
} else if (id && type === TypeEnum.BYPRODUCT) { | |||
result = await fetchByProduct(id); | |||
} | |||
if (id && type === TypeEnum.PRODUCT) { | |||
defaultValues = {}; | |||
} | |||
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)} | |||
@@ -229,8 +229,6 @@ const ProductDetails: React.FC<Props> = ({ | |||
inputProps={NumberInputProps} | |||
{...register("sampleRate", { | |||
valueAsNumber: true, | |||
min: 0, | |||
max: 100, | |||
required: "sampleRate required!", | |||
})} | |||
error={Boolean(errors.sampleRate)} | |||
@@ -245,8 +243,6 @@ const ProductDetails: React.FC<Props> = ({ | |||
inputProps={NumberInputProps} | |||
{...register("passingRate", { | |||
valueAsNumber: true, | |||
min: 0, | |||
max: 100, | |||
required: "passingRate required!", | |||
})} | |||
error={Boolean(errors.passingRate)} // change backend for null or not null | |||
@@ -188,8 +188,8 @@ const NavigationContent: React.FC = () => { | |||
}, | |||
{ | |||
icon: <RequestQuote />, | |||
label: "Maintain By-product", | |||
path: "/settings/user", | |||
label: "By-product", | |||
path: "/settings/byProduct", | |||
}, | |||
{ | |||
icon: <RequestQuote />, | |||
@@ -100,6 +100,11 @@ const MaterialSearch: React.FC<Props> = ({ productMaterial, type }) => { | |||
pm.code.toLowerCase().includes(query.code.toLowerCase()) && | |||
pm.name.toLowerCase().includes(query.name.toLowerCase()) | |||
); | |||
} else if (type === TypeEnum.BYPRODUCT) { | |||
return ( | |||
pm.code.toLowerCase().includes(query.code.toLowerCase()) && | |||
pm.name.toLowerCase().includes(query.name.toLowerCase()) | |||
); | |||
} | |||
}) | |||
); | |||
@@ -3,6 +3,7 @@ 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; | |||
@@ -13,16 +14,20 @@ type Props = { | |||
}; | |||
const ProductMaterialSearchWrapper: React.FC<Props> & SubComponents = async ({ | |||
type | |||
type, | |||
}) => { | |||
var result: ListResult[] = [] | |||
if (TypeEnum.PRODUCT === type) { | |||
result = [] | |||
} else if (TypeEnum.MATERIAL === 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={TypeEnum.MATERIAL} />; | |||
return <ProductMaterialSearch productMaterial={result} type={type} />; | |||
}; | |||
ProductMaterialSearchWrapper.Loading = MaterialSearchLoading; | |||