diff --git a/src/components/MenuContent/index.tsx b/src/components/MenuContent/index.tsx
index 794a33b..31207fd 100644
--- a/src/components/MenuContent/index.tsx
+++ b/src/components/MenuContent/index.tsx
@@ -13,10 +13,6 @@ import { RootState } from "../../redux/store/store";
import DashboardOutlinedIcon from "@mui/icons-material/DashboardOutlined";
import ManageAccountsOutlinedIcon from "@mui/icons-material/ManageAccountsOutlined";
-//Eknoor singh and Jaanvi
-//date:- 12-Feb-2025
-//Made a different variable for super admin to access all the details.
-
type PropType = {
hidden: boolean;
};
@@ -26,6 +22,7 @@ export default function MenuContent({ hidden }: PropType) {
const userRole = useSelector(
(state: RootState) => state.profileReducer.user?.userType
);
+
const baseMenuItems = [
{
text: "Dashboard",
@@ -37,19 +34,25 @@ export default function MenuContent({ hidden }: PropType) {
icon: ,
url: "/panel/admin-list",
},
- userRole === "admin" && {
- text: "Users",
- icon: ,
- url: "/panel/user-list",
- },
userRole === "superadmin" && {
text: "Roles",
icon: ,
url: "/panel/role-list",
},
+ userRole === "admin" && {
+ text: "Users",
+ icon: ,
+ url: "/panel/user-list",
+ },
+ userRole === "admin" && {
+ text: "Managers",
+ icon: ,
+ url: "/panel/manager-list", // Placeholder for now
+ },
];
const filteredMenuItems = baseMenuItems.filter(Boolean);
+
return (
@@ -59,7 +62,6 @@ export default function MenuContent({ hidden }: PropType) {
disablePadding
sx={{ display: "block", py: 1 }}
>
- {/* Wrap ListItemButton with Link to enable routing */}
);
-}
+}
\ No newline at end of file
diff --git a/src/components/Modals/ViewModal/ViewModal.tsx b/src/components/Modals/ViewModal/ViewModal.tsx
deleted file mode 100644
index 8a1df15..0000000
--- a/src/components/Modals/ViewModal/ViewModal.tsx
+++ /dev/null
@@ -1,82 +0,0 @@
-import { Box, Button, Modal, Typography } from "@mui/material";
-import { AppDispatch, RootState } from "../../../redux/store/store";
-import { useDispatch, useSelector } from "react-redux";
-import { useEffect, useState } from "react";
-
-type Props = {
- open: boolean;
- setViewModal: Function;
- handleView: (id: string | undefined) => void;
- id?: string | undefined;
-};
-;
-
-const style = {
- position: "absolute",
- top: "50%",
- left: "50%",
- transform: "translate(-50%, -50%)",
- width: 330,
- bgcolor: "background.paper",
- borderRadius: 1.5,
- boxShadow: 24,
- p: 3,
-};
-
-const btnStyle = { py: 1, px: 5, width: "50%", textTransform: "capitalize", alignItems: "center" };
-
-export default function ViewModal({
- open,
- setViewModal,
- id, // Selected user's ID
-}: Props) {
- const { admins } = useSelector((state: RootState) => state.adminReducer);
- const [selectedAdmin, setSelectedAdmin] = useState(null);
-
- useEffect(() => {
- if (id) {
- const admin = admins.find((admin) => admin.id === id);
- setSelectedAdmin(admin || null);
- }
- }, [id, admins]);
-
- return (
-
-
-
- Details of {selectedAdmin?.name}
-
- {selectedAdmin ? (
- <>
- Name: {selectedAdmin?.name}
- Email: {selectedAdmin?.email}
- Phone: {selectedAdmin?.phone}
- Address: {selectedAdmin?.registeredAddress}
- >
- ) : (
- No admin found with this ID
- )}
-
-
-
-
-
- );
-}
\ No newline at end of file
diff --git a/src/pages/AddManagerModal/index.tsx b/src/pages/AddManagerModal/index.tsx
new file mode 100644
index 0000000..b0d32f2
--- /dev/null
+++ b/src/pages/AddManagerModal/index.tsx
@@ -0,0 +1,126 @@
+import { useState } from "react";
+import {
+ Box,
+ Button,
+ Typography,
+ TextField,
+ Modal,
+ IconButton,
+} from "@mui/material";
+import CloseIcon from "@mui/icons-material/Close";
+
+export default function AddManagerModal({ open, handleClose, handleAddManager }) {
+ // State for input fields
+ const [managerName, setManagerName] = useState("");
+ const [stationName, setStationName] = useState("");
+ const [stationLocation, setStationLocation] = useState("");
+ const [phoneNumber, setPhoneNumber] = useState("");
+
+ const handleSubmit = () => {
+ if (!managerName || !stationName || !stationLocation || !phoneNumber) {
+ alert("Please fill all fields");
+ return;
+ }
+
+ const newManager = {
+ managerName,
+ stationName,
+ stationLocation,
+ phoneNumber,
+ };
+
+ handleAddManager(newManager); // Add manager to table
+ handleClose(); // Close modal after adding
+ };
+
+ return (
+
+
+ {/* Header */}
+
+
+ Add Managers
+
+
+
+
+
+
+ {/* Horizontal Line */}
+
+
+ {/* Input Fields */}
+
+ {/* First Row - Two Inputs */}
+
+
+ Manager Name
+ setManagerName(e.target.value)}
+ />
+
+
+
+ Station Name
+ setStationName(e.target.value)}
+ />
+
+
+
+ {/* Second Row - Two Inputs */}
+
+
+ Station Location
+ setStationLocation(e.target.value)}
+ />
+
+
+
+ Phone Number
+ setPhoneNumber(e.target.value)}
+ />
+
+
+
+
+ {/* Submit Button */}
+
+
+
+
+
+ );
+}
diff --git a/src/pages/EditUserModal/index.tsx b/src/pages/EditUserModal/index.tsx
new file mode 100644
index 0000000..1e2468e
--- /dev/null
+++ b/src/pages/EditUserModal/index.tsx
@@ -0,0 +1,175 @@
+import React, { useEffect } from "react";
+import {
+ Box,
+ Button,
+ Typography,
+ TextField,
+ Modal,
+ IconButton,
+} from "@mui/material";
+import CloseIcon from "@mui/icons-material/Close";
+import { useForm, Controller } from "react-hook-form";
+
+interface EditModalProps {
+ open: boolean;
+ handleClose: () => void;
+ handleCreate: (data: FormData) => void;
+ handleUpdate: (id: string, data: FormData) => void;
+ editRow: any;
+}
+
+interface FormData {
+ managerName: string;
+ stationName: string;
+ stationLocation: string;
+ phoneNumber: string;
+}
+
+const EditModal: React.FC = ({
+ open,
+ handleClose,
+ handleCreate,
+ handleUpdate,
+ editRow,
+}) => {
+ const {
+ control,
+ handleSubmit,
+ formState: { errors },
+ setValue,
+ reset,
+ } = useForm({
+ defaultValues: {
+ managerName: "",
+ stationName: "",
+ stationLocation: "",
+ phoneNumber: "",
+ },
+ });
+
+ useEffect(() => {
+ if (editRow) {
+ setValue("managerName", editRow.managerName);
+ setValue("stationName", editRow.stationName);
+ setValue("stationLocation", editRow.stationLocation);
+ setValue("phoneNumber", editRow.phoneNumber);
+ } else {
+ reset();
+ }
+ }, [editRow, setValue, reset]);
+
+ const onSubmit = (data: FormData) => {
+ if (editRow) {
+ handleUpdate(editRow.id, data);
+ } else {
+ handleCreate(data);
+ }
+ handleClose();
+ reset();
+ };
+
+ return (
+
+
+ {/* Header */}
+
+
+ {editRow ? "Edit Manager" : "Add Manager"}
+
+
+
+
+
+
+ {/* Horizontal Line */}
+
+
+ {/* Input Fields */}
+
+ {/* First Row - Two Inputs */}
+
+
+ Manager Name
+ (
+
+ )}
+ />
+
+
+
+ Station Name
+ (
+
+ )}
+ />
+
+
+
+ {/* Second Row - Two Inputs */}
+
+
+ Station Location
+ (
+
+ )}
+ />
+
+
+
+ Phone Number
+ (
+
+ )}
+ />
+
+
+
+
+ {/* Submit Button */}
+
+
+
+
+
+ );
+};
+
+export default EditModal;
\ No newline at end of file
diff --git a/src/pages/ManagerList/index.tsx b/src/pages/ManagerList/index.tsx
new file mode 100644
index 0000000..50ed6dc
--- /dev/null
+++ b/src/pages/ManagerList/index.tsx
@@ -0,0 +1,131 @@
+import React, { useState } from "react";
+import { Box, Button, Typography, TextField, InputAdornment, IconButton } from "@mui/material";
+import SearchIcon from "@mui/icons-material/Search";
+import EqualizerIcon from "@mui/icons-material/Tune";
+import CustomTable, { Column } from "../../components/CustomTable";
+import AddManagerModal from "../../pages/AddManagerModal";
+import EditUserModal from "../EditUserModal";
+
+export default function ManagerList() {
+ const [search, setSearch] = useState("");
+ const [addButtonModal, setAddButtonModal] = useState(false);
+ const [modalOpen, setModalOpen] = useState(false);
+ const [rowData, setRowData] = useState(null);
+ const [viewModal, setViewModal] = React.useState(false);
+ const [deleteModal, setDeleteModal] = React.useState(false);
+
+
+ const [managers, setManagers] = useState([
+ { id: 1, srno: 1, managerName: "John Doe", stationName: "Station A", stationLocation: "Location X", phoneNumber: "123-456-7890" },
+ { id: 2, srno: 2, managerName: "Jane Smith", stationName: "Station B", stationLocation: "Location Y", phoneNumber: "987-654-3210" },
+ ]);
+
+ const handleSearchChange = (event) => {
+ setSearch(event.target.value);
+ };
+
+ const handleClickOpen = () => {
+ setRowData(null);
+ setAddButtonModal(true);
+ };
+
+ const handleCloseModal = () => {
+ setAddButtonModal(false);
+ setModalOpen(false);
+ setRowData(null);
+ };
+
+ const handleUpdate = (id, updatedData) => {
+ setManagers((prevManagers) =>
+ prevManagers.map((manager) => (manager.id === id ? { ...manager, ...updatedData } : manager))
+ );
+ handleCloseModal();
+ };
+ const handleAddManager = (newManager) => {
+ setManagers((prevManagers) => {
+ const newId = prevManagers.length > 0 ? prevManagers[prevManagers.length - 1].id + 1 : 1;
+ return [...prevManagers, { ...newManager, id: newId, srno: newId }];
+ });
+ setAddButtonModal(false);
+ };
+
+
+
+ const managerColumns: Column[] = [
+ { id: "srno", label: "Sr No" },
+ { id: "managerName", label: "Manager Name" },
+ { id: "stationName", label: "Station Name" },
+ { id: "stationLocation", label: "Station Location" },
+ { id: "phoneNumber", label: "Phone Number" },
+ { id: "action", label: "Action", align: "center" },
+ ];
+
+ const filteredManagers = managers.filter((manager) =>
+ Object.values(manager).some((value) =>
+ typeof value === "string" && value.toLowerCase().includes(search.toLowerCase())
+ )
+ );
+
+ return (
+ <>
+
+
+ Managers
+
+
+
+
+
+ ),
+ }}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/src/redux/slices/managerSlice.ts b/src/redux/slices/managerSlice.ts
new file mode 100644
index 0000000..48387c3
--- /dev/null
+++ b/src/redux/slices/managerSlice.ts
@@ -0,0 +1,103 @@
+import { createSlice, createAsyncThunk, PayloadAction } from "@reduxjs/toolkit";
+import { toast } from "sonner";
+
+// Interfaces
+interface Manager {
+ id: string;
+ name: string;
+ email: string;
+ role: string;
+ phone: string;
+ registeredAddress: string;
+}
+
+interface ManagerState {
+ managers: Manager[];
+ isLoading: boolean;
+}
+
+// Dummy API function placeholder
+const dummyApiCall = async (response: any, delay = 500) =>
+ new Promise((resolve) => setTimeout(() => resolve(response), delay));
+
+// Fetch Manager List
+export const fetchManagerList = createAsyncThunk(
+ "fetchManagerList",
+ async (_, { rejectWithValue }) => {
+ try {
+ const response: any = await dummyApiCall({ data: [{ id: "1", name: "John Doe", email: "john@example.com", role: "Manager", phone: "1234567890", registeredAddress: "Somewhere" }] });
+ return response.data;
+ } catch (error: any) {
+ toast.error("Error fetching manager list: " + error);
+ return rejectWithValue("An error occurred");
+ }
+ }
+);
+
+// Delete Manager
+export const deleteManager = createAsyncThunk(
+ "deleteManager",
+ async (id, { rejectWithValue }) => {
+ try {
+ await dummyApiCall(null);initialState
+);
+
+// Add Manager
+export const addManager = createAsyncThunk<
+ Manager,
+ { name: string; email: string; phone: string; registeredAddress: string },
+ { rejectValue: string }
+>("addManager", async (data, { rejectWithValue }) => {
+ try {
+ const response: any = await dummyApiCall({ id: "2", ...data });
+ return response;
+ } catch (error: any) {
+ return rejectWithValue("An error occurred");
+ }
+});
+
+const initialState: ManagerState = {
+ managers: [],
+ isLoading: false,
+};
+
+const managerSlice = createSlice({
+ name: "manager",
+ initialState,
+ reducers: {},
+ extraReducers: (builder) => {
+ builder
+ .addCase(fetchManagerList.pending, (state) => {
+ state.isLoading = true;
+ })
+ .addCase(fetchManagerList.fulfilled, (state, action: PayloadAction) => {
+ state.isLoading = false;
+ state.managers = action.payload;
+ })
+ .addCase(fetchManagerList.rejected, (state) => {
+ state.isLoading = false;
+ })
+ .addCase(deleteManager.pending, (state) => {
+ state.isLoading = true;
+ })
+ .addCase(deleteManager.fulfilled, (state, action) => {
+ state.isLoading = false;
+ state.managers = state.managers.filter((manager) => manager.id !== action.payload);
+ })
+ .addCase(deleteManager.rejected, (state) => {
+ state.isLoading = false;
+ })
+ .addCase(addManager.pending, (state) => {
+ state.isLoading = true;
+ })
+ .addCase(addManager.fulfilled, (state, action) => {
+ state.isLoading = false;
+ state.managers.push(action.payload);
+ })
+ .addCase(addManager.rejected, (state) => {
+ state.isLoading = false;
+ });
+ },
+});
+
+export default managerSlice.reducer;
diff --git a/src/router.tsx b/src/router.tsx
index d2ce56d..feffbfd 100644
--- a/src/router.tsx
+++ b/src/router.tsx
@@ -15,6 +15,8 @@ const ProfilePage = lazy(() => import("./pages/ProfilePage"));
const NotFoundPage = lazy(() => import("./pages/NotFound"));
const UserList = lazy(() => import("./pages/UserList"));
const PermissionsTable = lazy(() => import("./pages/PermissionTable"));
+const ManagerList = lazy(() => import("./pages/ManagerList"));
+
interface ProtectedRouteProps {
caps: string[];
@@ -86,6 +88,18 @@ export default function AppRouter() {
/>
}
/>
+
+ }
+ />
+ }
+ />
+
+
{children}
+
);
}