|
|
@@ -0,0 +1,377 @@ |
|
|
|
"use client"; |
|
|
|
import { |
|
|
|
Card, |
|
|
|
CardHeader, |
|
|
|
CardContent, |
|
|
|
SxProps, |
|
|
|
Theme, |
|
|
|
Typography, |
|
|
|
Grid, |
|
|
|
TextField, |
|
|
|
FormControl, |
|
|
|
InputLabel, |
|
|
|
Select, |
|
|
|
MenuItem, |
|
|
|
Checkbox, |
|
|
|
FormControlLabel, |
|
|
|
Button, |
|
|
|
} from "@mui/material"; |
|
|
|
import { DataGrid, GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; |
|
|
|
import { darken, lighten, styled } from "@mui/material/styles"; |
|
|
|
import { Controller, useForm, useFormContext } from "react-hook-form"; |
|
|
|
import Stack from "@mui/material/Stack"; |
|
|
|
import { useTranslation } from "react-i18next"; |
|
|
|
import Box from "@mui/material/Box"; |
|
|
|
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; |
|
|
|
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; |
|
|
|
import { DemoItem } from "@mui/x-date-pickers/internals/demo"; |
|
|
|
import { DatePicker } from "@mui/x-date-pickers/DatePicker"; |
|
|
|
import dayjs from "dayjs"; |
|
|
|
import { useEffect, useState } from "react"; |
|
|
|
import { Check } from "@mui/icons-material"; |
|
|
|
|
|
|
|
// interface Option { |
|
|
|
// // Define properties of each option object |
|
|
|
// // based on your specific requirements |
|
|
|
// id: any; |
|
|
|
// value: any; |
|
|
|
// label: string; |
|
|
|
// } |
|
|
|
|
|
|
|
interface Field { |
|
|
|
// subtitle: string; |
|
|
|
id: string; |
|
|
|
label: string; |
|
|
|
type: string; |
|
|
|
value?: any; |
|
|
|
required?: boolean; |
|
|
|
options?: any[]; |
|
|
|
readOnly?: boolean; |
|
|
|
} |
|
|
|
|
|
|
|
interface CustomInputFormProps { |
|
|
|
onSubmit: (data: any) => void; |
|
|
|
// resetForm: () => void; |
|
|
|
Title?: string[]; |
|
|
|
isActive: boolean; |
|
|
|
fieldLists: Field[][]; |
|
|
|
} |
|
|
|
|
|
|
|
const CustomInputForm: React.FC<CustomInputFormProps> = ({ |
|
|
|
Title, |
|
|
|
isActive, |
|
|
|
fieldLists, |
|
|
|
onSubmit, |
|
|
|
// resetForm, |
|
|
|
}) => { |
|
|
|
const { t } = useTranslation(); |
|
|
|
const { reset, register, handleSubmit, control } = useForm(); |
|
|
|
const [dateObj, setDateObj] = useState<any>(null); |
|
|
|
const [value, setValue] = useState<any>({}); |
|
|
|
const [checkboxValue, setCheckboxValue] = useState({}); |
|
|
|
// const [dateObj, setDateObj] = useState({}); |
|
|
|
|
|
|
|
interface DateObj { |
|
|
|
[key: string]: string; |
|
|
|
} |
|
|
|
|
|
|
|
const handleFormSubmit = (data: any) => { |
|
|
|
// if (date != null || date != undefined ) { |
|
|
|
// data.date = dayjs(date).format('YYYY-MM-DD'); |
|
|
|
// } |
|
|
|
for (const key in data) { |
|
|
|
if (!isNaN(data[key])) { |
|
|
|
if (data[key] !== "") { |
|
|
|
if (Number.isInteger(parseFloat(data[key]))) { |
|
|
|
data[key] = parseInt(data[key]); |
|
|
|
} else { |
|
|
|
data[key] = parseFloat(data[key]); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (checkboxValue !== null) { |
|
|
|
data = { ...data, ...checkboxValue }; |
|
|
|
} |
|
|
|
|
|
|
|
// if (value !== null) { |
|
|
|
// data.dropdownCombo = value; |
|
|
|
// } |
|
|
|
const finalData = { |
|
|
|
...value, |
|
|
|
...data, |
|
|
|
...dateObj, |
|
|
|
}; |
|
|
|
|
|
|
|
console.log(finalData); |
|
|
|
onSubmit(finalData); |
|
|
|
}; |
|
|
|
|
|
|
|
const handleDateChange = (id: string, newValue: dayjs.Dayjs | null): void => { |
|
|
|
console.log(dayjs(newValue).format("YYYY-MM-DD")); |
|
|
|
setDateObj((prevValues: DateObj) => ({ |
|
|
|
...prevValues, |
|
|
|
[id]: newValue ? dayjs(newValue).format("YYYY-MM-DD") : "", |
|
|
|
})); |
|
|
|
}; |
|
|
|
|
|
|
|
const handleCheckboxChange = (id: string, newValue: boolean): void => { |
|
|
|
setCheckboxValue((prevValues: { [key: string]: boolean }) => ({ |
|
|
|
...prevValues, |
|
|
|
[id]: newValue, |
|
|
|
})); |
|
|
|
}; |
|
|
|
|
|
|
|
const handleAutocompleteChange = (id: any, newValue: any) => { |
|
|
|
setValue((prevValues: any) => ({ |
|
|
|
...prevValues, |
|
|
|
[id]: newValue, |
|
|
|
})); |
|
|
|
}; |
|
|
|
|
|
|
|
fieldLists.forEach((list) => { |
|
|
|
list.forEach((obj) => { |
|
|
|
if ( |
|
|
|
obj.id === "created" || |
|
|
|
obj.id === "createdBy" || |
|
|
|
obj.id === "modified" || |
|
|
|
obj.id === "deleted" || |
|
|
|
obj.id === "modifiedBy" |
|
|
|
) { |
|
|
|
obj.readOnly = true; |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
// useEffect(() => { |
|
|
|
// if (dateObj) { |
|
|
|
// console.log(dateObj); |
|
|
|
// } |
|
|
|
// }, [dateObj]); |
|
|
|
|
|
|
|
return ( |
|
|
|
<form onSubmit={handleSubmit(handleFormSubmit)}> |
|
|
|
<Card sx={{ display: isActive ? "block" : "none" }}> |
|
|
|
<CardContent component={Stack} spacing={4}> |
|
|
|
<> |
|
|
|
{fieldLists.map((fieldList, fieldListIndex) => ( |
|
|
|
<Box key={fieldListIndex}> |
|
|
|
{Title ? ( |
|
|
|
<Typography |
|
|
|
variant="overline" |
|
|
|
display="block" |
|
|
|
marginBlockEnd={1} |
|
|
|
> |
|
|
|
{t(`${Title[fieldListIndex]}`)} |
|
|
|
</Typography> |
|
|
|
) : null} |
|
|
|
<Grid container spacing={2} columns={{ xs: 6, sm: 12 }}> |
|
|
|
{fieldList.map((field: Field) => { |
|
|
|
if (field.type === "textfield") { |
|
|
|
return ( |
|
|
|
<Grid item xs={6} key={field.id}> |
|
|
|
<TextField |
|
|
|
label={t(`${field.label}`)} |
|
|
|
fullWidth |
|
|
|
// {...register(`asdasd`, { |
|
|
|
{...register(`${field.id}`, { |
|
|
|
required: field.required ?? false, |
|
|
|
})} |
|
|
|
// error={Boolean(errors.projectCode)} |
|
|
|
/> |
|
|
|
</Grid> |
|
|
|
); |
|
|
|
} else if (field.type === "multiDate") { |
|
|
|
return ( |
|
|
|
<Grid item xs={6} key={field.id}> |
|
|
|
<LocalizationProvider dateAdapter={AdapterDayjs}> |
|
|
|
<DemoItem> |
|
|
|
<DatePicker |
|
|
|
key={field.id} |
|
|
|
label={field.label} |
|
|
|
value={!dateObj ? null : !dateObj[field.id] ? null : dayjs(dateObj[field.id])} // Set initial value or use a default value from state |
|
|
|
onChange={(newValue) => { |
|
|
|
handleDateChange(field.id, newValue); |
|
|
|
}} |
|
|
|
// required = {field.required ?? false}, |
|
|
|
/> |
|
|
|
</DemoItem> |
|
|
|
</LocalizationProvider> |
|
|
|
</Grid> |
|
|
|
); |
|
|
|
} else if (field.type === "combo-Obj") { |
|
|
|
return ( |
|
|
|
<Grid item xs={6} key={field.id}> |
|
|
|
<FormControl fullWidth> |
|
|
|
<InputLabel id={`${field.id}-label`}> |
|
|
|
{field.label} |
|
|
|
</InputLabel> |
|
|
|
<Controller |
|
|
|
name={field.id} |
|
|
|
control={control} |
|
|
|
defaultValue={ |
|
|
|
field.value !== undefined ? field.value : "" |
|
|
|
} |
|
|
|
render={({ field: { onChange, value } }) => ( |
|
|
|
<Select |
|
|
|
labelId={`${field.id}-label`} |
|
|
|
id={field.id} |
|
|
|
value={value} |
|
|
|
onChange={(event) => { |
|
|
|
console.log(event); |
|
|
|
console.log(event.target); |
|
|
|
onChange(event.target.value); |
|
|
|
const newValue = event.target.value; |
|
|
|
const selectedOption = field.options?.find( |
|
|
|
(option) => option.id === newValue |
|
|
|
); |
|
|
|
handleAutocompleteChange( |
|
|
|
field.id, |
|
|
|
selectedOption |
|
|
|
); |
|
|
|
}} |
|
|
|
required={field.required} |
|
|
|
> |
|
|
|
{field.options?.map((option) => ( |
|
|
|
<MenuItem |
|
|
|
value={ |
|
|
|
option.id !== undefined |
|
|
|
? option.id |
|
|
|
: option |
|
|
|
} |
|
|
|
key={ |
|
|
|
option.id !== undefined |
|
|
|
? option.id |
|
|
|
: option |
|
|
|
} |
|
|
|
> |
|
|
|
{option.id !== undefined |
|
|
|
? option.label |
|
|
|
: option} |
|
|
|
</MenuItem> |
|
|
|
))} |
|
|
|
</Select> |
|
|
|
)} |
|
|
|
/> |
|
|
|
</FormControl> |
|
|
|
</Grid> |
|
|
|
); |
|
|
|
} else if (field.type === "numeric") { |
|
|
|
return ( |
|
|
|
<Grid item xs={6} key={field.id}> |
|
|
|
<TextField |
|
|
|
fullWidth |
|
|
|
{...register(field.id)} |
|
|
|
id={field.id} |
|
|
|
label={field.label} |
|
|
|
defaultValue={!field.value ? `${field.value}` : ""} |
|
|
|
inputProps={{ |
|
|
|
inputMode: "numeric", |
|
|
|
pattern: "^-?\\d*\\.?\\d+$", |
|
|
|
}} |
|
|
|
required={field.required} |
|
|
|
/> |
|
|
|
</Grid> |
|
|
|
); |
|
|
|
} else if (field.type === "numeric-positive") { |
|
|
|
return ( |
|
|
|
<Grid item xs={6} key={field.id}> |
|
|
|
<TextField |
|
|
|
fullWidth |
|
|
|
{...register(field.id)} |
|
|
|
id={field.id} |
|
|
|
label={field.label} |
|
|
|
defaultValue={!field.value ? `${field.value}` : ""} |
|
|
|
inputProps={{ |
|
|
|
inputMode: "numeric", |
|
|
|
pattern: "[0-9]*[.]?[0-9]*", |
|
|
|
}} |
|
|
|
required={field.required} |
|
|
|
/> |
|
|
|
</Grid> |
|
|
|
); |
|
|
|
} else if (field.type === "checkbox") { |
|
|
|
return ( |
|
|
|
<Grid item xs={6} key={field.id}> |
|
|
|
<FormControlLabel |
|
|
|
control={ |
|
|
|
<Checkbox |
|
|
|
defaultChecked={field.value} |
|
|
|
onChange={(event) => { |
|
|
|
handleCheckboxChange( |
|
|
|
field.id, |
|
|
|
event.target.checked |
|
|
|
); |
|
|
|
}} |
|
|
|
color="primary" |
|
|
|
/> |
|
|
|
} |
|
|
|
label={ |
|
|
|
<Typography variant="h4"> |
|
|
|
{field.label} |
|
|
|
</Typography> |
|
|
|
} |
|
|
|
/> |
|
|
|
</Grid> |
|
|
|
); |
|
|
|
} else if (field.type === "remarks") { |
|
|
|
return ( |
|
|
|
<Grid item xs={12} key={field.id}> |
|
|
|
<TextField |
|
|
|
fullWidth |
|
|
|
multiline |
|
|
|
rows={4} |
|
|
|
variant="filled" |
|
|
|
{...register(field.id)} |
|
|
|
defaultValue={!field.value ? `${field.value}` : ""} |
|
|
|
id={field.id} |
|
|
|
label={field.label} |
|
|
|
required={field.required} |
|
|
|
/> |
|
|
|
</Grid> |
|
|
|
); |
|
|
|
} else { |
|
|
|
return ( |
|
|
|
<Grid item xs={6} key={field.id}> |
|
|
|
<TextField |
|
|
|
fullWidth |
|
|
|
{...register( |
|
|
|
field.id |
|
|
|
// , { required: true } |
|
|
|
)} |
|
|
|
id={field.id} |
|
|
|
label={field.label} |
|
|
|
defaultValue={`${field.value}`} |
|
|
|
required={field.required} |
|
|
|
inputProps={{ |
|
|
|
readOnly: field.readOnly, |
|
|
|
}} |
|
|
|
/> |
|
|
|
</Grid> |
|
|
|
); |
|
|
|
} |
|
|
|
})} |
|
|
|
</Grid> |
|
|
|
</Box> |
|
|
|
))} |
|
|
|
<Stack direction="row" justifyContent="flex-end" gap={1}> |
|
|
|
{/* <Button |
|
|
|
variant="outlined" |
|
|
|
startIcon={<Close />} |
|
|
|
onClick={handleCancel} |
|
|
|
> |
|
|
|
{t("Cancel")} |
|
|
|
</Button> */} |
|
|
|
<Button variant="contained" startIcon={<Check />} type="submit"> |
|
|
|
{t("Confirm")} |
|
|
|
</Button> |
|
|
|
</Stack> |
|
|
|
</> |
|
|
|
</CardContent> |
|
|
|
</Card> |
|
|
|
</form> |
|
|
|
); |
|
|
|
}; |
|
|
|
|
|
|
|
export default CustomInputForm; |