diff --git a/src/components/AddManagerModal/addManagerModal.tsx b/src/components/AddManagerModal/addManagerModal.tsx
index e3cfdf2..f91bd46 100644
--- a/src/components/AddManagerModal/addManagerModal.tsx
+++ b/src/components/AddManagerModal/addManagerModal.tsx
@@ -57,9 +57,9 @@ export default function AddManagerModal({ open, handleClose }) {
try {
await dispatch(addManager(managerData));
dispatch(managerList());
- clearErrors();
- reset();
- handleClose();
+ clearErrors();
+ reset();
+ handleClose();
} catch (error) {
console.error("Error adding manager:", error);
}
@@ -67,8 +67,8 @@ export default function AddManagerModal({ open, handleClose }) {
// Handle modal close, clearing errors and resetting form
const handleModalClose = () => {
- clearErrors();
- reset();
+ clearErrors();
+ reset();
handleClose();
};
@@ -348,6 +348,9 @@ export default function AddManagerModal({ open, handleClose }) {
togglePasswordVisibility
}
edge="end"
+ sx={{
+ color: "#000000",
+ }}
>
{showPassword ? (
diff --git a/src/components/MainGrid/adminGrid.tsx b/src/components/MainGrid/adminGrid.tsx
new file mode 100644
index 0000000..7af0102
--- /dev/null
+++ b/src/components/MainGrid/adminGrid.tsx
@@ -0,0 +1,105 @@
+import React, { useEffect } from "react";
+import Grid from "@mui/material/Grid";
+import Box from "@mui/material/Box";
+import Typography from "@mui/material/Typography";
+import SessionsChart from "../SessionsChart/sessionChart";
+import ResourcesPieChart from "../ResourcePieChart/resourcePieChart";
+import RoundedBarChart from "../barChartCard/barChartCard";
+import LineChartCard from "../LineChartCard/lineChartCard";
+import { AppDispatch, RootState } from "../../redux/store/store";
+import { useDispatch, useSelector } from "react-redux";
+import { fetchDashboardData } from "../../redux/slices/dashboardSlice";
+import AppTheme from "../../shared-theme/AppTheme";
+import StatCard from "../StatCard/statCard";
+
+export default function AdminGrid() {
+ const dispatch = useDispatch();
+ const { totalManagers, totalUsers, totalStations, loading, error } =
+ useSelector((state: RootState) => state.dashboardReducer);
+
+ useEffect(() => {
+ dispatch(fetchDashboardData());
+ }, [dispatch]);
+
+ // Fallback defaults if data is undefined
+ const data = {
+ totalManagers: totalManagers ?? 12,
+ totalUsers: totalUsers ?? 24,
+ totalStations: totalStations ?? 8,
+ };
+
+ const statCards = [
+ { title: "Total Managers", value: data.totalManagers },
+ { title: "Total Users", value: data.totalUsers },
+ { title: "Total Stations", value: data.totalStations },
+ ];
+
+ return (
+
+ theme.palette.background.default,
+ }}
+ >
+ {/* Header */}
+
+ Admin Dashboard
+
+
+
+ {statCards.map((card, index) => (
+
+
+
+ ))}
+
+
+ {/* Charts */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/MainGrid/mainGrid.tsx b/src/components/MainGrid/mainGrid.tsx
index a1aefae..49d0a67 100644
--- a/src/components/MainGrid/mainGrid.tsx
+++ b/src/components/MainGrid/mainGrid.tsx
@@ -1,3 +1,120 @@
+// import React, { useEffect } from "react";
+// import Grid from "@mui/material/Grid";
+// import Box from "@mui/material/Box";
+// import Typography from "@mui/material/Typography";
+// import SessionsChart from "../SessionsChart/sessionChart";
+// import ResourcesPieChart from "../ResourcePieChart/resourcePieChart";
+// import RoundedBarChart from "../barChartCard/barChartCard";
+// import LineChartCard from "../LineChartCard/lineChartCard";
+// import { AppDispatch, RootState } from "../../redux/store/store";
+// import { useDispatch, useSelector } from "react-redux";
+// import { fetchDashboardData } from "../../redux/slices/dashboardSlice";
+// import AppTheme from "../../shared-theme/AppTheme"; // Import the custom theme
+// import StatCard from "../StatCard/statCard"; // Adjusted import for consistency
+
+// export default function MainGrid() {
+// const dispatch = useDispatch();
+// const {
+// totalAdmins,
+// totalManagers,
+// totalUsers,
+// totalStations,
+
+// } = useSelector((state: RootState) => state.dashboardReducer);
+// const userType = useSelector(
+// (state: RootState) => state.profileReducer.user?.userType
+// );
+// useEffect(() => {
+// dispatch(fetchDashboardData());
+// }, [dispatch]);
+
+// const data = {
+// totalAdmins: totalAdmins ?? 86,
+// totalManagers: totalManagers ?? 12,
+// totalUsers: totalUsers ?? 24,
+// totalStations: totalStations ?? 8,
+// };
+
+// const getStatCards = () => {
+// switch (userType) {
+// case "superadmin":
+// return [
+// { title: "Total Admins", value: data.totalAdmins },
+// { title: "Total Managers", value: data.totalManagers },
+// { title: "Total Users", value: data.totalUsers },
+// { title: "Total Stations", value: data.totalStations },
+// ];
+// case "admin":
+// return [
+// { title: "Total Managers", value: data.totalManagers },
+// { title: "Total Users", value: data.totalUsers },
+// { title: "Total Stations", value: data.totalStations },
+// ];
+// case "manager":
+// return [
+// { title: "Total Users", value: data.totalUsers },
+
+// ];
+
+// default:
+// return [];
+// }
+// };
+// return (
+//
+// theme.palette.background.default,
+// }}
+// >
+// {/* Dashboard Header */}
+//
+// Dashboard
+//
+
+// {/* Grid Layout */}
+//
+// {/* Statistic Cards */}
+// {getStatCards().map((card, index) => (
+//
+//
+//
+// ))}
+
+// {/* Charts */}
+// {userType !== "user" && (
+// <>
+//
+//
+//
+//
+//
+//
+
+//
+//
+//
+
+//
+//
+//
+// >
+// )}
+//
+//
+//
+// );
+// }
import React, { useEffect } from "react";
import Grid from "@mui/material/Grid";
import Box from "@mui/material/Box";
@@ -50,20 +167,18 @@ export default function MainGrid() {
maxWidth: "1800px",
mx: "auto",
px: { xs: 2, sm: 1, md: 0 },
- background: (theme) => theme.palette.background.default, // #DFECF1 from theme
+ background: (theme) => theme.palette.background.default,
}}
>
{/* Dashboard Header */}
- Dashboard
+ Dashboard
{/* Grid Layout */}
diff --git a/src/components/MainGrid/managerGrid.tsx b/src/components/MainGrid/managerGrid.tsx
new file mode 100644
index 0000000..5cab860
--- /dev/null
+++ b/src/components/MainGrid/managerGrid.tsx
@@ -0,0 +1,77 @@
+import React, { useEffect } from "react";
+import Grid from "@mui/material/Grid";
+import Box from "@mui/material/Box";
+import Typography from "@mui/material/Typography";
+import SessionsChart from "../SessionsChart/sessionChart";
+import ResourcesPieChart from "../ResourcePieChart/resourcePieChart";
+import RoundedBarChart from "../barChartCard/barChartCard";
+import LineChartCard from "../LineChartCard/lineChartCard";
+import { AppDispatch, RootState } from "../../redux/store/store";
+import { useDispatch, useSelector } from "react-redux";
+import { fetchDashboardData } from "../../redux/slices/dashboardSlice";
+import AppTheme from "../../shared-theme/AppTheme";
+import StatCard from "../StatCard/statCard";
+
+export default function ManagerGrid() {
+ const dispatch = useDispatch();
+ const { totalUsers, totalStations } = useSelector(
+ (state: RootState) => state.dashboardReducer
+ );
+
+ useEffect(() => {
+ dispatch(fetchDashboardData());
+ }, [dispatch]);
+
+ const statCards = [{ title: "Total Users", value: totalUsers ?? 24 }];
+
+ return (
+
+ theme.palette.background.default,
+ }}
+ >
+ {/* Header */}
+
+ Dashboard
+
+
+ {/* Stat Cards - Centered */}
+
+ {statCards.map((card, index) => (
+
+
+
+ ))}
+
+
+ {/* Charts */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/MainGrid/userDashboard.tsx b/src/components/MainGrid/userDashboard.tsx
new file mode 100644
index 0000000..8aac5b6
--- /dev/null
+++ b/src/components/MainGrid/userDashboard.tsx
@@ -0,0 +1,248 @@
+import React, { useEffect } from "react";
+import { Box, Grid, Typography, Divider, Avatar, Chip } from "@mui/material";
+import {
+ EvStation,
+ AccessTime,
+ DirectionsCar,
+ BookOnline,
+} from "@mui/icons-material";
+import { useDispatch, useSelector } from "react-redux";
+import { fetchDashboardData } from "../../redux/slices/dashboardSlice";
+import { AppDispatch, RootState } from "../../redux/store/store";
+import { BarChart } from "@mui/x-charts/BarChart";
+import { LineChart } from "@mui/x-charts/LineChart";
+import AppTheme from "../../shared-theme/AppTheme";
+import StatCard from "../StatCard/statCard";
+
+export default function UserDashboard() {
+ const dispatch = useDispatch();
+ const { user } = useSelector((state: RootState) => state.profileReducer);
+ const { totalStations } = useSelector(
+ (state: RootState) => state.dashboardReducer
+ );
+
+ useEffect(() => {
+ dispatch(fetchDashboardData());
+ }, [dispatch]);
+
+ const statCards = [
+ {
+ title: "Active Bookings",
+ value: 2,
+ icon: ,
+ },
+ {
+ title: "Nearby Stations",
+ value: totalStations || 8,
+ icon: ,
+ },
+ {
+ title: "Charges This Month",
+ value: 15,
+ icon: ,
+ },
+ {
+ title: "Available Slots",
+ value: 4,
+ icon: ,
+ },
+ ];
+
+ const upcomingBookings = [
+ { title: "Indian EV Station - Slot 1", time: "Apr 25, 6:00 PM" },
+ { title: "Mumbai EV Station - Slot 3", time: "Apr 26, 2:00 PM" },
+ ];
+
+ const recentSessions = [
+ {
+ station: "Indian EV Station",
+ time: "Yesterday at 3:00 PM",
+ duration: "1h 30m",
+ },
+ {
+ station: "Delhi EV Station",
+ time: "Apr 22, 5:00 PM",
+ duration: "2h",
+ },
+ ];
+
+ const barChartData = [
+ { category: "Station A", bookings: 5 },
+ { category: "Station B", bookings: 3 },
+ { category: "Station C", bookings: 8 },
+ ];
+
+ const lineChartData = [
+ { date: "2025-04-01", charges: 5 },
+ { date: "2025-04-02", charges: 6 },
+ { date: "2025-04-03", charges: 4 },
+ { date: "2025-04-04", charges: 7 },
+ { date: "2025-04-05", charges: 5 },
+ ];
+
+ return (
+
+
+ {/* Greeting */}
+
+ {/*
+ {user?.name?.charAt(0).toUpperCase() || "U"}
+ */}
+
+
+ Welcome back, {user?.name || "User"}!
+
+
+ Here’s a quick snapshot of your EV activity.
+
+
+
+
+ {/* Stat Cards */}
+
+ {statCards.map((card, index) => (
+
+
+
+ ))}
+
+
+ {/* Charts */}
+
+
+
+
+ Bookings by Station
+
+
+
+
+
+
+
+
+ Daily Charges
+
+
+
+
+
+
+
+ {/* Bookings & Sessions */}
+
+
+
+
+ Upcoming Bookings
+
+
+ {upcomingBookings.map((booking, idx) => (
+
+
+ {booking.title}
+
+
+ }
+ label={booking.time}
+ sx={{
+ bgcolor: "#000000",
+ color: "#D0E1E9 !important",
+ "& .MuiChip-label": {
+ color: "#D0E1E9 !important",
+ },
+ }}
+ />
+
+ ))}
+
+
+
+
+
+ Recent Charging Sessions
+
+
+ {recentSessions.map((session, idx) => (
+
+
+ {session.station}
+
+
+ {session.time} • {session.duration}
+
+
+ ))}
+
+
+
+
+
+ );
+}
diff --git a/src/components/MenuContent/index.tsx b/src/components/MenuContent/index.tsx
index 492f9a4..a2a9974 100644
--- a/src/components/MenuContent/index.tsx
+++ b/src/components/MenuContent/index.tsx
@@ -89,17 +89,17 @@ export default function MenuContent({ hidden }: PropType) {
userRole === "manager" && {
text: "Station Details",
icon: ,
- url: "/panel/manager-station-details", // Placeholder for now
+ url: "/panel/manager-station-details",
},
userRole === "user" && {
text: "Available Slots",
icon: ,
- url: "/panel/all-available-slots", // Placeholder for now
+ url: "/panel/all-available-slots",
},
userRole === "user" && {
text: "Near By Stations",
icon: ,
- url: "/panel/external-station-list", // Placeholder for now
+ url: "/panel/external-station-list",
},
];
@@ -119,7 +119,7 @@ export default function MenuContent({ hidden }: PropType) {
{
+ const userType = useSelector(
+ (state: RootState) => state.profileReducer.user?.userType
+ );
+
+ if (userType === "user") {
+ return ;
+ }
+
+ // Optional: route others to dashboard or their own start page
+ return ;
+};
+
+export default RoleBasedRedirect;
diff --git a/src/components/barChartCard/barChartCard.tsx b/src/components/barChartCard/barChartCard.tsx
index e667a36..689122d 100644
--- a/src/components/barChartCard/barChartCard.tsx
+++ b/src/components/barChartCard/barChartCard.tsx
@@ -84,11 +84,12 @@ export default function RoundedBarChart() {
const chartSetting = getChartSettings();
// Data transformation for BarChart
- const chartData = topStations.map((station) => ({
- name: station?.ChargingStation?.name,
- count: parseInt(station.count, 10), // Ensure count is a number
+ const chartData = (topStations ?? []).map((station) => ({
+ name: station?.ChargingStation?.name ?? "Unknown Station",
+ count: parseInt(station?.count ?? "0", 10),
}));
+
return (
= ({
disableCustomTheme = false,
}) => {
+
+ const userType = useSelector(
+ (state: RootState) => state.profileReducer.user?.userType
+ );
+
+
+ const renderGrid = () => {
+ switch (userType?.toLowerCase()) {
+ case "superadmin":
+ return ;
+ case "admin":
+ return ;
+ case "manager":
+ return ;
+ case "user":
+ return ;
+
+ default:
+ return (
+
+
+ Access Denied: You do not have permission to view
+ this dashboard.
+
+
+ );
+ }
+ };
+
return (
- {!disableCustomTheme ? (
- <>
-
- >
- ) : (
-
- )}
+ {!disableCustomTheme && renderGrid()}
);
};
diff --git a/src/redux/slices/dashboardSlice.ts b/src/redux/slices/dashboardSlice.ts
index f4bc836..ace0259 100644
--- a/src/redux/slices/dashboardSlice.ts
+++ b/src/redux/slices/dashboardSlice.ts
@@ -18,13 +18,13 @@ interface TopStation {
}
interface DashboardState {
- totalAdmins: number;
- totalManagers: number;
- totalUsers: number;
- totalStations: number;
- carPortCounts: CarPortCount[];
- topStations: TopStation[];
- totalBookings: number;
+ totalAdmins?: number;
+ totalManagers?: number;
+ totalUsers?: number;
+ totalStations?: number;
+ carPortCounts?: CarPortCount[];
+ topStations?: TopStation[];
+ totalBookings?: number;
loading: boolean;
error: string | null;
}
diff --git a/src/router.tsx b/src/router.tsx
index b78f394..5d3d935 100644
--- a/src/router.tsx
+++ b/src/router.tsx
@@ -62,6 +62,7 @@ export default function AppRouter() {
{/* Dashboard Routes */}
}>
+
} />}