|
- "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 { useCallback, useEffect, useState } from "react";
- import { Check, Close } from "@mui/icons-material";
- import { NumericFormat, NumericFormatProps } from "react-number-format";
- import * as React from "react";
-
- // 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;
- pattern?: string;
- message?: string;
- options?: any[];
- readOnly?: boolean;
- size?: number;
- setValue?: any[];
- }
- interface CustomProps {
- onChange: (event: { target: { name: string; value: string } }) => void;
- name: string;
- }
- interface CustomInputFormProps {
- onSubmit: (data: any) => void;
- onSubmitError?: (data: any) => void;
- onCancel: () => void;
- // resetForm: () => void;
- Title?: string[];
- isActive: boolean;
- fieldLists: Field[][];
- }
-
- // interface SubComponents {
- // Loading: typeof CustomerSearchLoading;
- // }
-
- const CustomInputForm: React.FC<CustomInputFormProps> = ({
- Title,
- isActive,
- fieldLists,
- onSubmit,
- onSubmitError,
- onCancel,
- // resetForm,
- }) => {
- const { t } = useTranslation();
- const {
- reset,
- register,
- handleSubmit,
- control,
- formState: { errors },
- } = useForm();
- const [dateObj, setDateObj] = useState<any>(null);
- const [value, setValue] = useState<any>({});
- const [checkboxValue, setCheckboxValue] = 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 };
- }
-
- 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,
- }));
- };
-
- const handleCancel = () => {
- reset();
- // resetForm();
- // setFromDate(null);
- setDateObj(null);
- setValue({});
- if (onCancel) {
- onCancel();
- }
- // if fields include setValue func
- // fieldLists.map((list) => {
- // list.map((field) => {
- // if (typeof field.setValue === 'function') {
- // field.setValue(typeof field.value === 'boolean' ? false : null);
- // } else if (typeof field.setValue === 'object') {
- // field.setValue.map((setFunc: any) => {
- // setFunc(null);
- // });
- // }
- // })
- // });
- // setToDate(null);
- };
-
- 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;
- }
- });
- });
-
- const NumericFormatCustom = React.forwardRef<NumericFormatProps, CustomProps>(
- function NumericFormatCustom(props, ref) {
- const { onChange, ...other } = props;
-
- return (
- <NumericFormat
- {...other}
- getInputRef={ref}
- onValueChange={(values) => {
- onChange({
- target: {
- name: props.name,
- value: values.value,
- },
- });
- }}
- thousandSeparator
- valueIsNumericString
- prefix="$"
- />
- );
- }
- );
- const [values, setValues] = React.useState({
- hourlyRate: "",
- });
- const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
- setValues({
- ...values,
- [event.target.name]: event.target.value,
- });
- };
-
- return (
- <form onSubmit={handleSubmit(handleFormSubmit, onSubmitError)}>
- <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 === "text") {
- return (
- <Grid item xs={field.size ?? 6} key={field.id}>
- <TextField
- label={field.label}
- fullWidth
- {...register(field.id, {
- pattern: field.pattern
- ? new RegExp(field.pattern)
- : /.*/,
- })}
- defaultValue={!field.value ? `${field.value}` : ""}
- required={field.required ?? false}
- error={Boolean(errors[field.id])}
- helperText={
- Boolean(errors[field.id]) && field.message
- }
- />
- </Grid>
- );
- } else if (field.type === "email") {
- return (
- <Grid item xs={field.size ?? 6} key={field.id}>
- <TextField
- label={field.label}
- fullWidth
- {...register(field.id, {
- pattern:
- /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$/,
- })}
- defaultValue={!field.value ? `${field.value}` : ""}
- required={field.required ?? false}
- error={Boolean(errors[field.id])}
- helperText={
- Boolean(errors[field.id]) && field.message
- }
- />
- </Grid>
- );
- } else if (field.type === "multiDate") {
- return (
- <Grid item xs={field.size ?? 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={field.size ?? 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={field.size ?? 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-testing") {
- return (
- <Grid item xs={field.size ?? 6} key={field.id}>
- <FormControl fullWidth>
- <Controller
- {...register(field.id)}
- name={field.id}
- control={control}
- defaultValue={
- !field.value ? `${field.value}` : ""
- }
- render={({ field }) => {
- console.log(field);
- return (
- <NumericFormat
- {...field}
- customInput={TextField}
- thousandSeparator
- valueIsNumericString
- prefix="$"
- label={t(field.name)}
- />
- );
- }}
- />
- </FormControl>
- </Grid>
- );
- } else if (field.type === "numeric-positive") {
- return (
- <Grid item xs={field.size ?? 6} key={field.id}>
- <TextField
- fullWidth
- {...register(field.id)}
- id={field.id}
- name={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={field.size ?? 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={field.size ?? 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>
- );
- };
-
- // CustomInputForm.Loading = CustomerSearchLoading;
-
- export default CustomInputForm;
|