feat: edit and delete option for super admin

This commit is contained in:
deepvasoya 2025-05-22 14:42:43 +05:30
parent a17366037b
commit 34bec707ca
7 changed files with 623 additions and 130 deletions

View File

@ -81,3 +81,23 @@ export const resetPassword = (data) => {
.catch((err) => reject(err)); .catch((err) => reject(err));
}); });
}; };
export const updateAdmin = (data, id) => {
const url = `/admin/user/${id}`;
return new Promise((resolve, reject) => {
axiosInstance
.put(url, data)
.then((response) => resolve(response))
.catch((err) => reject(err));
});
};
export const deleteAdmin = (id) => {
const url = `/admin/user/${id}`;
return new Promise((resolve, reject) => {
axiosInstance
.delete(url)
.then((response) => resolve(response))
.catch((err) => reject(err));
});
};

View File

@ -111,8 +111,8 @@ export const getClinicOffer = (params) => {
}); });
}; };
export const updateClinicOffer = (data) => { export const updateClinicOffer = (data, id) => {
const url = `/admin/clinic/offer`; const url = `/admin/clinic/offer/${id}`;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
axiosInstance axiosInstance
.put(url, data) .put(url, data)

View File

@ -24,8 +24,8 @@ export const setMasterData = (data) => {
}); });
}; };
export const updateMasterData = (data) => { export const updateMasterData = (data, id) => {
const url = "/admin/master-data"; const url = `/admin/master-data/${id}`;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
axiosInstance axiosInstance
.put(url, data) .put(url, data)
@ -33,3 +33,13 @@ export const updateMasterData = (data) => {
.catch((err) => reject(err)); .catch((err) => reject(err));
}); });
}; };
export const deleteMasterData = (id) => {
const url = `/admin/master-data/${id}`;
return new Promise((resolve, reject) => {
axiosInstance
.delete(url)
.then((response) => resolve(response))
.catch((err) => reject(err));
});
};

View File

@ -107,7 +107,9 @@ function Dashboard() {
const clinicAdmin = ( const clinicAdmin = (
<Box> <Box>
<ThankYou isActive={isActive} canClose={false} /> {!isActive && (
<ThankYou canClose={false} />
)}
<Box> <Box>
<Box> <Box>
<Box className={classes.dashboardTitleBox}> <Box className={classes.dashboardTitleBox}>

View File

@ -1,5 +1,6 @@
import AddIcon from "@mui/icons-material/Add"; import AddIcon from "@mui/icons-material/Add";
import DescriptionIcon from '@mui/icons-material/Description'; import EditIcon from "@mui/icons-material/Edit";
import DeleteIcon from "@mui/icons-material/Delete";
import CloseIcon from "@mui/icons-material/Close"; import CloseIcon from "@mui/icons-material/Close";
import PersonAddIcon from "@mui/icons-material/PersonAdd"; import PersonAddIcon from "@mui/icons-material/PersonAdd";
import { import {
@ -21,16 +22,24 @@ import { pushNotification } from "../../utils/notification";
import { NOTIFICATION } from "../../constants"; import { NOTIFICATION } from "../../constants";
import { useStyles } from "./masterDataStyles"; import { useStyles } from "./masterDataStyles";
import Table from "../../components/Table"; import Table from "../../components/Table";
import { getMasterData, setMasterData } from "../../services/masterData.services"; import {
getMasterData,
setMasterData,
updateMasterData,
deleteMasterData,
} from "../../services/masterData.services";
const MasterDataManagement = () => { const MasterDataManagement = () => {
const classes = useStyles(); const classes = useStyles();
const ref = useRef(null); const tableRef = useRef(null);
// State for form fields // State for form fields
const [type, setType] = useState(""); const [type, setType] = useState("");
const [editId, setEditId] = useState(null);
const [deleteId, setDeleteId] = useState(null);
// State for dialog // State for dialog
const [openDialog, setOpenDialog] = useState(false); const [openDialog, setOpenDialog] = useState(false);
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
// Handle dialog open/close // Handle dialog open/close
const handleOpenDialog = () => { const handleOpenDialog = () => {
@ -41,6 +50,38 @@ const MasterDataManagement = () => {
setOpenDialog(false); setOpenDialog(false);
// Clear form // Clear form
setType(""); setType("");
setEditId(null);
};
// Open delete confirmation dialog
const openDeleteConfirmation = (id) => {
setDeleteId(id);
setDeleteDialogOpen(true);
};
// Handle delete master data after confirmation
const handleDelete = async () => {
try {
const resp = await deleteMasterData(deleteId);
pushNotification(
"Appointment type deleted successfully",
NOTIFICATION.SUCCESS
);
} catch (error) {
console.error("Error deleting appointment type:", error);
pushNotification(
`Failed to delete appointment type`,
NOTIFICATION.ERROR
);
}
// Close the dialog and refresh the table
setDeleteDialogOpen(false);
setDeleteId(null);
if (tableRef.current) {
tableRef.current.reFetchData();
}
}; };
// Handle form submission // Handle form submission
@ -51,34 +92,49 @@ const MasterDataManagement = () => {
type, type,
}; };
const response = await setMasterData(payload); let resp;
if (response?.data?.data) { if (editId !== null) {
pushNotification("Master Data created successfully!", NOTIFICATION.SUCCESS); resp = await updateMasterData(payload, editId);
} else { } else {
pushNotification(response?.data?.message, NOTIFICATION.ERROR); resp = await setMasterData(payload);
}
if (resp?.data?.data) {
pushNotification(
"Master Data created successfully!",
NOTIFICATION.SUCCESS
);
} else {
pushNotification(resp?.data?.message, NOTIFICATION.ERROR);
}
// Refresh the table data
if (tableRef.current) {
tableRef.current.reFetchData();
} }
// Close dialog // Close dialog
handleCloseDialog(); handleCloseDialog();
setEditId(null);
}; };
const getData = async (filters) => { const getData = async (filters) => {
try { try {
// Remove the type parameter since it's not defined // Remove the type parameter since it's not defined
let params = { let params = {
...filters ...filters,
}; };
const resp = await getMasterData(params); const resp = await getMasterData(params);
console.log('API Response:', resp); console.log("API Response:", resp);
return { return {
data: resp?.data?.data?.data, data: resp?.data?.data?.data,
rowCount: resp?.data?.data?.total || 0, rowCount: resp?.data?.data?.total || 0,
}; };
} catch (error) { } catch (error) {
console.error('Error fetching admins:', error); console.error("Error fetching admins:", error);
return { return {
data: [], data: [],
rowCount: 0, rowCount: 0,
@ -86,6 +142,12 @@ const MasterDataManagement = () => {
} }
}; };
const handleEdit = async (row) => {
setEditId(row.original.id); // Store the ID for update operation
setType(row.original.type);
setOpenDialog(true);
};
// ...................breadcrumbs array........................ // ...................breadcrumbs array........................
const breadcrumbs = [ const breadcrumbs = [
{ {
@ -121,7 +183,7 @@ const MasterDataManagement = () => {
accessorKey: "type", accessorKey: "type",
header: "Type", header: "Type",
enableColumnFilter: false, enableColumnFilter: false,
} },
// Removed the empty object that was causing the error // Removed the empty object that was causing the error
]); ]);
@ -147,23 +209,20 @@ const MasterDataManagement = () => {
}} }}
searchText="Master Data" searchText="Master Data"
showSearchBox={true} showSearchBox={true}
ref={ref} showAction={true}
// actions={[ ref={tableRef}
// { actions={[
// onClick: (row) => { {
onClick: (row) => handleEdit(row),
// }, text: "Edit",
// text: "Remove", icon: <EditIcon alt="Edit" />,
// icon: ( },
// <DescriptionIcon /> {
// // <img onClick: (row) => openDeleteConfirmation(row.original.id),
// // src={TransactionHistoryIcon} text: "Delete",
// // className={classes.tableActionIcons} icon: <DeleteIcon alt="Delete" />,
// // alt="transaction history" },
// // /> ]}
// ),
// },
// ]}
/> />
</Box> </Box>
</Box> </Box>
@ -173,26 +232,34 @@ const MasterDataManagement = () => {
onClose={handleCloseDialog} onClose={handleCloseDialog}
maxWidth="sm" maxWidth="sm"
fullWidth fullWidth
PaperProps={{
sx: {
borderRadius: "12px",
overflow: "hidden",
},
}}
> >
<DialogTitle <DialogTitle
sx={{ sx={{
display: "flex", padding: "16px 24px",
alignItems: "center", backgroundColor: (theme) => theme.palette.primary.main,
justifyContent: "space-between", color: "white",
pb: 1, fontWeight: "bold",
position: "relative",
}} }}
> >
<Box sx={{ display: "flex", alignItems: "center" }}> {editId !== null
<PersonAddIcon sx={{ mr: 1, color: "#0a2d6b" }} /> ? "Edit Appointment Type"
<Typography : "Add New Appointment Type"}
variant="h6" <IconButton
component="span" onClick={handleCloseDialog}
sx={{ fontWeight: "bold", color: "#0a2d6b" }} sx={{
position: "absolute",
right: 8,
top: 8,
color: "white",
}}
> >
Add Appointment Type
</Typography>
</Box>
<IconButton onClick={handleCloseDialog} size="small">
<CloseIcon /> <CloseIcon />
</IconButton> </IconButton>
</DialogTitle> </DialogTitle>
@ -230,10 +297,87 @@ const MasterDataManagement = () => {
}, },
}} }}
> >
Add Appointment Type {editId !== null
? "Update Appointment Type"
: "Add Appointment Type"}
</Button> </Button>
</DialogActions> </DialogActions>
</Dialog> </Dialog>
{/* Delete Confirmation Dialog */}
<Dialog
open={deleteDialogOpen}
onClose={() => setDeleteDialogOpen(false)}
maxWidth="xs"
fullWidth
PaperProps={{
sx: {
borderRadius: "12px",
overflow: "hidden",
},
}}
>
<DialogTitle
sx={{
padding: "16px 24px",
backgroundColor: (theme) => theme.palette.error.main,
color: "white",
fontWeight: "bold",
position: "relative",
}}
>
Confirm Deletion
<IconButton
aria-label="close"
onClick={() => setDeleteDialogOpen(false)}
sx={{
position: "absolute",
right: 8,
top: 8,
color: "white",
}}
>
<CloseIcon />
</IconButton>
</DialogTitle>
<DialogContent sx={{ padding: "24px 24px 16px", mt: 1 }}>
<Typography variant="body1">
Are you sure you want to delete this appointment type? This action cannot be undone.
</Typography>
</DialogContent>
<DialogActions
sx={{
padding: "16px 24px",
borderTop: "1px solid",
borderColor: (theme) => theme.palette.grey[200],
justifyContent: "space-between",
}}
>
<Button
onClick={() => setDeleteDialogOpen(false)}
sx={{
color: (theme) => theme.palette.grey[700],
fontWeight: "medium",
}}
>
Cancel
</Button>
<Button
onClick={handleDelete}
variant="contained"
color="error"
sx={{
borderRadius: "8px",
px: 3,
}}
>
Delete
</Button>
</DialogActions>
</Dialog>
</Box> </Box>
</Box> </Box>
); );

View File

@ -1,5 +1,6 @@
import AddIcon from "@mui/icons-material/Add"; import AddIcon from "@mui/icons-material/Add";
import EditIcon from "@mui/icons-material/Edit"; import EditIcon from "@mui/icons-material/Edit";
import DeleteIcon from "@mui/icons-material/Delete";
import CloseIcon from "@mui/icons-material/Close"; import CloseIcon from "@mui/icons-material/Close";
import { import {
Box, Box,
@ -28,12 +29,13 @@ import { NOTIFICATION } from "../../constants";
import { emailRegex } from "../../utils/regex"; import { emailRegex } from "../../utils/regex";
import { import {
createClinicOffer, createClinicOffer,
deleteClinicOffer,
getClinicOffer, getClinicOffer,
updateClinicOffer,
} from "../../services/clinics.service"; } from "../../services/clinics.service";
const PaymentManagement = () => { const PaymentManagement = () => {
const classes = useStyles(); const classes = useStyles();
const ref = useRef(null);
const tableRef = useRef(null); const tableRef = useRef(null);
// State for payment dialog // State for payment dialog
@ -46,10 +48,11 @@ const PaymentManagement = () => {
}); });
// State for payments list // State for payments list
const [paymentsList, setPaymentsList] = useState([]); const [editPaymentId, setEditPaymentId] = useState(null);
const [editPaymentIndex, setEditPaymentIndex] = useState(null);
const handleSubmit = () => {}; // State for delete confirmation dialog
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
const [deletePaymentId, setDeletePaymentId] = useState(null);
const columns = useMemo(() => [ const columns = useMemo(() => [
{ {
@ -98,7 +101,6 @@ const PaymentManagement = () => {
}; };
const resp = await getClinicOffer(params); const resp = await getClinicOffer(params);
console.log("API Response:", resp);
return { return {
data: resp?.data?.data?.data, data: resp?.data?.data?.data,
@ -113,7 +115,7 @@ const PaymentManagement = () => {
} }
}; };
// Handle payment dialog submission // Handle payment dialog submission (both add and update)
const handleAddPayment = async () => { const handleAddPayment = async () => {
// Validate input // Validate input
if (!paymentData.clinicEmail.trim()) { if (!paymentData.clinicEmail.trim()) {
@ -143,8 +145,14 @@ const PaymentManagement = () => {
: "0", : "0",
}; };
try {
if (editPaymentId !== null) {
const resp = await updateClinicOffer(payload, editPaymentId);
}
else{
const resp = await createClinicOffer(payload); const resp = await createClinicOffer(payload);
console.log("API Response:", resp); }
// Reset form and close dialog // Reset form and close dialog
setPaymentData({ setPaymentData({
@ -153,33 +161,81 @@ const PaymentManagement = () => {
specialOffer: false, specialOffer: false,
configurationMonth: 3, configurationMonth: 3,
}); });
setEditPaymentIndex(null); setEditPaymentId(null);
setPaymentDialogOpen(false); setPaymentDialogOpen(false);
// Refresh the table data // Refresh the table data
if (tableRef.current) { if (tableRef.current) {
tableRef.current.reFetchData(); tableRef.current.reFetchData();
pushNotification("Payment configuration added successfully", NOTIFICATION.SUCCESS); pushNotification(
`Payment configuration ${editPaymentId !== null ? 'updated' : 'added'} successfully`,
NOTIFICATION.SUCCESS
);
}
} catch (error) {
console.error("Error saving payment configuration:", error);
pushNotification(
`Failed to ${editPaymentId !== null ? 'update' : 'add'} payment configuration`,
NOTIFICATION.ERROR
);
} }
}; };
// Handle edit payment // Handle edit payment
const handleEditPayment = (index) => { const handleEditPayment = (rowData) => {
setEditPaymentIndex(index); // Convert the data from API format to form format
setPaymentData({ ...paymentsList[index] }); const formattedData = {
clinicEmail: rowData.original.clinic_email,
setupFeeWaived: rowData.original.setup_fees_waived,
specialOffer: rowData.original.special_offer_for_month !== "0",
configurationMonth: rowData.original.special_offer_for_month !== "0" ? parseInt(rowData.original.special_offer_for_month) : 3,
};
setEditPaymentId(rowData.original.id); // Store the ID for update operation
setPaymentData(formattedData);
setPaymentDialogOpen(true); setPaymentDialogOpen(true);
}; };
// Handle delete payment // Open delete confirmation dialog
const handleDeletePayment = (index) => { const openDeleteConfirmation = (id) => {
const updatedPayments = [...paymentsList]; setDeletePaymentId(id);
updatedPayments.splice(index, 1); setDeleteDialogOpen(true);
setPaymentsList(updatedPayments); };
const handleDialog = () => {
setPaymentDialogOpen(!paymentDialogOpen);
setPaymentData({
clinicEmail: "",
setupFeeWaived: false,
specialOffer: false,
configurationMonth: 3,
});
setEditPaymentId(null);
};
// Handle delete payment after confirmation
const handleDeletePayment = async () => {
try {
const resp = await deleteClinicOffer(deletePaymentId);
pushNotification( pushNotification(
"Payment configuration deleted successfully", "Payment configuration deleted successfully",
NOTIFICATION.SUCCESS NOTIFICATION.SUCCESS
); );
} catch (error) {
console.error("Error deleting payment configuration:", error);
pushNotification(
`Failed to delete payment configuration`,
NOTIFICATION.ERROR
);
}
// Close the dialog and refresh the table
setDeleteDialogOpen(false);
setDeletePaymentId(null);
if (tableRef.current) {
tableRef.current.reFetchData();
}
}; };
// Breadcrumbs // Breadcrumbs
@ -194,7 +250,7 @@ const PaymentManagement = () => {
<PageHeader <PageHeader
pageTitle="Payment Management" pageTitle="Payment Management"
addButtonIcon={<AddIcon />} addButtonIcon={<AddIcon />}
onAddButtonClick={() => setPaymentDialogOpen(true)} onAddButtonClick={handleDialog}
/> />
<CustomBreadcrumbs breadcrumbs={breadcrumbs} /> <CustomBreadcrumbs breadcrumbs={breadcrumbs} />
<Box className={classes.tableMainDiv}> <Box className={classes.tableMainDiv}>
@ -209,13 +265,19 @@ const PaymentManagement = () => {
showTopBar: false, showTopBar: false,
showFilters: true, showFilters: true,
}} }}
showAction={true}
searchText="Staff" searchText="Staff"
showSearchBox={true} showSearchBox={true}
actions={[ actions={[
{ {
onClick: (row) => handleEditPayment(row), onClick: (row) => handleEditPayment(row),
text: "Edit", text: "Edit",
icon: <EditIcon />, icon: (<EditIcon alt="Edit" />),
},
{
onClick: (row) => openDeleteConfirmation(row.original.id),
text: "Delete",
icon: (<DeleteIcon alt="Delete" />),
}, },
]} ]}
/> />
@ -225,7 +287,7 @@ const PaymentManagement = () => {
{/* Improved Dialog Box */} {/* Improved Dialog Box */}
<Dialog <Dialog
open={paymentDialogOpen} open={paymentDialogOpen}
onClose={() => setPaymentDialogOpen(false)} onClose={handleDialog}
maxWidth="sm" maxWidth="sm"
fullWidth fullWidth
PaperProps={{ PaperProps={{
@ -244,12 +306,12 @@ const PaymentManagement = () => {
position: "relative", position: "relative",
}} }}
> >
{editPaymentIndex !== null {editPaymentId !== null
? "Edit Payment Configuration" ? "Edit Payment Configuration"
: "Add New Payment"} : "Add New Payment"}
<IconButton <IconButton
aria-label="close" aria-label="close"
onClick={() => setPaymentDialogOpen(false)} onClick={handleDialog}
sx={{ sx={{
position: "absolute", position: "absolute",
right: 8, right: 8,
@ -262,7 +324,7 @@ const PaymentManagement = () => {
</DialogTitle> </DialogTitle>
<DialogContent sx={{ padding: "24px 24px 16px" }}> <DialogContent sx={{ padding: "24px 24px 16px" }}>
<Box component="form" onSubmit={handleSubmit} sx={{ mt: 1 }}> <Box component="form" sx={{ mt: 1 }}>
<Typography variant="subtitle2" gutterBottom sx={{ mb: 1 }}> <Typography variant="subtitle2" gutterBottom sx={{ mb: 1 }}>
Clinic Information Clinic Information
</Typography> </Typography>
@ -405,7 +467,81 @@ const PaymentManagement = () => {
px: 3, px: 3,
}} }}
> >
{editPaymentIndex !== null ? "Update" : "Save"} {editPaymentId !== null ? "Update" : "Save"}
</Button>
</DialogActions>
</Dialog>
{/* Delete Confirmation Dialog */}
<Dialog
open={deleteDialogOpen}
onClose={() => setDeleteDialogOpen(false)}
maxWidth="xs"
fullWidth
PaperProps={{
sx: {
borderRadius: "12px",
overflow: "hidden",
},
}}
>
<DialogTitle
sx={{
padding: "16px 24px",
backgroundColor: (theme) => theme.palette.error.main,
color: "white",
fontWeight: "bold",
position: "relative",
}}
>
Confirm Deletion
<IconButton
aria-label="close"
onClick={() => setDeleteDialogOpen(false)}
sx={{
position: "absolute",
right: 8,
top: 8,
color: "white",
}}
>
<CloseIcon />
</IconButton>
</DialogTitle>
<DialogContent sx={{ padding: "24px 24px 16px", mt: 1 }}>
<Typography variant="body1">
Are you sure you want to delete this payment configuration? This action cannot be undone.
</Typography>
</DialogContent>
<DialogActions
sx={{
padding: "16px 24px",
borderTop: "1px solid",
borderColor: (theme) => theme.palette.grey[200],
justifyContent: "space-between",
}}
>
<Button
onClick={() => setDeleteDialogOpen(false)}
sx={{
color: (theme) => theme.palette.grey[700],
fontWeight: "medium",
}}
>
Cancel
</Button>
<Button
onClick={handleDeletePayment}
variant="contained"
color="error"
sx={{
borderRadius: "8px",
px: 3,
}}
>
Delete
</Button> </Button>
</DialogActions> </DialogActions>
</Dialog> </Dialog>

View File

@ -1,4 +1,6 @@
import AddIcon from "@mui/icons-material/Add"; import AddIcon from "@mui/icons-material/Add";
import EditIcon from "@mui/icons-material/Edit";
import DeleteIcon from "@mui/icons-material/Delete";
import CloseIcon from "@mui/icons-material/Close"; import CloseIcon from "@mui/icons-material/Close";
import PersonAddIcon from "@mui/icons-material/PersonAdd"; import PersonAddIcon from "@mui/icons-material/PersonAdd";
import { import {
@ -16,7 +18,7 @@ import {
import React, { useMemo, useRef, useState } from "react"; import React, { useMemo, useRef, useState } from "react";
import CustomBreadcrumbs from "../../components/CustomBreadcrumbs"; import CustomBreadcrumbs from "../../components/CustomBreadcrumbs";
import PageHeader from "../../components/PageHeader"; import PageHeader from "../../components/PageHeader";
import { createAdmin, getAdmins } from "../../services/auth.services"; import { createAdmin, getAdmins, updateAdmin, deleteAdmin } from "../../services/auth.services";
import { pushNotification } from "../../utils/notification"; import { pushNotification } from "../../utils/notification";
import { NOTIFICATION } from "../../constants"; import { NOTIFICATION } from "../../constants";
import { useStyles } from "./staffStyles"; import { useStyles } from "./staffStyles";
@ -25,15 +27,23 @@ import Table from "../../components/Table";
const StaffManagement = () => { const StaffManagement = () => {
const classes = useStyles(); const classes = useStyles();
const ref = useRef(null); const ref = useRef(null);
const tableRef = useRef(null);
// State for form fields // State for form fields
const [firstName, setFirstName] = useState(""); const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState(""); const [lastName, setLastName] = useState("");
const [email, setEmail] = useState(""); const [email, setEmail] = useState("");
const [emailError, setEmailError] = useState(""); const [emailError, setEmailError] = useState("");
const [isEditMode, setIsEditMode] = useState(false);
const [editId, setEditId] = useState(null);
// State for dialog // State for dialog
const [openDialog, setOpenDialog] = useState(false); const [openDialog, setOpenDialog] = useState(false);
// State for delete confirmation dialog
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
const [deleteId, setDeleteId] = useState(null);
// Email validation function // Email validation function
const validateEmail = (email) => { const validateEmail = (email) => {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
@ -52,27 +62,52 @@ const StaffManagement = () => {
setLastName(""); setLastName("");
setEmail(""); setEmail("");
setEmailError(""); setEmailError("");
setIsEditMode(false);
setEditId(null);
}; };
// Handle form submission // Handle form submission
const handleSubmit = async (e) => { const handleSubmit = async (e) => {
e.preventDefault(); e.preventDefault();
// For edit mode, only username is required
if (!isEditMode) {
// Validate email // Validate email
if (!validateEmail(email)) { if (!validateEmail(email)) {
setEmailError("Please enter a valid email address"); setEmailError("Please enter a valid email address");
return; return;
} }
}
let response;
if (isEditMode) {
// In edit mode, only update the username
const payload = {
username: `${firstName} ${lastName}`,
};
response = await updateAdmin(payload, editId);
} else {
// In create mode, include both username and email
const payload = { const payload = {
username: `${firstName} ${lastName}`, username: `${firstName} ${lastName}`,
email, email,
}; };
const response = await createAdmin(payload); response = await createAdmin(payload);
}
if (response?.data?.data) { if (response?.data?.data) {
pushNotification("Admin created successfully!", NOTIFICATION.SUCCESS); pushNotification(
`Admin ${isEditMode ? 'updated' : 'created'} successfully!`,
NOTIFICATION.SUCCESS
);
// Refresh the table
if (tableRef.current) {
tableRef.current.reFetchData();
}
} else { } else {
pushNotification(response?.data?.message, NOTIFICATION.ERROR); pushNotification(response?.data?.message, NOTIFICATION.ERROR);
} }
@ -85,18 +120,17 @@ const StaffManagement = () => {
try { try {
// Remove the type parameter since it's not defined // Remove the type parameter since it's not defined
let params = { let params = {
...filters ...filters,
}; };
const resp = await getAdmins(params); const resp = await getAdmins(params);
console.log('API Response:', resp);
return { return {
data: resp?.data?.data?.data, data: resp?.data?.data?.data,
rowCount: resp?.data?.total || 0, rowCount: resp?.data?.total || 0,
}; };
} catch (error) { } catch (error) {
console.error('Error fetching admins:', error); console.error("Error fetching admins:", error);
return { return {
data: [], data: [],
rowCount: 0, rowCount: 0,
@ -104,6 +138,52 @@ const StaffManagement = () => {
} }
}; };
const handleEdit = (row) => {
setIsEditMode(true);
setEditId(row.original.id);
// Split the username into first and last name
const nameParts = row.original.username.split(' ');
setFirstName(nameParts[0] || '');
setLastName(nameParts.slice(1).join(' ') || '');
// Set email but make it read-only in the form
setEmail(row.original.email);
setOpenDialog(true);
}
// Open delete confirmation dialog
const openDeleteConfirmation = (id) => {
setDeleteId(id);
setDeleteDialogOpen(true);
};
// Handle delete after confirmation
const handleDelete = async () => {
try {
const resp = await deleteAdmin(deleteId);
pushNotification(
"Admin deleted successfully",
NOTIFICATION.SUCCESS
);
} catch (error) {
console.error("Error deleting admin:", error);
pushNotification(
"Failed to delete admin",
NOTIFICATION.ERROR
);
}
// Close the dialog and refresh the table
setDeleteDialogOpen(false);
setDeleteId(null);
if (tableRef.current) {
tableRef.current.reFetchData();
}
};
// ...................breadcrumbs array........................ // ...................breadcrumbs array........................
const breadcrumbs = [ const breadcrumbs = [
{ {
@ -169,7 +249,20 @@ const StaffManagement = () => {
}} }}
searchText="Staff" searchText="Staff"
showSearchBox={true} showSearchBox={true}
ref={ref} showAction={true}
ref={tableRef}
actions={[
{
onClick: (row) => handleEdit(row),
text: "Edit",
icon: <EditIcon alt="Edit" />,
},
{
onClick: (row) => openDeleteConfirmation(row.original.id),
text: "Delete",
icon: <DeleteIcon alt="Delete" />,
},
]}
/> />
</Box> </Box>
</Box> </Box>
@ -195,7 +288,7 @@ const StaffManagement = () => {
component="span" component="span"
sx={{ fontWeight: "bold", color: "#0a2d6b" }} sx={{ fontWeight: "bold", color: "#0a2d6b" }}
> >
Add New Staff {isEditMode ? "Edit Staff" : "Add New Staff"}
</Typography> </Typography>
</Box> </Box>
<IconButton onClick={handleCloseDialog} size="small"> <IconButton onClick={handleCloseDialog} size="small">
@ -233,6 +326,7 @@ const StaffManagement = () => {
}} }}
/> />
{!isEditMode ? (
<TextField <TextField
label="Email Address" label="Email Address"
fullWidth fullWidth
@ -251,6 +345,19 @@ const StaffManagement = () => {
shrink: true, shrink: true,
}} }}
/> />
) : (
<TextField
label="Email Address"
fullWidth
margin="normal"
type="email"
value={email}
disabled
InputLabelProps={{
shrink: true,
}}
/>
)}
</Box> </Box>
</DialogContent> </DialogContent>
@ -268,7 +375,81 @@ const StaffManagement = () => {
}, },
}} }}
> >
Add Admin {isEditMode ? "Update Admin" : "Add Admin"}
</Button>
</DialogActions>
</Dialog>
{/* Delete Confirmation Dialog */}
<Dialog
open={deleteDialogOpen}
onClose={() => setDeleteDialogOpen(false)}
maxWidth="xs"
fullWidth
PaperProps={{
sx: {
borderRadius: "12px",
overflow: "hidden",
},
}}
>
<DialogTitle
sx={{
padding: "16px 24px",
backgroundColor: (theme) => theme.palette.error.main,
color: "white",
fontWeight: "bold",
position: "relative",
}}
>
Confirm Deletion
<IconButton
aria-label="close"
onClick={() => setDeleteDialogOpen(false)}
sx={{
position: "absolute",
right: 8,
top: 8,
color: "white",
}}
>
<CloseIcon />
</IconButton>
</DialogTitle>
<DialogContent sx={{ padding: "24px 24px 16px", mt: 1 }}>
<Typography variant="body1">
Are you sure you want to delete this admin? This action cannot be undone.
</Typography>
</DialogContent>
<DialogActions
sx={{
padding: "16px 24px",
borderTop: "1px solid",
borderColor: (theme) => theme.palette.grey[200],
justifyContent: "space-between",
}}
>
<Button
onClick={() => setDeleteDialogOpen(false)}
sx={{
color: (theme) => theme.palette.grey[700],
fontWeight: "medium",
}}
>
Cancel
</Button>
<Button
onClick={handleDelete}
variant="contained"
color="error"
sx={{
borderRadius: "8px",
px: 3,
}}
>
Delete
</Button> </Button>
</DialogActions> </DialogActions>
</Dialog> </Dialog>