dev-jaanvi #1
|
@ -348,6 +348,9 @@ export default function AddManagerModal({ open, handleClose }) {
|
||||||
togglePasswordVisibility
|
togglePasswordVisibility
|
||||||
}
|
}
|
||||||
edge="end"
|
edge="end"
|
||||||
|
sx={{
|
||||||
|
color: "#000000",
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{showPassword ? (
|
{showPassword ? (
|
||||||
<VisibilityOff />
|
<VisibilityOff />
|
||||||
|
|
105
src/components/MainGrid/adminGrid.tsx
Normal file
105
src/components/MainGrid/adminGrid.tsx
Normal file
|
@ -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<AppDispatch>();
|
||||||
|
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 (
|
||||||
|
<AppTheme>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
width: "100%",
|
||||||
|
maxWidth: "1800px",
|
||||||
|
mx: "auto",
|
||||||
|
px: { xs: 2, sm: 1, md: 0 },
|
||||||
|
background: (theme) => theme.palette.background.default,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* Header */}
|
||||||
|
<Typography variant="h4" component="h2" sx={{ mb: 3 }}>
|
||||||
|
Admin Dashboard
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Grid container spacing={3} justifyContent="center">
|
||||||
|
{statCards.map((card, index) => (
|
||||||
|
<Grid
|
||||||
|
key={index}
|
||||||
|
item
|
||||||
|
xs={12}
|
||||||
|
sm={6}
|
||||||
|
md={
|
||||||
|
statCards.length === 1
|
||||||
|
? 12
|
||||||
|
: statCards.length === 2
|
||||||
|
? 6
|
||||||
|
: 4
|
||||||
|
}
|
||||||
|
lg={
|
||||||
|
statCards.length === 1
|
||||||
|
? 12
|
||||||
|
: statCards.length === 2
|
||||||
|
? 6
|
||||||
|
: 4
|
||||||
|
}
|
||||||
|
xl={
|
||||||
|
statCards.length === 1
|
||||||
|
? 8
|
||||||
|
: statCards.length === 2
|
||||||
|
? 6
|
||||||
|
: 4
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<StatCard {...card} />
|
||||||
|
</Grid>
|
||||||
|
))}
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Charts */}
|
||||||
|
<Grid container spacing={3} sx={{ mt: 1 }}>
|
||||||
|
<Grid item xs={12} md={6}>
|
||||||
|
<SessionsChart />
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} md={6}>
|
||||||
|
<ResourcesPieChart />
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} md={6}>
|
||||||
|
<RoundedBarChart />
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} md={6}>
|
||||||
|
<LineChartCard />
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Box>
|
||||||
|
</AppTheme>
|
||||||
|
);
|
||||||
|
}
|
|
@ -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<AppDispatch>();
|
||||||
|
// 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 (
|
||||||
|
// <AppTheme>
|
||||||
|
// <Box
|
||||||
|
// sx={{
|
||||||
|
// width: "100%",
|
||||||
|
// maxWidth: "1800px",
|
||||||
|
// mx: "auto",
|
||||||
|
// px: { xs: 2, sm: 1, md: 0 },
|
||||||
|
// background: (theme) => theme.palette.background.default,
|
||||||
|
// }}
|
||||||
|
// >
|
||||||
|
// {/* Dashboard Header */}
|
||||||
|
// <Typography
|
||||||
|
// component="h2"
|
||||||
|
// variant="h4"
|
||||||
|
// sx={{
|
||||||
|
// mb: 3,
|
||||||
|
// }}
|
||||||
|
// >
|
||||||
|
// Dashboard
|
||||||
|
// </Typography>
|
||||||
|
|
||||||
|
// {/* Grid Layout */}
|
||||||
|
// <Grid container spacing={3} columns={12}>
|
||||||
|
// {/* Statistic Cards */}
|
||||||
|
// {getStatCards().map((card, index) => (
|
||||||
|
// <Grid key={index} item xs={12} sm={6} md={3} lg={3}>
|
||||||
|
// <StatCard {...card} />
|
||||||
|
// </Grid>
|
||||||
|
// ))}
|
||||||
|
|
||||||
|
// {/* Charts */}
|
||||||
|
// {userType !== "user" && (
|
||||||
|
// <>
|
||||||
|
// <Grid item xs={12} sm={12} md={6} lg={6}>
|
||||||
|
// <SessionsChart />
|
||||||
|
// </Grid>
|
||||||
|
// <Grid item xs={12} sm={12} md={6} lg={6}>
|
||||||
|
// <ResourcesPieChart />
|
||||||
|
// </Grid>
|
||||||
|
|
||||||
|
// <Grid item xs={12} sm={12} md={6} lg={6}>
|
||||||
|
// <RoundedBarChart />
|
||||||
|
// </Grid>
|
||||||
|
|
||||||
|
// <Grid item xs={12} sm={12} md={6} lg={6}>
|
||||||
|
// <LineChartCard />
|
||||||
|
// </Grid>
|
||||||
|
// </>
|
||||||
|
// )}
|
||||||
|
// </Grid>
|
||||||
|
// </Box>
|
||||||
|
// </AppTheme>
|
||||||
|
// );
|
||||||
|
// }
|
||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import Grid from "@mui/material/Grid";
|
import Grid from "@mui/material/Grid";
|
||||||
import Box from "@mui/material/Box";
|
import Box from "@mui/material/Box";
|
||||||
|
@ -50,17 +167,15 @@ export default function MainGrid() {
|
||||||
maxWidth: "1800px",
|
maxWidth: "1800px",
|
||||||
mx: "auto",
|
mx: "auto",
|
||||||
px: { xs: 2, sm: 1, md: 0 },
|
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 Header */}
|
||||||
<Typography
|
<Typography
|
||||||
component="h2"
|
component="h2"
|
||||||
variant="h4" // Use h4 to match the "Good morning, James!" size and weight
|
variant="h4"
|
||||||
sx={{
|
sx={{
|
||||||
mb: 3,
|
mb: 3,
|
||||||
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Dashboard
|
Dashboard
|
||||||
|
|
77
src/components/MainGrid/managerGrid.tsx
Normal file
77
src/components/MainGrid/managerGrid.tsx
Normal file
|
@ -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<AppDispatch>();
|
||||||
|
const { totalUsers, totalStations } = useSelector(
|
||||||
|
(state: RootState) => state.dashboardReducer
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
dispatch(fetchDashboardData());
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
|
const statCards = [{ title: "Total Users", value: totalUsers ?? 24 }];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AppTheme>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
width: "100%",
|
||||||
|
maxWidth: "1800px",
|
||||||
|
mx: "auto",
|
||||||
|
px: { xs: 2, sm: 2, md: 3 },
|
||||||
|
background: (theme) => theme.palette.background.default,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* Header */}
|
||||||
|
<Typography
|
||||||
|
component="h2"
|
||||||
|
variant="h4"
|
||||||
|
sx={{ mb: 3, fontWeight: 600 }}
|
||||||
|
>
|
||||||
|
Dashboard
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
{/* Stat Cards - Centered */}
|
||||||
|
<Grid
|
||||||
|
container
|
||||||
|
spacing={3}
|
||||||
|
justifyContent="center"
|
||||||
|
alignItems="stretch"
|
||||||
|
sx={{ mb: 1 }}
|
||||||
|
>
|
||||||
|
{statCards.map((card, index) => (
|
||||||
|
<Grid key={index} item xs={12} sm={8} md={4} lg={3}>
|
||||||
|
<StatCard {...card} />
|
||||||
|
</Grid>
|
||||||
|
))}
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Charts */}
|
||||||
|
<Grid container spacing={3} mt={1}>
|
||||||
|
<Grid item xs={12} sm={12} md={6} lg={6}>
|
||||||
|
<SessionsChart />
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} sm={12} md={6} lg={6}>
|
||||||
|
<ResourcesPieChart />
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} sm={12} md={6} lg={6}>
|
||||||
|
<LineChartCard />
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Box>
|
||||||
|
</AppTheme>
|
||||||
|
);
|
||||||
|
}
|
248
src/components/MainGrid/userDashboard.tsx
Normal file
248
src/components/MainGrid/userDashboard.tsx
Normal file
|
@ -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<AppDispatch>();
|
||||||
|
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: <BookOnline color="primary" />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Nearby Stations",
|
||||||
|
value: totalStations || 8,
|
||||||
|
icon: <EvStation color="success" />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Charges This Month",
|
||||||
|
value: 15,
|
||||||
|
icon: <DirectionsCar color="warning" />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Available Slots",
|
||||||
|
value: 4,
|
||||||
|
icon: <AccessTime color="secondary" />,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
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 (
|
||||||
|
<AppTheme>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
width: "100%",
|
||||||
|
color: "#DE0E1E9",
|
||||||
|
py: 3,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* Greeting */}
|
||||||
|
<Box display="flex" alignItems="center" px={3} mb={4}>
|
||||||
|
{/* <Avatar
|
||||||
|
sx={{
|
||||||
|
width: 64,
|
||||||
|
height: 64,
|
||||||
|
mr: 2,
|
||||||
|
bgcolor: "",
|
||||||
|
boxShadow: "0 4px 12px rgba(0,0,0,0.2)",
|
||||||
|
border: "2px solid white",
|
||||||
|
fontSize: "2rem",
|
||||||
|
fontWeight: "bold",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{user?.name?.charAt(0).toUpperCase() || "U"}
|
||||||
|
</Avatar> */}
|
||||||
|
<Box>
|
||||||
|
<Typography variant="h3">
|
||||||
|
Welcome back, {user?.name || "User"}!
|
||||||
|
</Typography>
|
||||||
|
<Typography color="#DE0E1E9">
|
||||||
|
Here’s a quick snapshot of your EV activity.
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* Stat Cards */}
|
||||||
|
<Grid container spacing={3} px={3}>
|
||||||
|
{statCards.map((card, index) => (
|
||||||
|
<Grid item xs={12} sm={6} md={3} key={index}>
|
||||||
|
<StatCard
|
||||||
|
title={card.title}
|
||||||
|
value={card.value}
|
||||||
|
icon={card.icon}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
))}
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Charts */}
|
||||||
|
<Grid container spacing={3} mt={1} px={3}>
|
||||||
|
<Grid item xs={12} md={6}>
|
||||||
|
<Box bgcolor="#D0E1E9" borderRadius={2} p={2}>
|
||||||
|
<Typography variant="h6" color="#000">
|
||||||
|
Bookings by Station
|
||||||
|
</Typography>
|
||||||
|
<Divider sx={{ my: 2 }} />
|
||||||
|
<BarChart
|
||||||
|
dataset={barChartData}
|
||||||
|
xAxis={[
|
||||||
|
{
|
||||||
|
scaleType: "band",
|
||||||
|
dataKey: "category",
|
||||||
|
label: "Station",
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
series={[
|
||||||
|
{
|
||||||
|
dataKey: "bookings",
|
||||||
|
label: "Bookings",
|
||||||
|
color: "#000000",
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
width={500}
|
||||||
|
height={300}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} md={6}>
|
||||||
|
<Box bgcolor="#D0E1E9" borderRadius={2} p={2}>
|
||||||
|
<Typography variant="h6" color="#000">
|
||||||
|
Daily Charges
|
||||||
|
</Typography>
|
||||||
|
<Divider sx={{ my: 2 }} />
|
||||||
|
<LineChart
|
||||||
|
dataset={lineChartData}
|
||||||
|
xAxis={[
|
||||||
|
{
|
||||||
|
scaleType: "point",
|
||||||
|
dataKey: "date",
|
||||||
|
label: "Date",
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
series={[
|
||||||
|
{
|
||||||
|
dataKey: "charges",
|
||||||
|
label: "Charges",
|
||||||
|
color: "#000000",
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
width={500}
|
||||||
|
height={300}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Bookings & Sessions */}
|
||||||
|
<Grid container spacing={3} mt={1} px={3}>
|
||||||
|
<Grid item xs={12} md={6}>
|
||||||
|
<Box bgcolor="#D0E1E9" borderRadius={2} p={2}>
|
||||||
|
<Typography variant="h6" color="#000">
|
||||||
|
Upcoming Bookings
|
||||||
|
</Typography>
|
||||||
|
<Divider sx={{ my: 2 }} />
|
||||||
|
{upcomingBookings.map((booking, idx) => (
|
||||||
|
<Box key={idx} mb={2}>
|
||||||
|
<Typography variant="subtitle1">
|
||||||
|
{booking.title}
|
||||||
|
</Typography>
|
||||||
|
<Chip
|
||||||
|
icon={
|
||||||
|
<AccessTime
|
||||||
|
sx={{
|
||||||
|
color: "#D0E1E9 !important",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label={booking.time}
|
||||||
|
sx={{
|
||||||
|
bgcolor: "#000000",
|
||||||
|
color: "#D0E1E9 !important",
|
||||||
|
"& .MuiChip-label": {
|
||||||
|
color: "#D0E1E9 !important",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} md={6}>
|
||||||
|
<Box bgcolor="#D0E1E9" borderRadius={2} p={2}>
|
||||||
|
<Typography variant="h6" color="#000">
|
||||||
|
Recent Charging Sessions
|
||||||
|
</Typography>
|
||||||
|
<Divider sx={{ my: 2 }} />
|
||||||
|
{recentSessions.map((session, idx) => (
|
||||||
|
<Box key={idx} mb={2}>
|
||||||
|
<Typography variant="subtitle1">
|
||||||
|
{session.station}
|
||||||
|
</Typography>
|
||||||
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
color="text.secondary"
|
||||||
|
>
|
||||||
|
{session.time} • {session.duration}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Box>
|
||||||
|
</AppTheme>
|
||||||
|
);
|
||||||
|
}
|
|
@ -89,17 +89,17 @@ export default function MenuContent({ hidden }: PropType) {
|
||||||
userRole === "manager" && {
|
userRole === "manager" && {
|
||||||
text: "Station Details",
|
text: "Station Details",
|
||||||
icon: <ChecklistSharpIcon />,
|
icon: <ChecklistSharpIcon />,
|
||||||
url: "/panel/manager-station-details", // Placeholder for now
|
url: "/panel/manager-station-details",
|
||||||
},
|
},
|
||||||
userRole === "user" && {
|
userRole === "user" && {
|
||||||
text: "Available Slots",
|
text: "Available Slots",
|
||||||
icon: <ChecklistSharpIcon />,
|
icon: <ChecklistSharpIcon />,
|
||||||
url: "/panel/all-available-slots", // Placeholder for now
|
url: "/panel/all-available-slots",
|
||||||
},
|
},
|
||||||
userRole === "user" && {
|
userRole === "user" && {
|
||||||
text: "Near By Stations",
|
text: "Near By Stations",
|
||||||
icon: <EvStationIcon />,
|
icon: <EvStationIcon />,
|
||||||
url: "/panel/external-station-list", // Placeholder for now
|
url: "/panel/external-station-list",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
19
src/components/RoleBasedRedirect/roleBasedRedirect.tsx
Normal file
19
src/components/RoleBasedRedirect/roleBasedRedirect.tsx
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// src/components/RoleBasedRedirect.tsx
|
||||||
|
import { Navigate } from "react-router-dom";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import { RootState } from "../../redux/reducers";
|
||||||
|
|
||||||
|
const RoleBasedRedirect = () => {
|
||||||
|
const userType = useSelector(
|
||||||
|
(state: RootState) => state.profileReducer.user?.userType
|
||||||
|
);
|
||||||
|
|
||||||
|
if (userType === "user") {
|
||||||
|
return <Navigate to="/panel/booking-list" replace />;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optional: route others to dashboard or their own start page
|
||||||
|
return <Navigate to="/panel/dashboard" replace />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RoleBasedRedirect;
|
|
@ -84,11 +84,12 @@ export default function RoundedBarChart() {
|
||||||
const chartSetting = getChartSettings();
|
const chartSetting = getChartSettings();
|
||||||
|
|
||||||
// Data transformation for BarChart
|
// Data transformation for BarChart
|
||||||
const chartData = topStations.map((station) => ({
|
const chartData = (topStations ?? []).map((station) => ({
|
||||||
name: station?.ChargingStation?.name,
|
name: station?.ChargingStation?.name ?? "Unknown Station",
|
||||||
count: parseInt(station.count, 10), // Ensure count is a number
|
count: parseInt(station?.count ?? "0", 10),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// src/pages/Dashboard
|
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { Box, CssBaseline, Typography } from "@mui/material";
|
import { Box, CssBaseline, Typography } from "@mui/material";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import { RootState } from "../../redux/store/store";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
chartsCustomizations,
|
chartsCustomizations,
|
||||||
|
@ -9,9 +9,12 @@ import {
|
||||||
datePickersCustomizations,
|
datePickersCustomizations,
|
||||||
treeViewCustomizations,
|
treeViewCustomizations,
|
||||||
} from "./theme/customizations";
|
} from "./theme/customizations";
|
||||||
|
|
||||||
import AppTheme from "../../shared-theme/AppTheme";
|
import AppTheme from "../../shared-theme/AppTheme";
|
||||||
import MainGrid from "../../components/MainGrid/mainGrid";
|
import MainGrid from "../../components/MainGrid/mainGrid";
|
||||||
|
import AdminGrid from "../../components/MainGrid/adminGrid";
|
||||||
|
import ManagerGrid from "../../components/MainGrid/managerGrid";
|
||||||
|
import UserDashboard from "../../components/MainGrid/userDashboard";
|
||||||
|
|
||||||
const xThemeComponents = {
|
const xThemeComponents = {
|
||||||
...chartsCustomizations,
|
...chartsCustomizations,
|
||||||
|
@ -27,17 +30,25 @@ interface DashboardProps {
|
||||||
const Dashboard: React.FC<DashboardProps> = ({
|
const Dashboard: React.FC<DashboardProps> = ({
|
||||||
disableCustomTheme = false,
|
disableCustomTheme = false,
|
||||||
}) => {
|
}) => {
|
||||||
|
|
||||||
|
const userType = useSelector(
|
||||||
|
(state: RootState) => state.profileReducer.user?.userType
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
const renderGrid = () => {
|
||||||
|
switch (userType?.toLowerCase()) {
|
||||||
|
case "superadmin":
|
||||||
|
return <MainGrid />;
|
||||||
|
case "admin":
|
||||||
|
return <AdminGrid />;
|
||||||
|
case "manager":
|
||||||
|
return <ManagerGrid />;
|
||||||
|
case "user":
|
||||||
|
return <UserDashboard />;
|
||||||
|
|
||||||
|
default:
|
||||||
return (
|
return (
|
||||||
<AppTheme
|
|
||||||
{...{ disableCustomTheme }}
|
|
||||||
themeComponents={xThemeComponents}
|
|
||||||
>
|
|
||||||
<CssBaseline enableColorScheme />
|
|
||||||
{!disableCustomTheme ? (
|
|
||||||
<>
|
|
||||||
<MainGrid />
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
|
@ -48,8 +59,23 @@ const Dashboard: React.FC<DashboardProps> = ({
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
padding: 2,
|
padding: 2,
|
||||||
}}
|
}}
|
||||||
></Box>
|
>
|
||||||
)}
|
<Typography color="white">
|
||||||
|
Access Denied: You do not have permission to view
|
||||||
|
this dashboard.
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AppTheme
|
||||||
|
{...{ disableCustomTheme }}
|
||||||
|
themeComponents={xThemeComponents}
|
||||||
|
>
|
||||||
|
<CssBaseline enableColorScheme />
|
||||||
|
{!disableCustomTheme && renderGrid()}
|
||||||
</AppTheme>
|
</AppTheme>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,13 +18,13 @@ interface TopStation {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DashboardState {
|
interface DashboardState {
|
||||||
totalAdmins: number;
|
totalAdmins?: number;
|
||||||
totalManagers: number;
|
totalManagers?: number;
|
||||||
totalUsers: number;
|
totalUsers?: number;
|
||||||
totalStations: number;
|
totalStations?: number;
|
||||||
carPortCounts: CarPortCount[];
|
carPortCounts?: CarPortCount[];
|
||||||
topStations: TopStation[];
|
topStations?: TopStation[];
|
||||||
totalBookings: number;
|
totalBookings?: number;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
error: string | null;
|
error: string | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,7 @@ export default function AppRouter() {
|
||||||
|
|
||||||
{/* Dashboard Routes */}
|
{/* Dashboard Routes */}
|
||||||
<Route path="/panel" element={<DashboardLayout />}>
|
<Route path="/panel" element={<DashboardLayout />}>
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
path="dashboard"
|
path="dashboard"
|
||||||
element={<ProtectedRoute component={<Dashboard />} />}
|
element={<ProtectedRoute component={<Dashboard />} />}
|
||||||
|
|
Loading…
Reference in a new issue