diff --git a/public/Group 14.svg b/public/Group 14.svg
new file mode 100644
index 0000000..503ae50
--- /dev/null
+++ b/public/Group 14.svg
@@ -0,0 +1,4 @@
+
diff --git a/public/evLogo.png b/public/evLogo.png
new file mode 100644
index 0000000..0c96ea1
Binary files /dev/null and b/public/evLogo.png differ
diff --git a/src/components/AddStationModal/index.tsx b/src/components/AddStationModal/index.tsx
index f73b639..2919838 100644
--- a/src/components/AddStationModal/index.tsx
+++ b/src/components/AddStationModal/index.tsx
@@ -341,7 +341,7 @@ export default function AddStationModal({
/>
+ />
))
) : (
diff --git a/src/components/CustomTable/index.tsx b/src/components/CustomTable/index.tsx
index 7db5231..4eda242 100644
--- a/src/components/CustomTable/index.tsx
+++ b/src/components/CustomTable/index.tsx
@@ -83,10 +83,9 @@ interface CustomTableProps {
viewModal: boolean;
setViewModal: Function;
deleteModal: boolean;
- handleStatusToggle: (id: string, currentStatus: number) => void;
+ handleStatusToggle?: (id: string, currentStatus: number) => void;
tableType: string; // Adding tableType prop to change header text dynamically
handleClickOpen: () => void;
- //handleDeleteButton: (id: string | number | undefined) => void;
}
const CustomTable: React.FC = ({
@@ -108,11 +107,8 @@ const CustomTable: React.FC = ({
const [searchQuery, setSearchQuery] = React.useState("");
const [currentPage, setCurrentPage] = React.useState(1);
const usersPerPage = 10;
- const { user, isLoading } = useSelector(
- (state: RootState) => state?.profileReducer
- );
+ const { user } = useSelector((state: RootState) => state?.profileReducer);
const open = Boolean(anchorEl);
- console.log("Rows", rows);
const handleClick = (event: React.MouseEvent, row: Row) => {
setAnchorEl(event.currentTarget);
setSelectedRow(row);
@@ -199,7 +195,7 @@ const CustomTable: React.FC = ({
if (selectedRow) {
// Toggle the opposite of current status
const newStatus = selectedRow.statusValue === 1 ? 0 : 1;
- handleStatusToggle(selectedRow.id, newStatus);
+ handleStatusToggle?.(selectedRow.id, newStatus);
}
handleClose();
};
@@ -216,7 +212,7 @@ const CustomTable: React.FC = ({
const currentRows = filteredRows.slice(indexOfFirstRow, indexOfLastRow);
const handlePageChange = (
- event: React.ChangeEvent,
+ _event: React.ChangeEvent,
value: number
) => {
setCurrentPage(value);
@@ -241,24 +237,30 @@ const CustomTable: React.FC = ({
}}
>
{/* Dynamic title based on the page type */}
- {tableType === "admin"
- ? "Admin"
- : tableType === "role"
- ? "Roles"
- : tableType === "user"
- ? "Users"
- : tableType === "manager"
- ? "Managers"
- : tableType === "vehicle"
- ? "Vehicles"
- : tableType === "station"
- ? "Charging Station"
- : tableType === "booking"
- ? "Booking"
- : tableType === "slots"
- ? "Slot"
- : "List"}
+ {(() => {
+ switch (tableType) {
+ case "admin":
+ return "Admin";
+ case "role":
+ return "Roles";
+ case "user":
+ return "Users";
+ case "manager":
+ return "Managers";
+ case "vehicle":
+ return "Vehicles";
+ case "station":
+ return "Charging Station";
+ case "booking":
+ return "Booking";
+ case "slots":
+ return "Slot";
+ default:
+ return "List";
+ }
+ })()}
+
{/* Search & Buttons Section */}
= ({
onClick={() => handleClickOpen()}
>
Add{" "}
- {tableType === "admin"
- ? "Admin"
- : tableType === "role"
- ? "Role"
- : tableType === "user"
- ? "User"
- : tableType === "manager"
- ? "Manager"
- : tableType === "vehicle"
- ? "Vehicle"
- : tableType === "station"
- ? "Charging Station"
- : tableType === "booking"
- ? "Booking"
- : tableType === "slots"
- ? "Slot"
- : "Item"}
+ {(() => {
+ switch (tableType) {
+ case "admin":
+ return "Admin";
+ case "role":
+ return "Role";
+ case "user":
+ return "User";
+ case "manager":
+ return "Manager";
+ case "vehicle":
+ return "Vehicle";
+ case "station":
+ return "Charging Station";
+ case "booking":
+ return "Booking";
+ case "slots":
+ return "Slot";
+ default:
+ return "Item";
+ }
+ })()}
)}
diff --git a/src/components/EditManagerModal/index.tsx b/src/components/EditManagerModal/index.tsx
index ec4165c..ac0d1f6 100644
--- a/src/components/EditManagerModal/index.tsx
+++ b/src/components/EditManagerModal/index.tsx
@@ -14,11 +14,19 @@ import {
CustomIconButton,
CustomTextField,
} from "../AddEditUserModel/styled.css.tsx"; // Custom styled components
+import { AppDispatch } from "../../redux/store/store.ts";
interface EditManagerModalProps {
open: boolean;
handleClose: () => void;
- editRow: any; // Manager data including id
+ handleUpdate: (
+ id: string,
+ name: string,
+ email: string,
+ phone: string,
+ stationId: string
+ ) => Promise;
+ editRow: any;
}
interface FormData {
@@ -33,7 +41,7 @@ const EditManagerModal: React.FC = ({
handleClose,
editRow,
}) => {
- const dispatch = useDispatch(); // Use dispatch to send Redux actions
+ const dispatch = useDispatch();
const {
control,
handleSubmit,
@@ -74,7 +82,7 @@ const EditManagerModal: React.FC = ({
email: data.email,
phone: data.phone,
stationId: data.stationId,
-
+
},
})
).unwrap(); // Ensure that it throws an error if the update fails
diff --git a/src/components/EditSlotModal/index.tsx b/src/components/EditSlotModal/index.tsx
index 1365b1e..f227886 100644
--- a/src/components/EditSlotModal/index.tsx
+++ b/src/components/EditSlotModal/index.tsx
@@ -14,10 +14,17 @@ import {
CustomIconButton,
CustomTextField,
} from "../AddEditUserModel/styled.css.tsx"; // Custom styled components
+import { AppDispatch } from "../../redux/store/store.ts";
interface EditSlotModalProps {
open: boolean;
handleClose: () => void;
+ handleUpdate: (
+ id: string,
+ startTime: string,
+ endTime: string,
+ isAvailable: boolean
+ ) => Promise;
editRow: any; // Slot data including id
}
@@ -33,7 +40,7 @@ const EditSlotModal: React.FC = ({
handleClose,
editRow,
}) => {
- const dispatch = useDispatch(); // Use dispatch to send Redux actions
+ const dispatch = useDispatch();
const {
control,
handleSubmit,
@@ -54,13 +61,11 @@ const EditSlotModal: React.FC = ({
editRow?.isAvailable || false
);
- // Set values if editRow is provided
useEffect(() => {
if (editRow) {
- // setValue("date", editRow.date);
setValue("startTime", editRow.startTime);
setValue("endTime", editRow.endTime);
- setIsAvailable(editRow.isAvailable); // Set the initial availability correctly
+ setIsAvailable(editRow.isAvailable);
} else {
reset();
}
@@ -68,10 +73,10 @@ const EditSlotModal: React.FC = ({
const onSubmit = async (data: FormData) => {
if (editRow) {
- setLoading(true); // Start loading
+ setLoading(true);
try {
- // Convert boolean availability to 1/0
+
const availabilityStatus = isAvailable ? true : false;
await dispatch(
@@ -81,9 +86,7 @@ const EditSlotModal: React.FC = ({
endTime: data.endTime,
isAvailable: availabilityStatus,
})
- ).unwrap(); // Ensure that it throws an error if the update fails
-
- // Refresh the list after updating the slot
+ ).unwrap();
dispatch(fetchAvailableSlots());
handleClose(); // Close modal on success
reset(); // Reset form fields after submit
diff --git a/src/components/EditStationModal/index.tsx b/src/components/EditStationModal/index.tsx
index 047e6ef..12d671e 100644
--- a/src/components/EditStationModal/index.tsx
+++ b/src/components/EditStationModal/index.tsx
@@ -57,7 +57,6 @@ const EditStationModal: React.FC = ({
handleSubmit,
setValue,
reset,
- watch,
formState: { errors },
} = useForm({
defaultValues: {
@@ -77,7 +76,7 @@ const EditStationModal: React.FC = ({
(state: RootState) => state.vehicleReducer.vehicleBrands
);
- const [selectedBrand, setSelectedBrand] = useState("");
+ const [selectedBrands, setSelectedBrands] = useState([]);
const [selectedVehicles, setSelectedVehicles] = useState([]);
useEffect(() => {
@@ -98,11 +97,19 @@ const EditStationModal: React.FC = ({
}
}, [editRow, setValue, reset]);
-
- const filteredVehicles = vehicles.filter(
- (vehicle) => vehicle.company === selectedBrand
+ // Filter vehicles based on selected brands
+ const filteredVehicles = vehicles.filter((vehicle) =>
+ selectedBrands.includes(vehicle.company)
);
+ // Handle changes in vehicle brand selection
+ const handleBrandChange = (
+ event: React.ChangeEvent<{ value: unknown }>
+ ) => {
+ setSelectedBrands(event.target.value as string[]);
+ };
+
+ // Handle changes in vehicle selection
const handleCheckboxChange = (
event: React.ChangeEvent<{ value: unknown }>
) => {
@@ -125,7 +132,7 @@ const EditStationModal: React.FC = ({
);
handleClose();
reset();
- setSelectedBrand(""); // Reset brand after submit
+ setSelectedBrands([]); // Reset brands after submit
setSelectedVehicles([]); // Reset selected vehicles
};
@@ -285,7 +292,7 @@ const EditStationModal: React.FC = ({
- {/* Vehicle Brand Selection */}
+ {/* Vehicle Brand Selection with Checkboxes */}
= ({
}}
>
- Select Vehicle Brand
+ Select Vehicle Brands
Choose Brand
-
- {/* Vehicle Selection with Checkboxes */}
= ({
+
+
{/* Submit Button */}
void;
id?: string;
};
diff --git a/src/components/SideMenu/index.tsx b/src/components/SideMenu/index.tsx
index 62e2469..4efdf7c 100644
--- a/src/components/SideMenu/index.tsx
+++ b/src/components/SideMenu/index.tsx
@@ -64,15 +64,25 @@ export default function SideMenu() {
pl: 2,
}}
>
-
- */}
+ {/*
- {/* Digi EV Text Section */}
+
{user?.userType || "N/A"}
-
+ */}
({ mode: "onChange" });
- const dispatch = useDispatch();
+ const dispatch = useDispatch();
const router = useNavigate();
const handleClickOpen = () => {
@@ -104,11 +105,11 @@ export default function Login(props: { disableCustomTheme?: boolean }) {
}}
>
diff --git a/src/pages/EvSlotList/index.tsx b/src/pages/EvSlotList/index.tsx
index d1fbaa7..ef4f174 100644
--- a/src/pages/EvSlotList/index.tsx
+++ b/src/pages/EvSlotList/index.tsx
@@ -1,5 +1,4 @@
-import React, { useEffect, useState } from "react";
-import { Box, Button, TextField, Typography } from "@mui/material";
+import { useEffect, useState } from "react";
import CustomTable, { Column } from "../../components/CustomTable";
import { useDispatch, useSelector } from "react-redux";
import { RootState, AppDispatch } from "../../redux/store/store";
@@ -15,12 +14,10 @@ import EditSlotModal from "../../components/EditSlotModal";
export default function EVSlotList() {
const [addModalOpen, setAddModalOpen] = useState(false);
const [editModalOpen, setEditModalOpen] = useState(false);
- const [editRow, setEditRow] = useState(null);
const { reset } = useForm();
const [deleteModal, setDeleteModal] = useState(false);
const [viewModal, setViewModal] = useState(false);
const [rowData, setRowData] = useState(null);
- const [searchTerm, setSearchTerm] = useState("");
const dispatch = useDispatch();
const availableSlots = useSelector(
(state: RootState) => state?.slotReducer.availableSlots
@@ -55,29 +52,34 @@ export default function EVSlotList() {
console.error("Error adding slot", error);
}
};
-
-const handleUpdate = async (
- id: string,
- startTime: string,
- endTime: string,
- isAvailable: boolean
-) => {
- try {
- await dispatch(
- updateSlot({
- id, // Pass id separately, not inside slotData
- startTime,
- endTime,
- isAvailable,
- })
- ).unwrap(); // Ensure you unwrap the result so you can handle the error properly
- await dispatch(fetchAvailableSlots()); // Refresh the list after update
- handleCloseModal(); // Close modal after update
- } catch (error) {
- console.error("Update failed", error);
- }
-};
+ const handleUpdate = async (
+ id: string,
+ startTime: string,
+ endTime: string,
+ isAvailable: boolean
+ ) => {
+ try {
+ const formattedStartTime = dayjs(startTime, "HH:mm").format(
+ "HH:mm"
+ );
+ const formattedEndTime = dayjs(endTime, "HH:mm").format("HH:mm");
+
+ await dispatch(
+ updateSlot({
+ id,
+ startTime: formattedStartTime,
+ endTime: formattedEndTime,
+ isAvailable,
+ })
+ ).unwrap();
+
+ await dispatch(fetchAvailableSlots());
+ handleCloseModal();
+ } catch (error) {
+ console.error("Update failed", error);
+ }
+ };
const slotColumns: Column[] = [
{ id: "srno", label: "Sr No" },
@@ -90,15 +92,12 @@ const handleUpdate = async (
{ id: "action", label: "Action", align: "center" },
];
- // Make sure dayjs is imported
-
const slotRows = availableSlots?.length
? availableSlots.map((slot, index) => {
const formattedDate = dayjs(slot?.date).format("YYYY-MM-DD");
const startTime = dayjs(slot?.startTime).format("HH:mm");
const endTime = dayjs(slot?.endTime).format("HH:mm");
-
- console.log("first", startTime);
+
return {
srno: index + 1,
id: slot?.id ?? "NA",
diff --git a/src/pages/ManagerList/index.tsx b/src/pages/ManagerList/index.tsx
index 6946dfc..a2db5ca 100644
--- a/src/pages/ManagerList/index.tsx
+++ b/src/pages/ManagerList/index.tsx
@@ -9,11 +9,9 @@ import {
managerList,
addManager,
updateManager,
- deleteManager,
} from "../../redux/slices/managerSlice";
import { useForm } from "react-hook-form";
-
export default function ManagerList() {
const [addModalOpen, setAddModalOpen] = useState(false);
const [editModalOpen, setEditModalOpen] = useState(false);
@@ -67,7 +65,7 @@ export default function ManagerList() {
// Handle updating an existing manager
const handleUpdate = async (
- id: number,
+ id: string,
name: string,
email: string,
phone: string,
@@ -101,65 +99,29 @@ export default function ManagerList() {
{ id: "registeredAddress", label: "Station Location" },
{ id: "action", label: "Action", align: "center" },
];
- // const categoryColumns: Column[] = [
- // { id: "srno", label: "Sr No" },
- // { id: "name", label: "Name" },
- // { id: "email", label: "Email" },
- // { id: "phone", label: "Phone" },
- // { id: "stationName", label: "Station Name" }, // Added station name column
- // { id: "stationAddress", label: "Station Location" }, // Added station address column
- // { id: "action", label: "Action", align: "center" },
- // ];
-
// Filter managers based on search term
- const filteredManagers = managers?.filter(
- (manager) =>
- manager.name?.toLowerCase().includes(searchTerm.toLowerCase()) ||
- manager.email?.toLowerCase().includes(searchTerm.toLowerCase()) ||
- manager.phone?.toLowerCase().includes(searchTerm.toLowerCase())
-
- );
-
- // Format rows to display manager details
- // const categoryRows = filteredManagers?.length
- // ? filteredManagers?.map(
- // (
- // manager: {
- // id: number;
- // name: string;
- // email: string;
- // phone: string;
-
-
- // },
- // index: number
- // ) => ({
- // id: manager?.id,
- // srno: index + 1,
- // name: manager?.name,
- // email: manager?.email,
- // phone: manager.phone ?? "NA",
- // })
- // )
- // : [];
-
-const categoryRows = filteredManagers?.length
- ? filteredManagers.map((manager, index) => {
- const station = manager?.chargingStation; // Correct access to the ChargingStation data
- return {
- id: manager.id,
- srno: index + 1,
- name: manager.name,
- email: manager.email,
- phone: manager.phone ?? "NA",
- stationName: station?.name ?? "NA", // Corrected station name
- registeredAddress: station?.registeredAddress ?? "NA", // Corrected station address
- };
- })
- : [];
-
+ // const filteredManagers = managers?.filter(
+ // (manager) =>
+ // manager.name?.toLowerCase().includes(searchTerm.toLowerCase()) ||
+ // manager.email?.toLowerCase().includes(searchTerm.toLowerCase()) ||
+ // manager.phone?.toLowerCase().includes(searchTerm.toLowerCase())
+ // );
+ const categoryRows = managers?.length
+ ? managers.map((manager, index) => {
+ const station = manager?.chargingStation; // Correct access to the ChargingStation data
+ return {
+ id: manager.id,
+ srno: index + 1,
+ name: manager.name,
+ email: manager.email,
+ phone: manager.phone ?? "NA",
+ stationName: station?.name ?? "NA", // Corrected station name
+ registeredAddress: station?.registeredAddress ?? "NA", // Corrected station address
+ };
+ })
+ : [];
return (
<>
diff --git a/src/pages/VehicleList/index.tsx b/src/pages/VehicleList/index.tsx
index 317e1d4..5edaa6d 100644
--- a/src/pages/VehicleList/index.tsx
+++ b/src/pages/VehicleList/index.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useState } from "react";
+import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import CustomTable, { Column } from "../../components/CustomTable";
import { RootState } from "../../redux/reducers";
@@ -15,13 +15,11 @@ import EditVehicleModal from "../../components/EditVehicleModal";
export default function VehicleList() {
const [addModalOpen, setAddModalOpen] = useState(false);
const [editModalOpen, setEditModalOpen] = useState(false);
- const [editRow, setEditRow] = useState(null);
const { reset } = useForm();
const [deleteModal, setDeleteModal] = useState(false);
const [viewModal, setViewModal] = useState(false);
const [rowData, setRowData] = useState(null);
- const [searchTerm, setSearchTerm] = useState("");
const dispatch = useDispatch();
const vehicles = useSelector(
(state: RootState) => state.vehicleReducer.vehicles
@@ -32,7 +30,7 @@ export default function VehicleList() {
}, [dispatch]);
const handleClickOpen = () => {
- setRowData(null); // Reset row data when opening for new admin
+ setRowData(null);
setAddModalOpen(true);
};
@@ -44,7 +42,7 @@ export default function VehicleList() {
};
const handleAddVehicle = async (data: {
- vehicleName: string;
+ name: string;
company: string;
modelName: string;
chargeType: string;
@@ -60,7 +58,7 @@ export default function VehicleList() {
};
const handleUpdate = async (
- id: number,
+ id: string,
name: string,
company: string,
modelName: string,
@@ -95,24 +93,24 @@ export default function VehicleList() {
{ id: "action", label: "Action", align: "center" },
];
- const filteredVehicles = vehicles?.filter(
- (vehicle) =>
- vehicle.name?.toLowerCase().includes(searchTerm.toLowerCase()) ||
- vehicle.company?.toLowerCase().includes(searchTerm.toLowerCase()) ||
- vehicle.modelName
- ?.toLowerCase()
- .includes(searchTerm.toLowerCase()) ||
- vehicle.chargeType
- ?.toLowerCase()
- .includes(searchTerm.toLowerCase()) ||
- vehicle.imageUrl?.toLowerCase().includes(searchTerm.toLowerCase())
- );
+ // const filteredVehicles = vehicles?.filter(
+ // (vehicle) =>
+ // vehicle.name?.toLowerCase().includes(searchTerm.toLowerCase()) ||
+ // vehicle.company?.toLowerCase().includes(searchTerm.toLowerCase()) ||
+ // vehicle.modelName
+ // ?.toLowerCase()
+ // .includes(searchTerm.toLowerCase()) ||
+ // vehicle.chargeType
+ // ?.toLowerCase()
+ // .includes(searchTerm.toLowerCase()) ||
+ // vehicle.imageUrl?.toLowerCase().includes(searchTerm.toLowerCase())
+ // );
- const categoryRows = filteredVehicles?.length
- ? filteredVehicles?.map(
+ const categoryRows = vehicles?.length
+ ? vehicles?.map(
(
vehicle: {
- id: number;
+ id: string;
name: string;
company: string;
modelName: string;
@@ -132,8 +130,6 @@ export default function VehicleList() {
)
: [];
-
-
return (
<>
-
>
);
}
diff --git a/src/redux/slices/VehicleSlice.ts b/src/redux/slices/VehicleSlice.ts
index 31cefed..77c3310 100644
--- a/src/redux/slices/VehicleSlice.ts
+++ b/src/redux/slices/VehicleSlice.ts
@@ -8,7 +8,7 @@ interface VehicleBrand {
}
interface Vehicle {
- brandId: string;
+ brandId?: string;
id: string;
name: string;
company: string;
@@ -50,10 +50,8 @@ export const fetchVehicleBrands = createAsyncThunk<
}
});
-
-
export const vehicleList = createAsyncThunk<
- Vehicle,
+ Vehicle[],
void,
{ rejectValue: string }
>("fetchVehicles", async (_, { rejectWithValue }) => {
@@ -180,12 +178,9 @@ const vehicleSlice = createSlice({
state.vehicles.push(action.payload);
}
)
- .addCase(
- addVehicle.rejected,
- (state, action: PayloadAction) => {
- state.loading = false;
- }
- )
+ .addCase(addVehicle.rejected, (state) => {
+ state.loading = false;
+ })
.addCase(updateVehicle.pending, (state) => {
state.loading = true;
})
diff --git a/src/redux/slices/managerSlice.ts b/src/redux/slices/managerSlice.ts
index e81282c..a32cf0f 100644
--- a/src/redux/slices/managerSlice.ts
+++ b/src/redux/slices/managerSlice.ts
@@ -6,12 +6,12 @@ import { toast } from "sonner";
interface Manager {
Manager: any;
- id: number;
+ id: string;
name: string;
email: string;
phone: string;
stationId: string;
- chargingStation:string;
+ chargingStation:{name:string, registeredAddress:string};
}
interface ManagerState {
@@ -74,7 +74,7 @@ export const addManager = createAsyncThunk<
// Update Manager (Async Thunk)
export const updateManager = createAsyncThunk<
Manager,
- { id: number; managerData: Manager },
+ { id: string; managerData: Manager },
{ rejectValue: string }
>("updateManager", async ({ id, managerData }, { rejectWithValue }) => {
if (!id) {
diff --git a/src/redux/slices/slotSlice.ts b/src/redux/slices/slotSlice.ts
index 1dbc59b..04a9b58 100644
--- a/src/redux/slices/slotSlice.ts
+++ b/src/redux/slices/slotSlice.ts
@@ -88,17 +88,23 @@ export const createSlot = createAsyncThunk<
// Update Slot details
export const updateSlot = createAsyncThunk<
Slot,
- { id: string; startTime: string; endTime: string; isAvailable: boolean }, // Argument type (slot update data)
+ {
+ id: string;
+ startTime: string;
+ endTime: string;
+ isAvailable: boolean;
+ },
{ rejectValue: string }
>("slots/updateSlot", async ({ id, ...slotData }, { rejectWithValue }) => {
try {
- const response = await http.patch(
- `/update-availability/${id}`,
- slotData // slotData is being sent here, but we should ensure its structure is correct
- );
+ const response = await http.patch(`/update-availability/${id}`, {
+ ...slotData,
+ // Ensure data matches exactly what backend expects
+ startHour: slotData.startTime,
+ endHour: slotData.endTime,
+ });
toast.success("Slot updated successfully");
- console.log("Slots", response.data.data);
- return response.data.data; // Return updated slot data
+ return response.data.data;
} catch (error: any) {
toast.error("Error updating the slot: " + error?.message);
return rejectWithValue(