From e038428607611a5e63eda941b19303f545a13ffd Mon Sep 17 00:00:00 2001 From: jaanvi Date: Fri, 28 Mar 2025 14:58:24 +0530 Subject: [PATCH] add new changes in station and logo --- public/Group 14.svg | 4 + public/evLogo.png | Bin 0 -> 8099 bytes src/components/AddStationModal/index.tsx | 2 +- src/components/CustomTable/index.tsx | 91 ++++++++++++---------- src/components/EditManagerModal/index.tsx | 14 +++- src/components/EditSlotModal/index.tsx | 21 ++--- src/components/EditStationModal/index.tsx | 45 +++++++---- src/components/Modals/ViewModal/index.tsx | 1 + src/components/SideMenu/index.tsx | 26 +++++-- src/pages/Auth/Login/index.tsx | 7 +- src/pages/EvSlotList/index.tsx | 59 +++++++------- src/pages/ManagerList/index.tsx | 80 +++++-------------- src/pages/VehicleList/index.tsx | 43 +++++----- src/redux/slices/VehicleSlice.ts | 15 ++-- src/redux/slices/managerSlice.ts | 6 +- src/redux/slices/slotSlice.ts | 20 +++-- 16 files changed, 219 insertions(+), 215 deletions(-) create mode 100644 public/Group 14.svg create mode 100644 public/evLogo.png 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 0000000000000000000000000000000000000000..0c96ea10a64480ffa4a9234de9932920109b4394 GIT binary patch literal 8099 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 VviQ6A! z^#c%Jba)5D14EsgMyQ6?oBRM2n0VL7wEJ&uVSOG1+Nqf%n7wO0fy6y2av|<1ZX8a7{G(zJpiBL{^-pgu1uJ+Od4!D!{=W( zv8h)UfDY@8t5kmdhbNvi)hD)}6KG;-t)42dJi%Z2>la{aJkm~Bpf7|09QU|6JBqGX z6wYs8!37LAcOcC_MWeX@;1DFT< + /> )) ) : ( 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 }) { }} > Logo 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(