diff --git a/src/App.css b/src/App.css index 841a48f..51cd48d 100644 --- a/src/App.css +++ b/src/App.css @@ -24,7 +24,7 @@ html, body { @font-face { - font-family: 'Publica Sans Round Medium'; + font-family: '"Publica Sans Round Medium", sans-serif'; src: url('../public/fonts/PublicaSansRound-Md.otf') format('otf'); diff --git a/src/components/MainGrid/managerGrid.tsx b/src/components/MainGrid/managerGrid.tsx index 5cab860..594479c 100644 --- a/src/components/MainGrid/managerGrid.tsx +++ b/src/components/MainGrid/managerGrid.tsx @@ -61,9 +61,9 @@ export default function ManagerGrid() { {/* Charts */} - + {/* - + */} diff --git a/src/components/MainGrid/userDashboard.tsx b/src/components/MainGrid/userDashboard.tsx index 8aac5b6..1fafd4c 100644 --- a/src/components/MainGrid/userDashboard.tsx +++ b/src/components/MainGrid/userDashboard.tsx @@ -86,11 +86,12 @@ export default function UserDashboard() { sx={{ width: "100%", color: "#DE0E1E9", - py: 3, + py: 0, + mt:0 }} > {/* Greeting */} - + {/* */} - + Welcome back, {user?.name || "User"}! diff --git a/src/components/SessionsChart/sessionChart.tsx b/src/components/SessionsChart/sessionChart.tsx index ac8a30e..df2c5be 100644 --- a/src/components/SessionsChart/sessionChart.tsx +++ b/src/components/SessionsChart/sessionChart.tsx @@ -1,4 +1,5 @@ import * as React from "react"; +import { useDispatch, useSelector } from "react-redux"; import Card from "@mui/material/Card"; import CardContent from "@mui/material/CardContent"; import Typography from "@mui/material/Typography"; @@ -8,24 +9,54 @@ import MenuItem from "@mui/material/MenuItem"; import FormControl from "@mui/material/FormControl"; import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; import { useTheme } from "@mui/material/styles"; +import { fetchDashboardData } from "../../redux/slices/dashboardSlice"; +import { RootState } from "../../redux/store/store"; // Adjust the path accordingly export default function SessionsChart() { - const theme = useTheme(); - const [selectedStation, setSelectedStation] = React.useState( - "Delhi NCR EV Station" - ); + const theme = useTheme(); + const dispatch = useDispatch(); + const [selectedStation, setSelectedStation] = React.useState(""); - const handleChange = (event: { target: { value: React.SetStateAction } }) => { - setSelectedStation(event.target.value); - }; + // Get the dashboard data from Redux state + const { basicPrice, loading } = useSelector( + (state: RootState) => state.dashboardReducer + ); - return ( + // Get unique station names from basicPrice for the dropdown + const stationNames = Array.from( + new Set( + basicPrice?.map( + (price: { stationName: string }) => price.stationName + ) + ) + ); + + // Set default station when basicPrice loads + React.useEffect(() => { + if (stationNames.length > 0 && !selectedStation) { + setSelectedStation(stationNames[0]); + } + }, [basicPrice, stationNames, selectedStation]); + + // Handle station selection from dropdown + const handleChange = (event: React.ChangeEvent<{ value: unknown }>) => { + setSelectedStation(event.target.value as string); + }; + + // Filter basic prices for the selected station + const selectedBasePrices = + basicPrice?.filter( + (price: { stationName: string }) => + price.stationName === selectedStation + ) || []; + + return ( @@ -65,7 +101,8 @@ export default function SessionsChart() { - {/* Grid container for the four boxes */} + {/* Display the base prices for the selected station */} - {[1, 2, 3, 4].map((item) => ( - 0 ? ( + selectedBasePrices.map( + (price: { + stationId: any; + port: string; + price: number; + }) => ( + + + {price.port} + + + + {price.price.toFixed(2)}{" "} + {/* Ensure consistent decimal places */} + + + cents/kWh + + + + ) + ) + ) : ( + - - Basic Charging - - - - 16.83 - - - cents/kWh - - - - ))} + No pricing data available for this station. + + )} - ); + ); } diff --git a/src/index.css b/src/index.css index 94c07ff..86fdd5c 100644 --- a/src/index.css +++ b/src/index.css @@ -1,32 +1,31 @@ body { - margin: 0; - font-family: "Gilroy"; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - + margin: 0; + font-family: '"Publica Sans Round Medium", sans-serif'; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } code { - font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', - monospace; + font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", + monospace; } .mui-typography { - font-family: "Gilroy"; - background-color: rgb(7, 127, 233); + font-family: "Gilroy"; + background-color: rgb(7, 127, 233); } .css-1w8ddxu-MuiBarElement-root { - width: 19px !important; - border-radius: 50px !important; - rx: 8; - ry: 8 + width: 19px !important; + border-radius: 50px !important; + rx: 8; + ry: 8; } @font-face { - font-family: 'Publica Sans Round Medium'; - src: url('../public/fonts/PublicaSansRound-Md.otf') format('otf'); - - font-weight: 500; - font-style: normal; - font-display: swap; -} \ No newline at end of file + font-family: '"Publica Sans Round Medium", sans-serif'; + src: url("../public/fonts/PublicaSansRound-Md.otf") format("otf"); + + font-weight: 500; + font-style: normal; + font-display: swap; +} diff --git a/src/pages/Dashboard/index.tsx b/src/pages/Dashboard/index.tsx index 2ec1105..dbabb9c 100644 --- a/src/pages/Dashboard/index.tsx +++ b/src/pages/Dashboard/index.tsx @@ -48,24 +48,25 @@ const Dashboard: React.FC = ({ return ; default: - return ( - - - Access Denied: You do not have permission to view - this dashboard. - - - ); + return("") + // return ( + // + // + // Access Denied: You do not have permission to view + // this dashboard. + // + // + // ); } }; diff --git a/src/redux/slices/dashboardSlice.ts b/src/redux/slices/dashboardSlice.ts index ace0259..f3554d3 100644 --- a/src/redux/slices/dashboardSlice.ts +++ b/src/redux/slices/dashboardSlice.ts @@ -2,7 +2,6 @@ import { createSlice, createAsyncThunk, PayloadAction } from "@reduxjs/toolkit"; import http from "../../lib/https"; import { toast } from "sonner"; -// Define interfaces for the dashboard data structure interface CarPortCount { carPort: string; count: number; @@ -17,6 +16,13 @@ interface TopStation { }; } +interface BasicPrice { + port: string; + price: number; + stationId: number; + stationName: string; +} + interface DashboardState { totalAdmins?: number; totalManagers?: number; @@ -24,6 +30,7 @@ interface DashboardState { totalStations?: number; carPortCounts?: CarPortCount[]; topStations?: TopStation[]; + basicPrice?: BasicPrice[]; totalBookings?: number; loading: boolean; error: string | null; @@ -36,6 +43,7 @@ const initialState: DashboardState = { totalStations: 0, carPortCounts: [], topStations: [], + basicPrice: [], totalBookings: 0, loading: false, error: null, @@ -44,12 +52,17 @@ const initialState: DashboardState = { // Async thunk for fetching dashboard data export const fetchDashboardData = createAsyncThunk< DashboardState, - { startDateBookings?: string; endDateBookings?: string; startDateStations?: string; endDateStations?: string}, // Accept startDate and endDate as optional parameters + { + startDateBookings?: string; + endDateBookings?: string; + startDateStations?: string; + endDateStations?: string; + }, { rejectValue: string } >("dashboard/fetchDashboardData", async (params, { rejectWithValue }) => { try { - const response = await http.get("/dashboard", { params }); // Pass startDate and endDate as query params - return response.data; + const response = await http.get("/dashboard", { params }); + return response.data as DashboardState; // Ensure response matches DashboardState } catch (error: any) { toast.error("Error Fetching Dashboard Data: " + error.message); return rejectWithValue( @@ -73,15 +86,16 @@ const dashboardSlice = createSlice({ fetchDashboardData.fulfilled, (state, action: PayloadAction) => { state.loading = false; - state.totalAdmins = action.payload.totalAdmins; - state.totalManagers = action.payload.totalManagers; - state.totalUsers = action.payload.totalUsers; - state.totalStations = action.payload.totalStations; - state.carPortCounts = action.payload.carPortCounts; - state.topStations = action.payload.topStations; - state.totalBookings = action.payload.totalBookings; + // Map response fields to state + state.totalAdmins = action.payload.totalAdmins ?? 0; + state.totalManagers = action.payload.totalManagers ?? 0; + state.totalUsers = action.payload.totalUsers ?? 0; + state.totalStations = action.payload.totalStations ?? 0; + state.carPortCounts = action.payload.carPortCounts ?? []; + state.topStations = action.payload.topStations ?? []; + state.basicPrice = action.payload.basicPrice ?? []; + state.totalBookings = action.payload.totalBookings ?? 0; } - ) .addCase(fetchDashboardData.rejected, (state, action) => { state.loading = false; diff --git a/src/redux/slices/managerStationSlice.ts b/src/redux/slices/managerStationSlice.ts index 539b1e6..c13788e 100644 --- a/src/redux/slices/managerStationSlice.ts +++ b/src/redux/slices/managerStationSlice.ts @@ -35,7 +35,7 @@ export const stationDetailList = createAsyncThunk< const token = localStorage?.getItem("authToken"); if (!token) throw new Error("No token found"); - const response = await http.get("/get-station-details"); + const response = await http.get("/get-station-detail"); if (!response.data?.data) throw new Error("Invalid API response"); return response.data.data; } catch (error: any) { @@ -88,8 +88,7 @@ export const updateStationDetails = createAsyncThunk< try { const response = await http.patch( `/update-station-details/${id}`, - managerStationData, - + managerStationData ); toast.success("Station Details updated successfully"); return response.data; // Return the updated data @@ -207,7 +206,7 @@ const managerStationSlice = createSlice({ } } ) - + .addCase(deleteStationDetails.rejected, (state, action) => { state.loading = false; state.error =