"use client"; import Stack from "@mui/material/Stack"; import Card from "@mui/material/Card"; import CardContent from "@mui/material/CardContent"; import Typography from "@mui/material/Typography"; import { useTranslation } from "react-i18next"; import CardActions from "@mui/material/CardActions"; import RestartAlt from "@mui/icons-material/RestartAlt"; import Button from "@mui/material/Button"; import AddIcon from '@mui/icons-material/Add'; import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/DeleteOutlined'; import SaveIcon from '@mui/icons-material/Save'; import CancelIcon from '@mui/icons-material/Close'; import { GridRowsProp, GridRowModesModel, GridRowModes, GridColDef, GridToolbarContainer, GridActionsCellItem, GridEventListener, GridRowId, GridRowModel, GridRowEditStopReasons, } from '@mui/x-data-grid'; import CustomDatagrid from "../CustomDatagrid/CustomDatagrid"; import { useFieldArray, useFormContext } from "react-hook-form"; import { useCallback, useEffect, useMemo, useState } from "react"; interface Props { } interface EditToolbarProps { setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void; setRowModesModel: ( newModel: (oldModel: GridRowModesModel) => GridRowModesModel, ) => void; } var rowId = -1 function EditToolbar(props: EditToolbarProps) { const { setRows, setRowModesModel } = props; const { t } = useTranslation(); const handleClick = () => { const id = rowId; rowId = rowId - 1; setRows((oldRows) => [{ id, name: '', phone: '', email: '', isNew: true }, ...oldRows]); setRowModesModel((oldModel) => ({ ...oldModel, [id]: { mode: GridRowModes.Edit, fieldToFocus: 'name' }, })); }; return ( ); } const ContactInfo: React.FC = ({ }) => { const { t } = useTranslation(); const { control, setValue, getValues, formState: { errors, defaultValues }, setError, clearErrors, reset, watch, resetField } = useFormContext(); const { fields } = useFieldArray({ control, name: "addContacts" }) const initialRows: GridRowsProp = fields.map((item, index) => { return ({ id: Number(getValues(`addContacts[${index}].id`)), name: getValues(`addContacts[${index}].name`), phone: getValues(`addContacts[${index}].phone`), email: getValues(`addContacts[${index}].email`), isNew: false, }) }) const [rows, setRows] = useState([]); const [rowModesModel, setRowModesModel] = useState({}); useEffect(() => { if (initialRows.length > 0 && rows.length === 0) { setRows(initialRows) } }, [initialRows.length > 0]) const handleRowEditStop: GridEventListener<'rowEditStop'> = (params, event) => { if (params.reason === GridRowEditStopReasons.rowFocusOut) { event.defaultMuiPrevented = true; } }; const handleEditClick = (id: GridRowId) => () => { setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.Edit } }); }; const handleSaveClick = (id: GridRowId) => () => { setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.View } }); }; const handleDeleteClick = (id: GridRowId) => () => { const updatedRows = rows.filter((row) => row.id !== id) setRows(updatedRows); setValue("addContacts", updatedRows) }; const handleCancelClick = (id: GridRowId) => () => { setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.View, ignoreModifications: true }, }); const editedRow = rows.find((row) => row.id === id); if (editedRow!.isNew) { setRows(rows.filter((row) => row.id !== id)); } }; const processRowUpdate = useCallback((newRow: GridRowModel) => { const updatedRow = { ...newRow }; const updatedRows = rows.map((row) => (row.id === newRow.id ? updatedRow : row)) setRows(updatedRows); setValue("addContacts", updatedRows) return updatedRow; }, [rows]); const handleRowModesModelChange = useCallback((newRowModesModel: GridRowModesModel) => { setRowModesModel(newRowModesModel); }, [rows]); const resetContact = useCallback(() => { if (defaultValues !== undefined) { resetField("addContacts") // reset({addContacts: defaultValues.addContacts}) setRows((prev) => defaultValues.addContacts) setRowModesModel(rows.reduce((acc, row) => ({...acc, [row.id]: { mode: GridRowModes.View } }), {})) } }, [defaultValues]) const columns = useMemo( () => [ { field: 'name', headerName: t('Contact Name'), editable: true, flex: 1, }, { field: 'phone', headerName: t('Contact Phone'), editable: true, flex: 1, }, { field: 'email', headerName: t('Contact Email'), editable: true, flex: 1, }, { field: 'actions', type: 'actions', headerName: '', flex: 0.6, // width: 100, cellClassName: 'actions', getActions: ({ id, ...params }) => { const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit; if (isInEditMode) { return [ } label="Save" sx={{ color: 'primary.main', }} onClick={handleSaveClick(id)} />, } label="Cancel" className="textPrimary" onClick={handleCancelClick(id)} color="inherit" />, ]; } return [ } label="Edit" className="textPrimary" onClick={handleEditClick(id)} color="inherit" />, } label="Delete" onClick={handleDeleteClick(id)} color="inherit" />, ]; }, }, ], [rows, rowModesModel, t], ); // check error useEffect(() => { if (getValues("addContacts") === undefined || getValues("addContacts") === null) { return; } if (getValues("addContacts").length === 0) { clearErrors("addContacts") } else { const errorRows = rows.filter(row => String(row.name).trim().length === 0 || String(row.phone).trim().length === 0 || String(row.email).trim().length === 0) if (errorRows.length > 0) { setError("addContacts", { message: "Contact details include empty fields", type: "required" }) } else { const errorRows_EmailFormat = rows.filter(row => !/^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$/.test(String(row.email))) if (errorRows_EmailFormat.length > 0) { setError("addContacts", { message: "Contact details include empty fields", type: "email_format" }) } else { clearErrors("addContacts") } } } }, [rows, rowModesModel]) // check editing useEffect(() => { const filteredByKey = Object.fromEntries( Object.entries(rowModesModel).filter(([key, value]) => rowModesModel[key].mode === 'edit')) if (Object.keys(filteredByKey).length > 0) { setValue("isGridEditing", true) } else { setValue("isGridEditing", false) } }, [rowModesModel]) return ( {/*
*/} {t("Contact Info")} {Boolean(errors.addContacts?.type === "required") && ({ color: theme.palette.error.main })} variant="overline" display='inline-block' noWrap> {t("Please ensure at least one row is created, and all the fields are inputted and saved")} } {Boolean(errors.addContacts?.type === "email_format") && ({ color: theme.palette.error.main })} variant="overline" display='inline-block' noWrap> {t("Please ensure all the email formats are correct")} } {/*
*/}
); }; export default ContactInfo;