// import {
// Box,
// Button,
// Grid,
// Container,
// MenuItem,
// SvgIcon,
// TextField,
// Typography,
// Autocomplete,
// } from "@mui/material";
// import { useForm, Controller } from "react-hook-form";
// import { useRouter } from "next/router";
// import { useEffect, useState } from "react";
// import NextLink from "next/link";
// import { toast } from "react-toastify";
// import { Layout as DashboardLayout } from "src/layouts/dashboard/layout";
// import menuapi from "src/services/api/menu";
// import * as MuiIcons from "@mui/icons-material";
// import availableIcons from "src/static/icons";
// import Link from "next/link";
// import { ArrowLeft } from "src/Icons/ArrowLeft";
// const DynamicMuiIcon = ({ iconName }) => {
// if (!iconName) return null;
// const IconComponent = MuiIcons[iconName];
// return IconComponent ? (
// <IconComponent fontSize="small" />
// ) : (
// <span title="Icon not found">❓</span>
// );
// };
// const defaultValues = {
// menuName: "",
// menuCode: "",
// parentMenuId: "",
// url: "",
// icon: "",
// displayOrder: "",
// status: "Active",
// };
// const MenuForm = () => {
// const {
// register,
// handleSubmit,
// reset,
// watch,
// setValue,
// control,
// formState: { errors },
// } = useForm({ defaultValues });
// const [allMenus, setAllMenus] = useState([]);
// const router = useRouter();
// const { mode = "add", id } = router.query;
// useEffect(() => {
// fetchAllMenus();
// if (mode === "edit" && id) {
// fetchMenuDetails();
// }
// }, [id, mode]);
// const fetchAllMenus = async () => {
// try {
// const res = await menuapi.getAllMenuApi();
// setAllMenus(res.data.data || []);
// } catch (error) {
// toast.error("Failed to load menus");
// }
// };
// const fetchMenuDetails = async () => {
// try {
// const res = await menuapi.getMenuById(id);
// const data = res.data.data;
// reset({
// ...data,
// parentMenuId: data.parentMenuId || "",
// status: data.status || "Active",
// displayOrder: data.displayOrder?.toString() || "",
// });
// } catch (error) {
// console.error(error);
// toast.error("Failed to load menu");
// }
// };
// const isValidObjectId = (id) => /^[0-9a-fA-F]{24}$/.test(id);
// const onSubmit = async (formData) => {
// const cleanedData = {
// menuName: formData.menuName,
// menuCode: formData.menuCode,
// parentMenuId: isValidObjectId(formData.parentMenuId) ?
formData.parentMenuId : null,
// url: formData.url,
// icon: formData.icon,
// displayOrder: Number(formData.displayOrder),
// status: formData.status === "Active" ? "Active" : "Inactive",
// };
// try {
// const res = await menuapi.addMenuApi(cleanedData);
// toast.success("Menu created successfully!");
// router.push("/menumanagement");
// } catch (error) {
// console.error("Submit Error:", error?.response?.data || error);
// toast.error(error?.response?.data?.message || "An error occurred. Please
try again later.");
// }
// };
// // const selectedIconName = watch("icon");
// // const SelectedIcon = selectedIconName && MuiIcons[selectedIconName];
// const [selectedIconName, setSelectedIconName] = useState("");
// useEffect(() => {
// const iconFromForm = watch("icon");
// if (iconFromForm) {
// setSelectedIconName(iconFromForm);
// }
// }, [watch("icon")]);
// const SelectedIcon = selectedIconName && MuiIcons[selectedIconName];
// return (
// <Box component="main" sx={{ flexGrow: 1, py: 3 }}>
// <Container maxWidth={false}>
// <Box sx={{ mb: 4, display: "inline-block", width: "100%" }}>
// <Box sx={{ mb: 4 }}>
// <Link href="/menumanagement" passHref legacyBehavior>
// <Box
// component="a"
// sx={{
// display: "flex",
// alignItems: "center",
// textDecoration: "none",
// color: "text.primary",
// width: "fit-content",
// "&:hover": {
// textDecoration: "underline",
// color: "#60176F", // optional hover color
// },
// }}
// >
// <ArrowLeft fontSize="small" sx={{ mr: 1 }} />
// <Typography variant="subtitle2" sx={{ textDecoration:
"underline" }}>
// Back
// </Typography>
// </Box>
// </Link>
// </Box>
// <Grid container justifyContent="space-between" spacing={3}>
// <Grid item sx={{ alignItems: "center", display: "flex", overflow:
"hidden" }}>
// <Typography
// variant="h5"
// sx={{ color: "#60176F", fontWeight: 600, marginBottom: "3px" }}
// >
// {mode === "edit" ? "Edit Menu" : "Add New Menu"}
// </Typography>
// </Grid>
// </Grid>
// <Box
// component="form"
// onSubmit={handleSubmit(onSubmit)}
// sx={{
// mt: 3,
// P: 3,
// width: "100%",
// maxWidth: { xs: "100%", md: "100%" },
// mx: "auto",
// }}
// >
// <Grid container spacing={3}>
// <Grid item xs={12} sm={6}>
// <TextField
// label="MENU NAME"
// fullWidth
// {...register("menuName", { required: true })}
// error={!!errors.menuName}
// helperText={errors.menuName && "Menu name is required"}
// />
// </Grid>
// <Grid item xs={12} sm={6}>
// <TextField
// label="MENU CODE"
// fullWidth
// {...register("menuCode", { required: true })}
// error={!!errors.menuCode}
// helperText={errors.menuCode && "Menu code is required"}
// />
// </Grid>
// <Grid item xs={12} sm={6}>
// <Controller
// name="parentMenuId"
// control={control}
// render={({ field }) => (
// <TextField
// {...field}
// label="PARENT MENU"
// fullWidth
// select
// value={field.value || ""}
// onChange={(e) => {
// field.onChange(e.target.value);
// }}
// error={!!errors.parentMenuId}
// helperText={errors.parentMenuId?.message}
// >
// <MenuItem value="">
// <em>No Parent Menu</em>
// </MenuItem>
// {allMenus.map((menu) => (
// <MenuItem key={menu.id} value={menu.id}>
// {menu.menuName}
// </MenuItem>
// ))}
// </TextField>
// )}
// />
// </Grid>
// <Grid item xs={12} sm={6}>
// <TextField
// label="URL"
// fullWidth
// {...register("url", { required: "URL is required" })}
// error={!!errors.url}
// helperText={errors.url && "URL is required"}
// />
// </Grid>
// {/* <Grid item xs={12} sm={6}>
// <Autocomplete
// options={availableIcons}
// fullWidth
// renderInput={(params) => (
// <TextField
// {...params}
// label="ICON"
// error={!!errors.icon}
// helperText={errors.icon && "Icon is required"}
// />
// )}
// renderOption={(props, option) => (
// <li {...props} style={{ display: 'flex', alignItems:
'center', gap: '8px' }}>
// <DynamicMuiIcon iconName={option} />
// <span>{option}</span>
// </li>
// )}
// value={selectedIconName || ""}
// onChange={(_, newValue) => setValue("icon", newValue || "")}
// {...register("icon", { required: "Icon is required" })}
// />
// {SelectedIcon && (
// <Box mt={1}>
// <SelectedIcon fontSize="large" />
// </Box>
// )}
// </Grid> */}
// {/* <Grid item xs={12} sm={6}>
// <Autocomplete
// options={availableIcons}
// fullWidth
// value={selectedIconName || ""}
// onChange={(_, newValue) => {
// setSelectedIconName(newValue || "");
// setValue("icon", newValue || "",
{ shouldValidate: true }); // Update form state
// }}
// renderInput={(params) => (
// <TextField
// {...params}
// label="ICON"
// error={!!errors.icon}
// helperText={errors.icon && "Icon is
required"}
// {...register("icon", { required:
"Icon is required" })}
// />
// )}
// renderOption={(props, option) => (
// <li {...props} style={{ display: "flex",
alignItems: "center", gap: "8px" }}>
// <DynamicMuiIcon iconName={option} />
// <span>{option}</span>
// </li>
// )}
// />
// {selectedIconName && (
// <Box mt={1} display="flex"
alignItems="center" gap="8px">
// <DynamicMuiIcon
iconName={selectedIconName} fontSize="large" />
// <span>{selectedIconName}</span>
// </Box>
// )}
// </Grid> */}
// <Grid item xs={12} sm={6}>
// <Controller
// name="icon"
// control={control}
// rules={{ required: "Icon is required" }}
// render={({ field }) => (
// <Autocomplete
// options={availableIcons}
// fullWidth
// value={field.value || ""}
// onChange={(_, value) => field.onChange(value)}
// renderOption={(props, option) => (
// <li
// {...props}
// style={{ display: "flex", alignItems: "center", gap:
"8px" }}
// >
// <DynamicMuiIcon iconName={option} />
// {option}
// </li>
// )}
// renderInput={(params) => (
// <TextField
// {...params}
// label="ICON"
// error={!!errors.icon}
// helperText={errors.icon?.message}
// InputProps={{
// ...params.InputProps,
// startAdornment: selectedIconName ? (
// <Box sx={{ mr: 1, display: "flex", alignItems:
"center" }}>
// <DynamicMuiIcon iconName={selectedIconName} />
// </Box>
// ) : null,
// }}
// />
// )}
// />
// )}
// />
// </Grid>
// <Grid item xs={12} sm={6}>
// <TextField
// label="DISPLAY ORDER"
// fullWidth
// {...register("displayOrder", { required: true })}
// error={!!errors.displayOrder}
// helperText={errors.displayOrder && "Display order is
required"}
// />
// </Grid>
// <Grid item xs={12} sm={6}>
// <TextField
// select
// label="STATUS"
// fullWidth
// defaultValue="Y"
// {...register("status", { required: "Status is required" })}
// error={!!errors.status}
// helperText={errors.status && "Status is required"}
// >
// <MenuItem value="Y">Active</MenuItem>
// <MenuItem value="N">Inactive</MenuItem>
// </TextField>
// </Grid>
// </Grid>
// <Box sx={{ display: "flex", mt: 3 }}>
// <Button type="submit" variant="contained" sx={{ marginRight:
"10px" }}>
// {mode === "edit" ? "Save Changes" : "Add Menu"}
// </Button>
// <Button
// variant="outlined"
// onClick={() => router.push("/menumanagement")}
// sx={{ color: "#60176F", borderColor: "#60176F" }}
// >
// Cancel
// </Button>
// </Box>
// </Box>
// </Box>
// </Container>
// </Box>
// );
// };
// MenuForm.getLayout = (page) => <DashboardLayout>{page}</DashboardLayout>;
// export default MenuForm;
import {
Box,
Button,
Grid,
Container,
MenuItem,
SvgIcon,
TextField,
Typography,
Autocomplete,
} from "@mui/material";
import { useForm, Controller } from "react-hook-form";
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import NextLink from "next/link";
import { toast } from "react-toastify";
import menuapi from "src/services/api/menu";
import * as MuiIcons from "@mui/icons-material";
import availableIcons from "src/static/icons";
import Link from "next/link";
import { Layout as DashboardLayout } from "src/layouts/dashboard/layout";
import { ArrowLeft } from "src/Icons/ArrowLeft";
const DynamicMuiIcon = ({ iconName }) => {
if (!iconName) return null;
const IconComponent = MuiIcons[iconName];
return IconComponent ? (
<IconComponent fontSize="small" />
) : (
<span title="Icon not found">❓</span>
);
};
const defaultValues = {
menuName: "",
menuCode: "",
parentMenuId: "",
url: "",
icon: "",
displayOrder: "",
status: "Active",
};
const MenuForm = () => {
const {
register,
handleSubmit,
reset,
watch,
setValue,
control,
formState: { errors },
} = useForm({ defaultValues });
const [allMenus, setAllMenus] = useState([]);
const router = useRouter();
const { mode = "add", id } = router.query;
useEffect(() => {
fetchAllMenus();
if (mode === "edit" && id) {
fetchMenuDetails();
}
}, [id, mode]);
const fetchAllMenus = async () => {
try {
const res = await menuapi.getAllMenuApi();
setAllMenus(res.data.data || []);
} catch (error) {
toast.error("Failed to load menus");
}
};
const fetchMenuDetails = async () => {
try {
const res = await menuapi.getMenuById(id);
const data = res.data.data;
reset({
...data,
parentMenuId: data.parentMenuId?.toString() || "",
status: data.status || "Active",
displayOrder: data.displayOrder?.toString() || "",
});
} catch (error) {
console.error(error);
toast.error("Failed to load menu");
}
};
const isValidObjectId = (id) => /^[0-9a-fA-F]{24}$/.test(id);
const onSubmit = async (formData) => {
const cleanedData = {
menuName: formData.menuName,
menuCode: formData.menuCode,
parentMenuId: isValidObjectId(formData.parentMenuId) ?
formData.parentMenuId : null,
url: formData.url,
icon: formData.icon,
displayOrder: Number(formData.displayOrder),
status: formData.status === "Active" ? "Active" : "Inactive",
};
try {
if (mode === "edit" && id) {
await menuapi.updateMenuApi(id, cleanedData);
toast.success("Menu updated successfully!");
} else {
await menuapi.addMenuApi(cleanedData);
toast.success("Menu created successfully!");
}
router.push("/menumanagement");
} catch (error) {
console.error("Submit Error:", error?.response?.data || error);
toast.error(error?.response?.data?.message || "An error occurred. Please try
again later.");
}
};
const [selectedIconName, setSelectedIconName] = useState("");
useEffect(() => {
const subscription = watch((value, { name }) => {
if (name === "icon") {
setSelectedIconName(value.icon || "");
}
});
return () => subscription.unsubscribe();
}, [watch]);
return (
<Box component="main" sx={{ flexGrow: 1, py: 3 }}>
<Container maxWidth={false}>
<Box sx={{ mb: 4, display: "inline-block", width: "100%" }}>
<Box sx={{ mb: 4 }}>
<Link href="/menumanagement" passHref legacyBehavior>
<Box
component="a"
sx={{
display: "flex",
alignItems: "center",
textDecoration: "none",
color: "text.primary",
width: "fit-content",
"&:hover": {
textDecoration: "underline",
color: "#60176F",
},
}}
>
<ArrowLeft fontSize="small" sx={{ mr: 1 }} />
<Typography variant="subtitle2" sx={{ textDecoration:
"underline" }}>
Back
</Typography>
</Box>
</Link>
</Box>
<Grid container justifyContent="space-between" spacing={3}>
<Grid item sx={{ alignItems: "center", display: "flex", overflow:
"hidden" }}>
<Typography
variant="h5"
sx={{ color: "#60176F", fontWeight: 600, marginBottom: "3px" }}
>
{mode === "edit" ? "Edit Menu" : "Add New Menu"}
</Typography>
</Grid>
</Grid>
<Box
component="form"
onSubmit={handleSubmit(onSubmit)}
sx={{
mt: 3,
p: 3,
width: "100%",
maxWidth: { xs: "100%", md: "100%" },
mx: "auto",
}}
>
<Grid container spacing={3}>
<Grid item xs={12} sm={6}>
<TextField
label="MENU NAME"
fullWidth
{...register("menuName", { required: "Menu name is required" })}
error={!!errors.menuName}
helperText={errors.menuName?.message}
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
label="MENU CODE"
fullWidth
{...register("menuCode", { required: "Menu code is required" })}
error={!!errors.menuCode}
helperText={errors.menuCode?.message}
/>
</Grid>
{/* <Grid item xs={12} sm={6}>
<Controller
name="parentMenuId"
control={control}
render={({ field }) => (
<TextField
label="PARENT MENU Name"
fullWidth
select
{...field}
value={field.value || ""} // Ensure this is always a string
onChange={(event) => field.onChange(event.target.value)}
error={!!errors.parentMenuId}
helperText={errors.parentMenuId?.message || ""}
>
<MenuItem value="">
<em>None</em>
</MenuItem>
{allMenus.map((menu) => (
<MenuItem key={menu.id} value={menu.id ? menu.id.toString() : ""}>
{menu.menuName || "Unnamed Menu"}
</MenuItem>
))}
</TextField>
)}
/>
</Grid> */}
<Grid item xs={12} sm={6}>
<Controller
name="parentMenuId"
control={control}
render={({ field }) => (
<TextField
label="PARENT MENU NAME"
fullWidth
select
{...field}
value={field.value || ""}
onChange={(event) => field.onChange(event.target.value)}
error={!!errors.parentMenuId}
helperText={errors.parentMenuId?.message || ""}
>
<MenuItem value="">
<em>None</em>
</MenuItem>
{allMenus.map((menu) => (
<MenuItem key={menu._id} value={menu._id}>
{menu.menuName}
</MenuItem>
))}
</TextField>
)}
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
label="URL"
fullWidth
{...register("url")}
error={!!errors.url}
helperText={errors.url?.message}
/>
</Grid>
<Grid item xs={12} sm={6}>
<Controller
name="icon"
control={control}
rules={{ required: "Icon is required" }}
render={({ field }) => (
<Autocomplete
options={availableIcons}
fullWidth
value={field.value || ""}
onChange={(_, value) => {
field.onChange(value);
setSelectedIconName(value || "");
}}
renderOption={(props, option) => (
<li
{...props}
style={{ display: "flex", alignItems: "center", gap:
"8px" }}
>
<DynamicMuiIcon iconName={option} />
{option}
</li>
)}
renderInput={(params) => (
<TextField
{...params}
label="ICON"
error={!!errors.icon}
helperText={errors.icon?.message}
InputProps={{
...params.InputProps,
startAdornment: selectedIconName ? (
<Box sx={{ mr: 1, display: "flex", alignItems:
"center" }}>
<DynamicMuiIcon iconName={selectedIconName} />
</Box>
) : null,
}}
/>
)}
/>
)}
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
label="DISPLAY ORDER"
fullWidth
type="number"
{...register("displayOrder", {
required: "Display order is required",
valueAsNumber: true,
})}
error={!!errors.displayOrder}
helperText={errors.displayOrder?.message}
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
select
label="STATUS"
fullWidth
{...register("status", { required: "Status is required" })}
error={!!errors.status}
helperText={errors.status?.message}
>
<MenuItem value="Active">Active</MenuItem>
<MenuItem value="Inactive">Inactive</MenuItem>
</TextField>
</Grid>
</Grid>
<Box sx={{ display: "flex", mt: 3 }}>
<Button type="submit" variant="contained" sx={{ marginRight:
"10px" }}>
{mode === "edit" ? "Save Changes" : "Add Menu"}
</Button>
<Button
variant="outlined"
onClick={() => router.push("/menumanagement")}
sx={{ color: "#60176F", borderColor: "#60176F" }}
>
Cancel
</Button>
</Box>
</Box>
</Box>
</Container>
</Box>
);
};
MenuForm.getLayout = (page) => <DashboardLayout>{page}</DashboardLayout>;
export default MenuForm;