250 lines
5.9 KiB
TypeScript
250 lines
5.9 KiB
TypeScript
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: 0,
|
||
mt:0
|
||
}}
|
||
>
|
||
{/* Greeting */}
|
||
<Box display="flex" alignItems="center" px={3} mb={3} >
|
||
{/* <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="h4">
|
||
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>
|
||
);
|
||
}
|