dev-jaanvi #1
|
@ -8,7 +8,6 @@ import {
|
||||||
InputAdornment,
|
InputAdornment,
|
||||||
Select,
|
Select,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
InputLabel,
|
|
||||||
FormControl,
|
FormControl,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import CloseIcon from "@mui/icons-material/Close";
|
import CloseIcon from "@mui/icons-material/Close";
|
||||||
|
@ -21,12 +20,7 @@ import { RootState } from "../../redux/reducers.ts";
|
||||||
import { stationList } from "../../redux/slices/stationSlice.ts";
|
import { stationList } from "../../redux/slices/stationSlice.ts";
|
||||||
import { autofillFix } from "../../shared-theme/customizations/autoFill.tsx";
|
import { autofillFix } from "../../shared-theme/customizations/autoFill.tsx";
|
||||||
|
|
||||||
export default function AddManagerModal({
|
export default function AddManagerModal({ open, handleClose }) {
|
||||||
open,
|
|
||||||
handleClose,
|
|
||||||
handleAddManager,
|
|
||||||
// Assume the stations prop contains a list of station objects with 'id' and 'name'
|
|
||||||
}) {
|
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
|
@ -34,7 +28,10 @@ export default function AddManagerModal({
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
reset,
|
reset,
|
||||||
} = useForm();
|
clearErrors,
|
||||||
|
} = useForm({
|
||||||
|
mode: "onChange", // Trigger validation on change for real-time feedback
|
||||||
|
});
|
||||||
const [showPassword, setShowPassword] = useState(false);
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
const stations = useSelector(
|
const stations = useSelector(
|
||||||
(state: RootState) => state?.stationReducer.stations
|
(state: RootState) => state?.stationReducer.stations
|
||||||
|
@ -46,7 +43,6 @@ export default function AddManagerModal({
|
||||||
|
|
||||||
// Handle form submission
|
// Handle form submission
|
||||||
const onSubmit = async (data: any) => {
|
const onSubmit = async (data: any) => {
|
||||||
// Retrieve the stationId based on the stationName selected
|
|
||||||
const selectedStation = stations.find(
|
const selectedStation = stations.find(
|
||||||
(station) => station.name === data.stationName
|
(station) => station.name === data.stationName
|
||||||
);
|
);
|
||||||
|
@ -55,22 +51,29 @@ export default function AddManagerModal({
|
||||||
email: data.email,
|
email: data.email,
|
||||||
phone: data.phone,
|
phone: data.phone,
|
||||||
password: data.password,
|
password: data.password,
|
||||||
stationId: selectedStation?.id, // Send stationId here
|
stationId: selectedStation?.id,
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Dispatch the addManager action
|
|
||||||
await dispatch(addManager(managerData));
|
await dispatch(addManager(managerData));
|
||||||
dispatch(managerList());
|
dispatch(managerList());
|
||||||
handleClose(); // Close modal after successful addition
|
clearErrors(); // Clear errors on successful submission
|
||||||
reset(); // Reset form fields
|
reset(); // Reset form fields on successful submission
|
||||||
|
handleClose(); // Close modal
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error adding manager:", error);
|
console.error("Error adding manager:", error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Handle modal close, clearing errors and resetting form
|
||||||
|
const handleModalClose = () => {
|
||||||
|
clearErrors(); // Clear errors when closing via close icon
|
||||||
|
reset(); // Reset form fields when closing via close icon
|
||||||
|
handleClose(); // Close modal
|
||||||
|
};
|
||||||
|
|
||||||
const togglePasswordVisibility = (e: React.MouseEvent) => {
|
const togglePasswordVisibility = (e: React.MouseEvent) => {
|
||||||
e.preventDefault(); // Prevent focus loss
|
e.preventDefault();
|
||||||
setShowPassword((prev) => !prev);
|
setShowPassword((prev) => !prev);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,9 +82,9 @@ export default function AddManagerModal({
|
||||||
open={open}
|
open={open}
|
||||||
onClose={(e, reason) => {
|
onClose={(e, reason) => {
|
||||||
if (reason === "backdropClick") {
|
if (reason === "backdropClick") {
|
||||||
return;
|
return; // Prevent closing on backdrop click
|
||||||
}
|
}
|
||||||
handleClose(); // Close modal when clicking cross or cancel
|
handleModalClose();
|
||||||
}}
|
}}
|
||||||
aria-labelledby="add-manager-modal"
|
aria-labelledby="add-manager-modal"
|
||||||
>
|
>
|
||||||
|
@ -92,7 +95,7 @@ export default function AddManagerModal({
|
||||||
left: "50%",
|
left: "50%",
|
||||||
transform: "translate(-50%, -50%)",
|
transform: "translate(-50%, -50%)",
|
||||||
width: 400,
|
width: 400,
|
||||||
bgcolor: "background.paper",
|
bgcolor: "#000000",
|
||||||
boxShadow: 24,
|
boxShadow: 24,
|
||||||
p: 3,
|
p: 3,
|
||||||
borderRadius: 2,
|
borderRadius: 2,
|
||||||
|
@ -106,10 +109,15 @@ export default function AddManagerModal({
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="h6" fontWeight={600} fontSize={"16px"}>
|
<Typography
|
||||||
|
variant="h6"
|
||||||
|
fontWeight={600}
|
||||||
|
fontSize={"16px"}
|
||||||
|
color="#D0E1E9"
|
||||||
|
>
|
||||||
Add Manager
|
Add Manager
|
||||||
</Typography>
|
</Typography>
|
||||||
<CustomIconButton onClick={handleClose}>
|
<CustomIconButton onClick={handleModalClose}>
|
||||||
<CloseIcon />
|
<CloseIcon />
|
||||||
</CustomIconButton>
|
</CustomIconButton>
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -122,7 +130,11 @@ export default function AddManagerModal({
|
||||||
{/* Manager Name */}
|
{/* Manager Name */}
|
||||||
<Box sx={{ display: "flex", gap: 2, mb: 2 }}>
|
<Box sx={{ display: "flex", gap: 2, mb: 2 }}>
|
||||||
<Box sx={{ flex: 1, ...autofillFix }}>
|
<Box sx={{ flex: 1, ...autofillFix }}>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
fontWeight={500}
|
||||||
|
color="#D0E1E9"
|
||||||
|
>
|
||||||
Manager Name
|
Manager Name
|
||||||
</Typography>
|
</Typography>
|
||||||
<CustomTextField
|
<CustomTextField
|
||||||
|
@ -159,7 +171,11 @@ export default function AddManagerModal({
|
||||||
{/* Station Dropdown */}
|
{/* Station Dropdown */}
|
||||||
<Box sx={{ display: "flex", gap: 2, mb: 2 }}>
|
<Box sx={{ display: "flex", gap: 2, mb: 2 }}>
|
||||||
<Box sx={{ flex: 1 }}>
|
<Box sx={{ flex: 1 }}>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
fontWeight={500}
|
||||||
|
color="#D0E1E9"
|
||||||
|
>
|
||||||
Select Station
|
Select Station
|
||||||
</Typography>
|
</Typography>
|
||||||
<FormControl
|
<FormControl
|
||||||
|
@ -167,13 +183,21 @@ export default function AddManagerModal({
|
||||||
size="small"
|
size="small"
|
||||||
error={!!errors.stationName}
|
error={!!errors.stationName}
|
||||||
>
|
>
|
||||||
<Select
|
<Controller
|
||||||
{...register("stationName", {
|
name="stationName"
|
||||||
|
control={control}
|
||||||
|
rules={{
|
||||||
required: "Station Name is required",
|
required: "Station Name is required",
|
||||||
})}
|
}}
|
||||||
|
render={({ field }) => (
|
||||||
|
<Select
|
||||||
|
{...field}
|
||||||
|
onChange={(e) =>
|
||||||
|
field.onChange(e.target.value)
|
||||||
|
} // Update form state
|
||||||
|
value={field.value || ""} // Ensure controlled value
|
||||||
sx={{ marginTop: 1 }}
|
sx={{ marginTop: 1 }}
|
||||||
displayEmpty
|
displayEmpty
|
||||||
defaultValue=""
|
|
||||||
renderValue={(selected) => {
|
renderValue={(selected) => {
|
||||||
if (!selected) {
|
if (!selected) {
|
||||||
return (
|
return (
|
||||||
|
@ -182,7 +206,6 @@ export default function AddManagerModal({
|
||||||
</Typography>
|
</Typography>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return selected;
|
return selected;
|
||||||
}}
|
}}
|
||||||
MenuProps={{
|
MenuProps={{
|
||||||
|
@ -209,6 +232,8 @@ export default function AddManagerModal({
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
</Select>
|
</Select>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
{errors.stationName && (
|
{errors.stationName && (
|
||||||
<Typography
|
<Typography
|
||||||
color="error"
|
color="error"
|
||||||
|
@ -226,7 +251,11 @@ export default function AddManagerModal({
|
||||||
<Box sx={{ display: "flex", gap: 2, mb: 2 }}>
|
<Box sx={{ display: "flex", gap: 2, mb: 2 }}>
|
||||||
{/* Email */}
|
{/* Email */}
|
||||||
<Box sx={{ flex: 1, ...autofillFix }}>
|
<Box sx={{ flex: 1, ...autofillFix }}>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
fontWeight={500}
|
||||||
|
color="#D0E1E9"
|
||||||
|
>
|
||||||
Email
|
Email
|
||||||
</Typography>
|
</Typography>
|
||||||
<CustomTextField
|
<CustomTextField
|
||||||
|
@ -243,7 +272,8 @@ export default function AddManagerModal({
|
||||||
required: "Email is required",
|
required: "Email is required",
|
||||||
pattern: {
|
pattern: {
|
||||||
value: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
|
value: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
|
||||||
message: "Invalid email address",
|
message:
|
||||||
|
"Please enter a valid email address (e.g., example@domain.com).",
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
@ -251,7 +281,11 @@ export default function AddManagerModal({
|
||||||
|
|
||||||
{/* Password */}
|
{/* Password */}
|
||||||
<Box sx={{ flex: 1, ...autofillFix }}>
|
<Box sx={{ flex: 1, ...autofillFix }}>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
fontWeight={500}
|
||||||
|
color="#D0E1E9"
|
||||||
|
>
|
||||||
Password
|
Password
|
||||||
</Typography>
|
</Typography>
|
||||||
<Controller
|
<Controller
|
||||||
|
@ -319,7 +353,11 @@ export default function AddManagerModal({
|
||||||
{/* Phone Number */}
|
{/* Phone Number */}
|
||||||
<Box sx={{ display: "flex", gap: 2, mb: 2 }}>
|
<Box sx={{ display: "flex", gap: 2, mb: 2 }}>
|
||||||
<Box sx={{ flex: 1, ...autofillFix }}>
|
<Box sx={{ flex: 1, ...autofillFix }}>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
fontWeight={500}
|
||||||
|
color="#D0E1E9"
|
||||||
|
>
|
||||||
Phone Number
|
Phone Number
|
||||||
</Typography>
|
</Typography>
|
||||||
<CustomTextField
|
<CustomTextField
|
||||||
|
@ -343,7 +381,7 @@ export default function AddManagerModal({
|
||||||
if (value.length > 14) {
|
if (value.length > 14) {
|
||||||
return "Phone number must be at most 14 digits";
|
return "Phone number must be at most 14 digits";
|
||||||
}
|
}
|
||||||
return true; // No errors
|
return true;
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
@ -361,12 +399,12 @@ export default function AddManagerModal({
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
sx={{
|
sx={{
|
||||||
backgroundColor: "#52ACDF",
|
backgroundColor: "#D0E1E9",
|
||||||
color: "white",
|
color: "#000000",
|
||||||
borderRadius: "8px",
|
borderRadius: "8px",
|
||||||
fontSize: "16px",
|
fontSize: "16px",
|
||||||
width: "117px",
|
width: "125px",
|
||||||
"&:hover": { backgroundColor: "#439BC1" },
|
"&:hover": { backgroundColor: "#DFECF1" },
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Add Manager
|
Add Manager
|
||||||
|
|
|
@ -35,6 +35,7 @@ export default function AddStationModal({
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
reset,
|
reset,
|
||||||
|
clearErrors,
|
||||||
} = useForm();
|
} = useForm();
|
||||||
|
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
@ -83,7 +84,11 @@ export default function AddStationModal({
|
||||||
.filter((vehicle) => selectedVehicles.includes(vehicle.name))
|
.filter((vehicle) => selectedVehicles.includes(vehicle.name))
|
||||||
.map((vehicle) => vehicle.id);
|
.map((vehicle) => vehicle.id);
|
||||||
};
|
};
|
||||||
|
const handleModalClose = () => {
|
||||||
|
clearErrors();
|
||||||
|
reset();
|
||||||
|
handleClose();
|
||||||
|
};
|
||||||
const onSubmit = (data: any) => {
|
const onSubmit = (data: any) => {
|
||||||
const vehicleIds = getVehicleIds(); // Get the ids of the selected vehicles
|
const vehicleIds = getVehicleIds(); // Get the ids of the selected vehicles
|
||||||
|
|
||||||
|
@ -95,7 +100,7 @@ export default function AddStationModal({
|
||||||
};
|
};
|
||||||
|
|
||||||
handleAddStation(payload);
|
handleAddStation(payload);
|
||||||
handleClose(); // Close modal after adding
|
handleClose();
|
||||||
reset();
|
reset();
|
||||||
setSelectedVehicles([]);
|
setSelectedVehicles([]);
|
||||||
setSelectedBrands([]); // Reset selected brands after submission
|
setSelectedBrands([]); // Reset selected brands after submission
|
||||||
|
@ -119,7 +124,7 @@ export default function AddStationModal({
|
||||||
left: "50%",
|
left: "50%",
|
||||||
transform: "translate(-50%, -50%)",
|
transform: "translate(-50%, -50%)",
|
||||||
width: 400,
|
width: 400,
|
||||||
bgcolor: "background.paper",
|
bgcolor: "#000000",
|
||||||
boxShadow: 24,
|
boxShadow: 24,
|
||||||
p: 3,
|
p: 3,
|
||||||
borderRadius: 2,
|
borderRadius: 2,
|
||||||
|
@ -133,10 +138,15 @@ export default function AddStationModal({
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="h6" fontWeight={600} fontSize={"16px"}>
|
<Typography
|
||||||
|
variant="h6"
|
||||||
|
fontWeight={600}
|
||||||
|
fontSize={"16px"}
|
||||||
|
color="#D0E1E9"
|
||||||
|
>
|
||||||
Add Charging Station
|
Add Charging Station
|
||||||
</Typography>
|
</Typography>
|
||||||
<CustomIconButton onClick={handleClose}>
|
<CustomIconButton onClick={handleModalClose}>
|
||||||
<CloseIcon />
|
<CloseIcon />
|
||||||
</CustomIconButton>
|
</CustomIconButton>
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -163,7 +173,11 @@ export default function AddStationModal({
|
||||||
...autofillFix,
|
...autofillFix,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
fontWeight={500}
|
||||||
|
color="#D0E1E9"
|
||||||
|
>
|
||||||
Station Name
|
Station Name
|
||||||
</Typography>
|
</Typography>
|
||||||
<CustomTextField
|
<CustomTextField
|
||||||
|
@ -199,7 +213,11 @@ export default function AddStationModal({
|
||||||
...autofillFix,
|
...autofillFix,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
fontWeight={500}
|
||||||
|
color="#D0E1E9"
|
||||||
|
>
|
||||||
Station Location
|
Station Location
|
||||||
</Typography>
|
</Typography>
|
||||||
<CustomTextField
|
<CustomTextField
|
||||||
|
@ -215,7 +233,7 @@ export default function AddStationModal({
|
||||||
}
|
}
|
||||||
{...register("registeredAddress", {
|
{...register("registeredAddress", {
|
||||||
required:
|
required:
|
||||||
"Registered Address is required",
|
"Station Location is required",
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -230,7 +248,11 @@ export default function AddStationModal({
|
||||||
width: "100%",
|
width: "100%",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
fontWeight={500}
|
||||||
|
color="#D0E1E9"
|
||||||
|
>
|
||||||
Total Slots
|
Total Slots
|
||||||
</Typography>
|
</Typography>
|
||||||
<CustomTextField
|
<CustomTextField
|
||||||
|
@ -270,6 +292,7 @@ export default function AddStationModal({
|
||||||
variant="body2"
|
variant="body2"
|
||||||
fontWeight={500}
|
fontWeight={500}
|
||||||
sx={{ mb: 1 }}
|
sx={{ mb: 1 }}
|
||||||
|
color="#D0E1E9"
|
||||||
>
|
>
|
||||||
Vehicle Brand
|
Vehicle Brand
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -283,7 +306,7 @@ export default function AddStationModal({
|
||||||
renderValue={(selected) => {
|
renderValue={(selected) => {
|
||||||
if (selected.length === 0) {
|
if (selected.length === 0) {
|
||||||
return (
|
return (
|
||||||
<Typography color="text.secondary">
|
<Typography color="#D0E1E9">
|
||||||
Choose Brands
|
Choose Brands
|
||||||
</Typography>
|
</Typography>
|
||||||
);
|
);
|
||||||
|
@ -316,6 +339,7 @@ export default function AddStationModal({
|
||||||
<Typography
|
<Typography
|
||||||
key={index}
|
key={index}
|
||||||
variant="body2"
|
variant="body2"
|
||||||
|
color="#454545"
|
||||||
>
|
>
|
||||||
{brand
|
{brand
|
||||||
? brand.name
|
? brand.name
|
||||||
|
@ -328,7 +352,7 @@ export default function AddStationModal({
|
||||||
{moreCount > 0 && (
|
{moreCount > 0 && (
|
||||||
<Typography
|
<Typography
|
||||||
variant="body2"
|
variant="body2"
|
||||||
color="textSecondary"
|
color="#454545"
|
||||||
>
|
>
|
||||||
+{moreCount} more
|
+{moreCount} more
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -385,6 +409,7 @@ export default function AddStationModal({
|
||||||
variant="body2"
|
variant="body2"
|
||||||
fontWeight={500}
|
fontWeight={500}
|
||||||
sx={{ mb: 1 }}
|
sx={{ mb: 1 }}
|
||||||
|
color="#D0E1E9"
|
||||||
>
|
>
|
||||||
Vehicle Name
|
Vehicle Name
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -402,7 +427,7 @@ export default function AddStationModal({
|
||||||
renderValue={(selected) => {
|
renderValue={(selected) => {
|
||||||
if (selected.length === 0) {
|
if (selected.length === 0) {
|
||||||
return (
|
return (
|
||||||
<Typography color="text.secondary">
|
<Typography color="#454545">
|
||||||
{selectedBrands.length ===
|
{selectedBrands.length ===
|
||||||
0
|
0
|
||||||
? "Select brand first"
|
? "Select brand first"
|
||||||
|
@ -433,6 +458,7 @@ export default function AddStationModal({
|
||||||
<Typography
|
<Typography
|
||||||
key={index}
|
key={index}
|
||||||
variant="body2"
|
variant="body2"
|
||||||
|
color="#454545"
|
||||||
>
|
>
|
||||||
{name}
|
{name}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -441,7 +467,7 @@ export default function AddStationModal({
|
||||||
{moreCount > 0 && (
|
{moreCount > 0 && (
|
||||||
<Typography
|
<Typography
|
||||||
variant="body2"
|
variant="body2"
|
||||||
color="textSecondary"
|
color="#454545"
|
||||||
>
|
>
|
||||||
+{moreCount} more
|
+{moreCount} more
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -501,12 +527,12 @@ export default function AddStationModal({
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
sx={{
|
sx={{
|
||||||
backgroundColor: "#52ACDF",
|
backgroundColor: "#D0E1E9",
|
||||||
color: "white",
|
color: "#000000",
|
||||||
borderRadius: "8px",
|
borderRadius: "8px",
|
||||||
fontSize: "16px",
|
fontSize: "16px",
|
||||||
width: "117px",
|
width: "117px",
|
||||||
"&:hover": { backgroundColor: "#439BC1" },
|
"&:hover": { backgroundColor: "#DFECF1" },
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Add Station
|
Add Station
|
||||||
|
|
|
@ -9,6 +9,7 @@ export const CustomIconButton = styled(IconButton)({
|
||||||
backgroundColor: "transparent",
|
backgroundColor: "transparent",
|
||||||
border: "none",
|
border: "none",
|
||||||
},
|
},
|
||||||
|
color: "#D0E1E9",
|
||||||
});
|
});
|
||||||
|
|
||||||
// Custom TextField with different placeholder color
|
// Custom TextField with different placeholder color
|
||||||
|
|
|
@ -92,7 +92,7 @@ export default function AddVehicleModal({
|
||||||
left: "50%",
|
left: "50%",
|
||||||
transform: "translate(-50%, -50%)",
|
transform: "translate(-50%, -50%)",
|
||||||
width: 400,
|
width: 400,
|
||||||
bgcolor: "background.paper",
|
bgcolor: "#000000",
|
||||||
boxShadow: 24,
|
boxShadow: 24,
|
||||||
p: 3,
|
p: 3,
|
||||||
borderRadius: 2,
|
borderRadius: 2,
|
||||||
|
@ -106,7 +106,12 @@ export default function AddVehicleModal({
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="h6" fontWeight={600} fontSize={"16px"}>
|
<Typography
|
||||||
|
variant="h6"
|
||||||
|
fontWeight={600}
|
||||||
|
fontSize={"16px"}
|
||||||
|
color="#D0E1E9"
|
||||||
|
>
|
||||||
Add Vehicle
|
Add Vehicle
|
||||||
</Typography>
|
</Typography>
|
||||||
<CustomIconButton onClick={handleClose}>
|
<CustomIconButton onClick={handleClose}>
|
||||||
|
@ -133,6 +138,7 @@ export default function AddVehicleModal({
|
||||||
variant="body2"
|
variant="body2"
|
||||||
fontWeight={500}
|
fontWeight={500}
|
||||||
mb={0.5}
|
mb={0.5}
|
||||||
|
color="#D0E1E9"
|
||||||
>
|
>
|
||||||
Vehicle Name
|
Vehicle Name
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -183,6 +189,7 @@ export default function AddVehicleModal({
|
||||||
variant="body2"
|
variant="body2"
|
||||||
fontWeight={500}
|
fontWeight={500}
|
||||||
mb={0.5}
|
mb={0.5}
|
||||||
|
color="#D0E1E9"
|
||||||
>
|
>
|
||||||
Company
|
Company
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -226,6 +233,7 @@ export default function AddVehicleModal({
|
||||||
variant="body2"
|
variant="body2"
|
||||||
fontWeight={500}
|
fontWeight={500}
|
||||||
mb={0.5}
|
mb={0.5}
|
||||||
|
color="#D0E1E9"
|
||||||
>
|
>
|
||||||
Model Name
|
Model Name
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -259,6 +267,7 @@ export default function AddVehicleModal({
|
||||||
variant="body2"
|
variant="body2"
|
||||||
fontWeight={500}
|
fontWeight={500}
|
||||||
mb={0.5}
|
mb={0.5}
|
||||||
|
color="#D0E1E9"
|
||||||
>
|
>
|
||||||
Charge Type
|
Charge Type
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -290,17 +299,22 @@ export default function AddVehicleModal({
|
||||||
...autofillFix,
|
...autofillFix,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="body2" fontWeight={500} mb={0.5}>
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
fontWeight={500}
|
||||||
|
mb={0.5}
|
||||||
|
color="#D0E1E9"
|
||||||
|
>
|
||||||
Upload Image
|
Upload Image
|
||||||
</Typography>
|
</Typography>
|
||||||
<Button
|
<Button
|
||||||
component="label"
|
component="label"
|
||||||
sx={{
|
sx={{
|
||||||
backgroundColor: "#52ACDF",
|
backgroundColor: "#D0E1E9",
|
||||||
color: "white",
|
color: "#000000",
|
||||||
borderRadius: "8px",
|
borderRadius: "8px",
|
||||||
width: "100%",
|
width: "100%",
|
||||||
"&:hover": { backgroundColor: "#52ACDF" },
|
"&:hover": { backgroundColor: "#DFECF1" },
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Choose Image
|
Choose Image
|
||||||
|
@ -346,12 +360,12 @@ export default function AddVehicleModal({
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
sx={{
|
sx={{
|
||||||
backgroundColor: "#52ACDF",
|
backgroundColor: "#D0E1E9",
|
||||||
color: "white",
|
color: "#00000",
|
||||||
borderRadius: "8px",
|
borderRadius: "8px",
|
||||||
fontSize: "16px",
|
fontSize: "16px",
|
||||||
width: "117px",
|
width: "117px",
|
||||||
"&:hover": { backgroundColor: "#439BC1" },
|
"&:hover": { backgroundColor: "#DFECF1" },
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Add Vehicle
|
Add Vehicle
|
||||||
|
|
|
@ -6,86 +6,126 @@ import TableCell, { tableCellClasses } from "@mui/material/TableCell";
|
||||||
import TableContainer from "@mui/material/TableContainer";
|
import TableContainer from "@mui/material/TableContainer";
|
||||||
import TableHead from "@mui/material/TableHead";
|
import TableHead from "@mui/material/TableHead";
|
||||||
import TableRow from "@mui/material/TableRow";
|
import TableRow from "@mui/material/TableRow";
|
||||||
import Paper, { paperClasses } from "@mui/material/Paper";
|
import Paper from "@mui/material/Paper";
|
||||||
import { adminList, deleteAdmin } from "../../redux/slices/adminSlice.ts";
|
|
||||||
import { vehicleList, deleteVehicle } from "../../redux/slices/VehicleSlice.ts";
|
|
||||||
|
|
||||||
import { deleteManager, managerList } from "../../redux/slices/managerSlice.ts";
|
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
InputAdornment,
|
InputAdornment,
|
||||||
Menu,
|
|
||||||
IconButton,
|
|
||||||
Pagination,
|
Pagination,
|
||||||
TextField,
|
TextField,
|
||||||
Typography,
|
Typography,
|
||||||
|
IconButton,
|
||||||
|
Menu,
|
||||||
|
MenuItem,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
|
import MoreVertIcon from "@mui/icons-material/MoreVert";
|
||||||
|
import VisibilityIcon from "@mui/icons-material/Visibility";
|
||||||
import EditIcon from "@mui/icons-material/Edit";
|
import EditIcon from "@mui/icons-material/Edit";
|
||||||
import DeleteIcon from "@mui/icons-material/Delete";
|
import DeleteIcon from "@mui/icons-material/Delete";
|
||||||
jaanvi marked this conversation as resolved
Outdated
|
|||||||
import VisibilityIcon from "@mui/icons-material/Visibility";
|
import SearchIcon from "@mui/icons-material/Search";
|
||||||
jaanvi marked this conversation as resolved
Outdated
VishalMaurya
commented
Don't use the hardcoded color codes Don't use the hardcoded color codes
|
|||||||
import MoreHorizRoundedIcon from "@mui/icons-material/MoreHorizRounded";
|
import ArrowUpwardIcon from "@mui/icons-material/ArrowUpward";
|
||||||
import DeleteModal from "../Modals/DeleteModal/index.tsx";
|
import ArrowDownwardIcon from "@mui/icons-material/ArrowDownward";
|
||||||
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { AppDispatch, RootState } from "../../redux/store/store.ts";
|
import { AppDispatch, RootState } from "../../redux/store/store.ts";
|
||||||
|
import DeleteModal from "../Modals/DeleteModal/index.tsx";
|
||||||
import ViewModal from "../Modals/ViewModal/index.tsx";
|
import ViewModal from "../Modals/ViewModal/index.tsx";
|
||||||
import VehicleViewModal from "../Modals/VehicleViewModal/index.tsx";
|
import VehicleViewModal from "../Modals/VehicleViewModal/index.tsx";
|
||||||
|
import ManagerViewModal from "../Modals/ViewManagerModal/";
|
||||||
import SearchIcon from "@mui/icons-material/Search";
|
|
||||||
import TuneIcon from "@mui/icons-material/Tune";
|
|
||||||
import { CustomIconButton } from "../AddUserModal/styled.css";
|
|
||||||
import ManagerViewModal from "../Modals/ViewManagerModal/index.tsx";
|
|
||||||
import UserViewModal from "../Modals/UserViewModal/index.tsx";
|
import UserViewModal from "../Modals/UserViewModal/index.tsx";
|
||||||
|
import StationViewModal from "../Modals/StationViewModal/index.tsx";
|
||||||
|
import { adminList, deleteAdmin } from "../../redux/slices/adminSlice.ts";
|
||||||
|
import { vehicleList, deleteVehicle } from "../../redux/slices/VehicleSlice.ts";
|
||||||
|
import { deleteManager, managerList } from "../../redux/slices/managerSlice.ts";
|
||||||
import { deleteUser, userList } from "../../redux/slices/userSlice.ts";
|
import { deleteUser, userList } from "../../redux/slices/userSlice.ts";
|
||||||
import { deleteStation, stationList } from "../../redux/slices/stationSlice.ts";
|
import { deleteStation, stationList } from "../../redux/slices/stationSlice.ts";
|
||||||
import StationViewModal from "../Modals/StationViewModal/index.tsx";
|
|
||||||
import {
|
import {
|
||||||
deleteSlot,
|
deleteSlot,
|
||||||
fetchAvailableSlots,
|
fetchAvailableSlots,
|
||||||
} from "../../redux/slices/slotSlice.ts";
|
} from "../../redux/slices/slotSlice.ts";
|
||||||
import { bookingList, deleteBooking } from "../../redux/slices/bookSlice.ts";
|
import { bookingList, deleteBooking } from "../../redux/slices/bookSlice.ts";
|
||||||
import AddCircleIcon from "@mui/icons-material/AddCircle";
|
import {
|
||||||
|
deleteStationDetails,
|
||||||
|
stationDetailList,
|
||||||
|
} from "../../redux/slices/managerStationSlice.ts";
|
||||||
|
import { CustomIconButton } from "../AddUserModal/styled.css.tsx";
|
||||||
import { autofillFix } from "../../shared-theme/customizations/autoFill.tsx";
|
import { autofillFix } from "../../shared-theme/customizations/autoFill.tsx";
|
||||||
import ArrowUpwardIcon from "@mui/icons-material/ArrowUpward";
|
|
||||||
import ArrowDownwardIcon from "@mui/icons-material/ArrowDownward";
|
// Styled Components
|
||||||
import { deleteStationDetails, stationDetailList } from "../../redux/slices/managerStationSlice.ts";
|
|
||||||
import ManagerStationDetails from "../../pages/ManagerStationDetails/index.tsx";
|
|
||||||
// Styled components for customization
|
|
||||||
const StyledTableCell = styled(TableCell)(({ theme }) => ({
|
const StyledTableCell = styled(TableCell)(({ theme }) => ({
|
||||||
[`&.${tableCellClasses.body}`]: {
|
|
||||||
fontSize: "16px",
|
|
||||||
borderBottom: "1px solid rgba(87, 85, 85, 0.53)",
|
|
||||||
color: "#000000",
|
|
||||||
backgroundColor: "#D0E1E9",
|
|
||||||
},
|
|
||||||
[`&.${tableCellClasses.head}`]: {
|
[`&.${tableCellClasses.head}`]: {
|
||||||
backgroundColor: "#000000",
|
backgroundColor: "#000000",
|
||||||
color: "#D0E1E9",
|
color: "#D0E1E9",
|
||||||
|
fontWeight: 600,
|
||||||
|
fontSize: "16px",
|
||||||
|
padding: "12px 16px",
|
||||||
borderBottom: "none",
|
borderBottom: "none",
|
||||||
//borderRight: "1px solid rgba(141, 135, 135, 0.51)",
|
|
||||||
position: "sticky",
|
position: "sticky",
|
||||||
top: 0,
|
top: 0,
|
||||||
zIndex: 10,
|
zIndex: 10,
|
||||||
|
transition: "background-color 0.2s ease",
|
||||||
|
"&:hover": {
|
||||||
|
backgroundColor: "#2A2A2A",
|
||||||
|
cursor: "pointer",
|
||||||
|
},
|
||||||
|
// Make the "Action" header cell sticky
|
||||||
|
"&.action-cell": {
|
||||||
|
right: 0,
|
||||||
|
zIndex: 11, // Higher z-index to ensure it stays above other headers
|
||||||
|
boxShadow: "-4px 0 8px rgba(0, 0, 0, 0.1)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[`&.${tableCellClasses.body}`]: {
|
||||||
|
fontSize: "16px",
|
||||||
|
padding: "12px 16px",
|
||||||
|
borderBottom: "1px solid rgba(255, 255, 255, 0.1)",
|
||||||
|
color: "#333333",
|
||||||
|
transition: "background-color 0.2s ease",
|
||||||
|
// Make the "Action" body cell sticky
|
||||||
|
"&.action-cell": {
|
||||||
|
position: "sticky",
|
||||||
|
right: 0,
|
||||||
|
zIndex: 2,
|
||||||
|
boxShadow: "-4px 0 8px rgba(0, 0, 0, 0.1)",
|
||||||
|
backgroundColor: "#DFECF1", // Match row background
|
||||||
|
"&:hover": {
|
||||||
|
backgroundColor: "#D0E1E9", // Match row hover background
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledTableRow = styled(TableRow)(({ theme }) => ({
|
const StyledTableRow = styled(TableRow)(({ theme }) => ({
|
||||||
|
backgroundColor: "#DFECF1",
|
||||||
|
transition: "background-color 0.2s ease",
|
||||||
|
"&:hover": {
|
||||||
backgroundColor: "#D0E1E9",
|
backgroundColor: "#D0E1E9",
|
||||||
"& td, th": {
|
},
|
||||||
|
"& td, & th": {
|
||||||
borderColor: "#454545",
|
borderColor: "#454545",
|
||||||
borderWidth: "1px",
|
borderWidth: "1px",
|
||||||
borderBottom: "1px solid #454545",
|
borderBottom: "1px solid #454545",
|
||||||
color: "#000000",
|
|
||||||
backgroundColor: "#D0E1E9",
|
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const StyledTableContainer = styled(TableContainer)(({ theme }) => ({
|
||||||
|
borderRadius: "12px",
|
||||||
|
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.1)",
|
||||||
|
"&::-webkit-scrollbar": {
|
||||||
|
height: "6px",
|
||||||
|
},
|
||||||
|
"&::-webkit-scrollbar-track": {
|
||||||
|
background: "#D0E1E9",
|
||||||
|
},
|
||||||
|
"&::-webkit-scrollbar-thumb": {
|
||||||
|
background: "#000000",
|
||||||
|
borderRadius: "3px",
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Interfaces
|
||||||
export interface Column {
|
export interface Column {
|
||||||
id: string;
|
id: string;
|
||||||
label: string;
|
label: string;
|
||||||
align?: "left" | "center" | "right";
|
align?: "left" | "center" | "right";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Row {
|
interface Row {
|
||||||
|
@ -102,11 +142,16 @@ interface CustomTableProps {
|
||||||
setViewModal: Function;
|
setViewModal: Function;
|
||||||
deleteModal: boolean;
|
deleteModal: boolean;
|
||||||
handleStatusToggle?: (id: string, currentStatus: number | boolean) => void;
|
handleStatusToggle?: (id: string, currentStatus: number | boolean) => void;
|
||||||
tableType: string; // Adding tableType prop to change header text dynamically
|
tableType: string;
|
||||||
handleClickOpen?: () => void;
|
handleClickOpen?: () => void;
|
||||||
statusField?: string; // Optional field to indicate the status column
|
statusField?: string;
|
||||||
statusValue?: boolean; // Optional normalized status value
|
statusValue?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sorting State Interface
|
||||||
|
interface SortConfig {
|
||||||
|
key: string;
|
||||||
|
direction: "asc" | "desc" | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CustomTable: React.FC<CustomTableProps> = ({
|
const CustomTable: React.FC<CustomTableProps> = ({
|
||||||
|
@ -123,18 +168,19 @@ const CustomTable: React.FC<CustomTableProps> = ({
|
||||||
handleClickOpen,
|
handleClickOpen,
|
||||||
}) => {
|
}) => {
|
||||||
const dispatch = useDispatch<AppDispatch>();
|
const dispatch = useDispatch<AppDispatch>();
|
||||||
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
|
||||||
const [selectedRow, setSelectedRow] = React.useState<Row | null>(null);
|
const [selectedRow, setSelectedRow] = React.useState<Row | null>(null);
|
||||||
const [searchQuery, setSearchQuery] = React.useState("");
|
const [searchQuery, setSearchQuery] = React.useState("");
|
||||||
const [currentPage, setCurrentPage] = React.useState(1);
|
const [currentPage, setCurrentPage] = React.useState(1);
|
||||||
|
const [sortConfig, setSortConfig] = React.useState<SortConfig>({
|
||||||
|
key: "",
|
||||||
|
direction: null,
|
||||||
|
});
|
||||||
|
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
||||||
|
const [menuRow, setMenuRow] = React.useState<Row | null>(null);
|
||||||
const usersPerPage = 10;
|
const usersPerPage = 10;
|
||||||
const { user } = useSelector((state: RootState) => state?.profileReducer);
|
const { user } = useSelector((state: RootState) => state?.profileReducer);
|
||||||
const open = Boolean(anchorEl);
|
|
||||||
const [sortOrder, setSortOrder] = React.useState<"asc" | "desc" | null>(
|
|
||||||
null
|
|
||||||
);
|
|
||||||
// ... [imports remain the same, no changes needed] ...
|
|
||||||
|
|
||||||
|
// Helper Functions
|
||||||
const getTitleByType = (type: string) => {
|
const getTitleByType = (type: string) => {
|
||||||
const titles: { [key: string]: string } = {
|
const titles: { [key: string]: string } = {
|
||||||
admin: "Admins",
|
admin: "Admins",
|
||||||
|
@ -143,9 +189,9 @@ const CustomTable: React.FC<CustomTableProps> = ({
|
||||||
manager: "Managers",
|
manager: "Managers",
|
||||||
"all-managers": "Managers",
|
"all-managers": "Managers",
|
||||||
vehicle: "Vehicles",
|
vehicle: "Vehicles",
|
||||||
station: "Charging Station",
|
station: "Charging Stations",
|
||||||
"external-station": "Charging Station",
|
"external-station": "Charging Stations",
|
||||||
booking: "Booking",
|
booking: "Bookings",
|
||||||
slots: "Slots",
|
slots: "Slots",
|
||||||
"all-available-slots": "Available Slots",
|
"all-available-slots": "Available Slots",
|
||||||
"manager-station": "Station Details",
|
"manager-station": "Station Details",
|
||||||
|
@ -196,23 +242,76 @@ const CustomTable: React.FC<CustomTableProps> = ({
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClick = (event: React.MouseEvent<HTMLElement>, row: Row) => {
|
|
||||||
setAnchorEl(event.currentTarget);
|
|
||||||
setSelectedRow(row);
|
|
||||||
setRowData(row);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleClose = () => {
|
|
||||||
setAnchorEl(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
const isImage = (value: any) => {
|
const isImage = (value: any) => {
|
||||||
if (typeof value === "string") {
|
if (typeof value === "string") {
|
||||||
return value.startsWith("http") || value.startsWith("data:image"); // Check for URL or base64 image
|
return value.startsWith("http") || value.startsWith("data:image");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Sorting Logic
|
||||||
|
const handleSort = (key: string) => {
|
||||||
|
setSortConfig((prev) => {
|
||||||
|
if (prev.key === key) {
|
||||||
|
if (prev.direction === "asc") return { key, direction: "desc" };
|
||||||
|
if (prev.direction === "desc") return { key, direction: null };
|
||||||
|
return { key, direction: "asc" };
|
||||||
|
}
|
||||||
|
return { key, direction: "asc" };
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const sortedRows = React.useMemo(() => {
|
||||||
|
if (!sortConfig.key || !sortConfig.direction) return [...rows];
|
||||||
|
|
||||||
|
return [...rows].sort((a, b) => {
|
||||||
|
const aValue = a[sortConfig.key];
|
||||||
|
const bValue = b[sortConfig.key];
|
||||||
|
|
||||||
|
if (aValue == null && bValue == null) return 0;
|
||||||
|
if (aValue == null) return sortConfig.direction === "asc" ? 1 : -1;
|
||||||
|
if (bValue == null) return sortConfig.direction === "asc" ? -1 : 1;
|
||||||
|
|
||||||
|
if (typeof aValue === "number" && typeof bValue === "number") {
|
||||||
|
return sortConfig.direction === "asc"
|
||||||
|
? aValue - bValue
|
||||||
|
: bValue - aValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const aStr = String(aValue).toLowerCase();
|
||||||
|
const bStr = String(bValue).toLowerCase();
|
||||||
|
return sortConfig.direction === "asc"
|
||||||
|
? aStr.localeCompare(bStr)
|
||||||
|
: bStr.localeCompare(aStr);
|
||||||
|
});
|
||||||
|
}, [rows, sortConfig]);
|
||||||
|
|
||||||
|
// Filtering Logic
|
||||||
|
const filteredRows = sortedRows.filter((row) => {
|
||||||
|
if (!searchQuery.trim()) return true;
|
||||||
|
const lowerCaseQuery = searchQuery.toLowerCase().trim();
|
||||||
|
return (
|
||||||
|
(row.name && row.name.toLowerCase().includes(lowerCaseQuery)) ||
|
||||||
|
(row.registeredAddress &&
|
||||||
|
row.registeredAddress.toLowerCase().includes(lowerCaseQuery)) ||
|
||||||
|
(row.stationName &&
|
||||||
|
row.stationName.toLowerCase().includes(lowerCaseQuery))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Pagination Logic
|
||||||
|
const indexOfLastRow = currentPage * usersPerPage;
|
||||||
|
const indexOfFirstRow = indexOfLastRow - usersPerPage;
|
||||||
|
const currentRows = filteredRows.slice(indexOfFirstRow, indexOfLastRow);
|
||||||
|
|
||||||
|
const handlePageChange = (
|
||||||
|
_event: React.ChangeEvent<unknown>,
|
||||||
|
value: number
|
||||||
|
) => {
|
||||||
|
setCurrentPage(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Action Handlers
|
||||||
const handleDeleteButton = (id: string | undefined) => {
|
const handleDeleteButton = (id: string | undefined) => {
|
||||||
if (!id) {
|
if (!id) {
|
||||||
console.error("ID not found", id);
|
console.error("ID not found", id);
|
||||||
|
@ -221,36 +320,34 @@ const CustomTable: React.FC<CustomTableProps> = ({
|
||||||
|
|
||||||
switch (tableType) {
|
switch (tableType) {
|
||||||
case "admin":
|
case "admin":
|
||||||
dispatch(deleteAdmin(id || ""));
|
dispatch(deleteAdmin(id));
|
||||||
break;
|
break;
|
||||||
case "vehicle":
|
case "vehicle":
|
||||||
dispatch(deleteVehicle(id || ""));
|
dispatch(deleteVehicle(id));
|
||||||
break;
|
break;
|
||||||
case "manager":
|
case "manager":
|
||||||
dispatch(deleteManager(id || ""));
|
dispatch(deleteManager(id));
|
||||||
break;
|
break;
|
||||||
case "user":
|
case "user":
|
||||||
dispatch(deleteUser(id || ""));
|
dispatch(deleteUser(id));
|
||||||
break;
|
break;
|
||||||
case "station":
|
case "station":
|
||||||
dispatch(deleteStation(id || ""));
|
dispatch(deleteStation(id));
|
||||||
break;
|
break;
|
||||||
case "slots":
|
case "slots":
|
||||||
dispatch(deleteSlot(id || ""));
|
dispatch(deleteSlot(id));
|
||||||
break;
|
break;
|
||||||
case "booking":
|
case "booking":
|
||||||
dispatch(deleteBooking(id || ""));
|
dispatch(deleteBooking(id));
|
||||||
break;
|
break;
|
||||||
case "manager-station":
|
case "manager-station":
|
||||||
dispatch(deleteStationDetails(id || ""));
|
dispatch(deleteStationDetails(id));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
console.error("Unknown table type:", tableType);
|
console.error("Unknown table type:", tableType);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setDeleteModal(false); // Close the modal only after deletion
|
setDeleteModal(false);
|
||||||
handleClose();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleViewButton = (id: string | undefined) => {
|
const handleViewButton = (id: string | undefined) => {
|
||||||
|
@ -284,62 +381,55 @@ const CustomTable: React.FC<CustomTableProps> = ({
|
||||||
console.error("Unknown table type:", tableType);
|
console.error("Unknown table type:", tableType);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setViewModal(false);
|
setViewModal(false);
|
||||||
};
|
};
|
||||||
const handleToggleStatus = () => {
|
|
||||||
if (selectedRow) {
|
|
||||||
handleStatusToggle?.(selectedRow.id, !selectedRow.statusValue); // Toggle the boolean statusValue
|
|
||||||
}
|
|
||||||
handleClose();
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSort = () => {
|
|
||||||
setSortOrder((prevSortOrder) =>
|
|
||||||
prevSortOrder === "asc" ? "desc" : "asc"
|
|
||||||
);
|
|
||||||
};
|
|
||||||
const handleEditButton = (row: Row) => {
|
const handleEditButton = (row: Row) => {
|
||||||
setModalOpen(true);
|
setModalOpen(true);
|
||||||
setRowData(row);
|
setRowData(row);
|
||||||
};
|
};
|
||||||
|
|
||||||
const sortedRows = React.useMemo(() => {
|
// Menu Handlers
|
||||||
let sorted = [...rows];
|
const handleMenuOpen = (event: React.MouseEvent<HTMLElement>, row: Row) => {
|
||||||
if (sortOrder) {
|
setAnchorEl(event.currentTarget);
|
||||||
sorted.sort((a, b) => {
|
setMenuRow(row);
|
||||||
if (a.name < b.name) return sortOrder === "asc" ? -1 : 1;
|
};
|
||||||
if (a.name > b.name) return sortOrder === "asc" ? 1 : -1;
|
|
||||||
return 0;
|
const handleMenuClose = () => {
|
||||||
});
|
setAnchorEl(null);
|
||||||
|
setMenuRow(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMenuAction = (action: string) => {
|
||||||
|
if (!menuRow) return;
|
||||||
|
switch (action) {
|
||||||
|
case "view":
|
||||||
|
setSelectedRow(menuRow);
|
||||||
|
setViewModal(true);
|
||||||
|
break;
|
||||||
|
case "edit":
|
||||||
|
handleEditButton(menuRow);
|
||||||
|
break;
|
||||||
|
case "delete":
|
||||||
|
setDeleteModal(true);
|
||||||
|
setSelectedRow(menuRow);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return sorted;
|
handleMenuClose();
|
||||||
}, [rows, sortOrder]);
|
|
||||||
const filteredRows = sortedRows.filter((row) => {
|
|
||||||
if (!searchQuery.trim()) return true;
|
|
||||||
const lowerCaseQuery = searchQuery.toLowerCase().trim();
|
|
||||||
return (
|
|
||||||
(row.name && row.name.toLowerCase().includes(lowerCaseQuery)) ||
|
|
||||||
(row.registeredAddress &&
|
|
||||||
row.registeredAddress.toLowerCase().includes(lowerCaseQuery)) ||
|
|
||||||
(row.stationName &&
|
|
||||||
row.stationName.toLowerCase().includes(lowerCaseQuery))
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
const indexOfLastRow = currentPage * usersPerPage;
|
|
||||||
const indexOfFirstRow = indexOfLastRow - usersPerPage;
|
|
||||||
const currentRows = filteredRows.slice(indexOfFirstRow, indexOfLastRow);
|
|
||||||
|
|
||||||
const handlePageChange = (
|
|
||||||
_event: React.ChangeEvent<unknown>,
|
|
||||||
value: number
|
|
||||||
) => {
|
|
||||||
setCurrentPage(value);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ width: "100%", padding: "24px", borderRadius: "12px" }}>
|
<Box
|
||||||
|
sx={{
|
||||||
|
width: "100%",
|
||||||
|
padding: "24px",
|
||||||
|
backgroundColor: "#D0E1E9",
|
||||||
|
borderRadius: "12px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* Header Section */}
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
|
@ -353,48 +443,47 @@ const handleToggleStatus = () => {
|
||||||
>
|
>
|
||||||
<Typography
|
<Typography
|
||||||
sx={{
|
sx={{
|
||||||
color: "#000000",
|
|
||||||
fontWeight: 600,
|
fontWeight: 600,
|
||||||
fontSize: "30px",
|
fontSize: "30px",
|
||||||
|
letterSpacing: "-0.5px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{getTitleByType(tableType)}
|
{getTitleByType(tableType)}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
{/* Right Side: Search + Add */}
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
gap: 2,
|
gap: 2,
|
||||||
flexWrap: "wrap",
|
flexWrap: "wrap",
|
||||||
justifyContent: "flex-end",
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TextField
|
<TextField
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
placeholder="Search"
|
placeholder="Search"
|
||||||
sx={{
|
sx={{
|
||||||
width: { xs: "100%", sm: "300px", md: "300px" },
|
width: { xs: "100%", sm: "300px" },
|
||||||
input: { color: "#454545" },
|
...autofillFix,
|
||||||
"& .MuiOutlinedInput-root": {
|
"& .MuiOutlinedInput-root": {
|
||||||
borderRadius: "12px",
|
borderRadius: "8px",
|
||||||
height: "44px",
|
height: "40px",
|
||||||
"& fieldset": { borderColor: "#454545" },
|
backgroundColor: "#FFFFFF",
|
||||||
"&:hover fieldset": { borderColor: "#454545" },
|
"& fieldset": { borderColor: "#D1D5DB" },
|
||||||
|
"&:hover fieldset": { borderColor: "#9CA3AF" },
|
||||||
"&.Mui-focused fieldset": {
|
"&.Mui-focused fieldset": {
|
||||||
borderColor: "#52ACDF",
|
borderColor: "#3B82F6",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"& .MuiInputBase-input::placeholder": {
|
"& .MuiInputBase-input": {
|
||||||
color: "#454545",
|
fontSize: "14px",
|
||||||
opacity: 1,
|
color: "#1A1A1A",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
startAdornment: (
|
startAdornment: (
|
||||||
<InputAdornment position="start">
|
<InputAdornment position="start">
|
||||||
<SearchIcon sx={{ color: "#454545" }} />
|
<SearchIcon sx={{ color: "#6B7280" }} />
|
||||||
</InputAdornment>
|
</InputAdornment>
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
|
@ -402,16 +491,21 @@ const handleToggleStatus = () => {
|
||||||
onChange={(e) => setSearchQuery(e.target.value)}
|
onChange={(e) => setSearchQuery(e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Conditionally show Add Button */}
|
|
||||||
{shouldShowAddButton(user?.userType, tableType) && (
|
{shouldShowAddButton(user?.userType, tableType) && (
|
||||||
<Button
|
<Button
|
||||||
sx={{
|
sx={{
|
||||||
backgroundColor: "#000000",
|
backgroundColor: "#000000",
|
||||||
color: "white",
|
color: "#FFFFFF",
|
||||||
minWidth: "115px",
|
fontWeight: 600,
|
||||||
fontSize: "16px",
|
fontSize: "14px",
|
||||||
paddingX: 2,
|
padding: "8px 16px",
|
||||||
"&:hover": { backgroundColor: "#000000" },
|
borderRadius: "8px",
|
||||||
|
textTransform: "none",
|
||||||
|
"&:hover": {
|
||||||
|
backgroundColor: "#454545",
|
||||||
|
boxShadow: "0 2px 8px rgba(0, 0, 0, 0.15)",
|
||||||
|
},
|
||||||
|
transition: "all 0.2s ease",
|
||||||
}}
|
}}
|
||||||
onClick={handleClickOpen}
|
onClick={handleClickOpen}
|
||||||
>
|
>
|
||||||
|
@ -422,33 +516,58 @@ const handleToggleStatus = () => {
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Table Section */}
|
{/* Table Section */}
|
||||||
<TableContainer
|
<StyledTableContainer>
|
||||||
component={Paper}
|
|
||||||
sx={{
|
|
||||||
marginTop: "24px",
|
|
||||||
|
|
||||||
borderRadius: "12px",
|
|
||||||
overflow: "auto",
|
|
||||||
maxWidth: "100%",
|
|
||||||
"&::-webkit-scrollbar": {
|
|
||||||
height: "3px",
|
|
||||||
},
|
|
||||||
"&::-webkit-scrollbar-track": {
|
|
||||||
background: "#1C1C1C",
|
|
||||||
},
|
|
||||||
"&::-webkit-scrollbar-thumb": {
|
|
||||||
background: "#52ACDF",
|
|
||||||
borderRadius: "4px",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Table sx={{ minWidth: "750px", tableLayout: "auto" }}>
|
<Table sx={{ minWidth: "750px", tableLayout: "auto" }}>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
{" "}
|
|
||||||
<TableRow>
|
<TableRow>
|
||||||
{columns.map((column) => (
|
{columns.map((column) => (
|
||||||
<StyledTableCell key={column.id}>
|
<StyledTableCell
|
||||||
|
key={column.id}
|
||||||
|
align={column.align}
|
||||||
|
onClick={
|
||||||
|
column.id !== "action"
|
||||||
|
? () => handleSort(column.id)
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
sx={{
|
||||||
|
cursor:
|
||||||
|
column.id !== "action"
|
||||||
|
? "pointer"
|
||||||
|
: "default",
|
||||||
|
}}
|
||||||
|
className={
|
||||||
|
column.id === "action"
|
||||||
|
? "action-cell"
|
||||||
|
: undefined
|
||||||
|
} // Add action-cell class
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
{column.label}
|
{column.label}
|
||||||
|
{column.id !== "action" &&
|
||||||
|
sortConfig.key === column.id &&
|
||||||
|
sortConfig.direction &&
|
||||||
|
(sortConfig.direction === "asc" ? (
|
||||||
|
<ArrowUpwardIcon
|
||||||
|
sx={{
|
||||||
|
fontSize: "16px",
|
||||||
|
color: "#FFFFFF",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<ArrowDownwardIcon
|
||||||
|
sx={{
|
||||||
|
fontSize: "16px",
|
||||||
|
color: "#FFFFFF",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
</StyledTableCell>
|
</StyledTableCell>
|
||||||
))}
|
))}
|
||||||
</TableRow>
|
</TableRow>
|
||||||
|
@ -458,88 +577,156 @@ const handleToggleStatus = () => {
|
||||||
<StyledTableRow>
|
<StyledTableRow>
|
||||||
<StyledTableCell
|
<StyledTableCell
|
||||||
colSpan={columns.length}
|
colSpan={columns.length}
|
||||||
|
sx={{ textAlign: "center", py: 4 }}
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
sx={{
|
sx={{
|
||||||
textAlign: "center",
|
color: "#6B7280",
|
||||||
padding: "32px 0",
|
fontSize: "16px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{getEmptyMessage(tableType)}
|
{getEmptyMessage(tableType)}
|
||||||
|
</Typography>
|
||||||
</StyledTableCell>
|
</StyledTableCell>
|
||||||
</StyledTableRow>
|
</StyledTableRow>
|
||||||
) : (
|
) : (
|
||||||
currentRows.map((row, rowIndex) => (
|
currentRows.map((row, rowIndex) => (
|
||||||
<StyledTableRow key={rowIndex}>
|
<StyledTableRow key={rowIndex}>
|
||||||
{columns.map((column) => (
|
{columns.map((column) => (
|
||||||
// In CustomTable.tsx, update the status column rendering logic inside the TableBody
|
|
||||||
<StyledTableCell
|
<StyledTableCell
|
||||||
key={column.id}
|
key={column.id}
|
||||||
sx={{
|
align={column.align}
|
||||||
color: "#000000",
|
className={
|
||||||
backgroundColor: "#D0E1E9",
|
column.id === "action"
|
||||||
...(column.id === "action" && {
|
? "action-cell"
|
||||||
position: "sticky",
|
: undefined
|
||||||
right: 0,
|
} // Add action-cell class
|
||||||
zIndex: 2,
|
|
||||||
boxShadow:
|
|
||||||
"-5px 0 5px -2px rgba(0,0,0,0.15)",
|
|
||||||
}),
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{column.id === "action" ? (
|
{column.id === "action" ? (
|
||||||
<>
|
<Box>
|
||||||
<CustomIconButton
|
<CustomIconButton
|
||||||
onClick={() => {
|
onClick={(e) =>
|
||||||
setSelectedRow(row);
|
handleMenuOpen(
|
||||||
setViewModal(true);
|
e,
|
||||||
|
row
|
||||||
|
)
|
||||||
|
}
|
||||||
|
sx={{
|
||||||
|
color: "#6B7280",
|
||||||
|
"&:hover": {
|
||||||
|
color: "#454545",
|
||||||
|
},
|
||||||
|
transition:
|
||||||
|
"color 0.2s ease",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MoreVertIcon />
|
||||||
|
</CustomIconButton>
|
||||||
|
<Menu
|
||||||
|
anchorEl={anchorEl}
|
||||||
|
open={
|
||||||
|
Boolean(anchorEl) &&
|
||||||
|
menuRow === row
|
||||||
|
}
|
||||||
|
onClose={
|
||||||
|
handleMenuClose
|
||||||
|
}
|
||||||
|
anchorOrigin={{
|
||||||
|
vertical: "top",
|
||||||
|
horizontal: "right",
|
||||||
|
}}
|
||||||
|
transformOrigin={{
|
||||||
|
vertical: "top",
|
||||||
|
horizontal: "right",
|
||||||
|
}}
|
||||||
|
PaperProps={{
|
||||||
|
sx: {
|
||||||
|
borderRadius:
|
||||||
|
"8px",
|
||||||
|
boxShadow:
|
||||||
|
"0 2px 8px rgba(0, 0, 0, 0.15)",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MenuItem
|
||||||
|
onClick={() =>
|
||||||
|
handleMenuAction(
|
||||||
|
"view"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
sx={{
|
||||||
|
color: "#000000",
|
||||||
|
fontSize:
|
||||||
|
"16px",
|
||||||
|
display: "flex",
|
||||||
|
alignItems:
|
||||||
|
"center",
|
||||||
|
gap: 1,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<VisibilityIcon
|
<VisibilityIcon
|
||||||
sx={{
|
sx={{
|
||||||
|
fontSize:
|
||||||
|
"18px",
|
||||||
color: "#454545",
|
color: "#454545",
|
||||||
"&:hover": {
|
|
||||||
color: "#6B7280",
|
|
||||||
},
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</CustomIconButton>
|
View
|
||||||
|
</MenuItem>
|
||||||
<CustomIconButton
|
<MenuItem
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
handleEditButton(
|
handleMenuAction(
|
||||||
row
|
"edit"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
sx={{
|
||||||
|
color: "#000000",
|
||||||
|
fontSize:
|
||||||
|
"16px",
|
||||||
|
display: "flex",
|
||||||
|
alignItems:
|
||||||
|
"center",
|
||||||
|
gap: 1,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<EditIcon
|
<EditIcon
|
||||||
sx={{
|
sx={{
|
||||||
|
fontSize:
|
||||||
|
"18px",
|
||||||
color: "#454545",
|
color: "#454545",
|
||||||
"&:hover": {
|
|
||||||
color: "#6B7280",
|
|
||||||
},
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</CustomIconButton>
|
Edit
|
||||||
|
</MenuItem>
|
||||||
<CustomIconButton
|
<MenuItem
|
||||||
onClick={() => {
|
onClick={() =>
|
||||||
setDeleteModal(
|
handleMenuAction(
|
||||||
true
|
"delete"
|
||||||
);
|
)
|
||||||
setSelectedRow(row);
|
}
|
||||||
|
sx={{
|
||||||
|
color: "#000000",
|
||||||
|
fontSize:
|
||||||
|
"14px",
|
||||||
|
display: "flex",
|
||||||
|
alignItems:
|
||||||
|
"center",
|
||||||
|
gap: 1,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DeleteIcon
|
<DeleteIcon
|
||||||
sx={{
|
sx={{
|
||||||
|
fontSize:
|
||||||
|
"18px",
|
||||||
color: "#454545",
|
color: "#454545",
|
||||||
"&:hover": {
|
|
||||||
color: "#6B7280",
|
|
||||||
},
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</CustomIconButton>
|
Delete
|
||||||
</>
|
</MenuItem>
|
||||||
|
</Menu>
|
||||||
|
</Box>
|
||||||
) : row.statusField &&
|
) : row.statusField &&
|
||||||
column.id === row.statusField ? ( // Check if statusField matches the column
|
column.id === row.statusField ? (
|
||||||
<Button
|
<Button
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
|
@ -548,26 +735,25 @@ const handleToggleStatus = () => {
|
||||||
handleStatusToggle?.(
|
handleStatusToggle?.(
|
||||||
row.id,
|
row.id,
|
||||||
!row.statusValue
|
!row.statusValue
|
||||||
); // Toggle the opposite of current statusValue
|
);
|
||||||
}}
|
}}
|
||||||
color="primary"
|
|
||||||
sx={{
|
sx={{
|
||||||
justifyContent:
|
fontSize: "12px",
|
||||||
"flex-start",
|
fontWeight: 600,
|
||||||
py: 0.5,
|
borderRadius: "6px",
|
||||||
px: 1.5,
|
color: row.statusValue
|
||||||
fontSize: "0.75rem",
|
? "#10B981"
|
||||||
fontWeight: "600",
|
: "#EF4444",
|
||||||
borderRadius: "4px",
|
|
||||||
color: "#000000",
|
|
||||||
border: "1px solid #000000",
|
|
||||||
backgroundColor:
|
|
||||||
"transparent",
|
|
||||||
"&:hover": {
|
|
||||||
borderColor:
|
borderColor:
|
||||||
"#000000",
|
row.statusValue
|
||||||
|
? "#10B981"
|
||||||
|
: "#EF4444",
|
||||||
|
padding: "4px 12px",
|
||||||
|
"&:hover": {
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
"transparent",
|
row.statusValue
|
||||||
|
? "rgba(16, 185, 129, 0.1)"
|
||||||
|
: "rgba(239, 68, 68, 0.1)",
|
||||||
},
|
},
|
||||||
"&::before": {
|
"&::before": {
|
||||||
content: '""',
|
content: '""',
|
||||||
|
@ -580,7 +766,7 @@ const handleToggleStatus = () => {
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
row.statusValue
|
row.statusValue
|
||||||
? "#10B981"
|
? "#10B981"
|
||||||
: "#EF4444", // Green for true, red for false
|
: "#EF4444",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -593,8 +779,8 @@ const handleToggleStatus = () => {
|
||||||
src={row[column.id]}
|
src={row[column.id]}
|
||||||
alt="Row"
|
alt="Row"
|
||||||
style={{
|
style={{
|
||||||
width: "50px",
|
width: "40px",
|
||||||
height: "50px",
|
height: "40px",
|
||||||
borderRadius: "50%",
|
borderRadius: "50%",
|
||||||
objectFit: "cover",
|
objectFit: "cover",
|
||||||
}}
|
}}
|
||||||
|
@ -609,7 +795,8 @@ const handleToggleStatus = () => {
|
||||||
)}
|
)}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
</TableContainer>
|
</StyledTableContainer>
|
||||||
|
|
||||||
{/* Pagination */}
|
{/* Pagination */}
|
||||||
<Box sx={{ display: "flex", justifyContent: "flex-end", mt: 3 }}>
|
<Box sx={{ display: "flex", justifyContent: "flex-end", mt: 3 }}>
|
||||||
<Pagination
|
<Pagination
|
||||||
|
@ -618,16 +805,21 @@ const handleToggleStatus = () => {
|
||||||
onChange={handlePageChange}
|
onChange={handlePageChange}
|
||||||
sx={{
|
sx={{
|
||||||
"& .MuiPaginationItem-root": {
|
"& .MuiPaginationItem-root": {
|
||||||
color: "#000000",
|
color: "#1A1A1A",
|
||||||
|
fontSize: "16px",
|
||||||
},
|
},
|
||||||
"& .Mui-selected": {
|
"& .Mui-selected": {
|
||||||
backgroundColor: "#000000",
|
backgroundColor: "#000000",
|
||||||
color: "#FFFFFF",
|
color: "#FFFFFF",
|
||||||
|
"&:hover": {
|
||||||
|
backgroundColor: "#000000",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
{/* Modals */}
|
||||||
{viewModal && tableType === "admin" && (
|
{viewModal && tableType === "admin" && (
|
||||||
<ViewModal
|
<ViewModal
|
||||||
handleView={() => handleViewButton(selectedRow?.id)}
|
handleView={() => handleViewButton(selectedRow?.id)}
|
||||||
|
@ -644,7 +836,6 @@ const handleToggleStatus = () => {
|
||||||
id={selectedRow?.id}
|
id={selectedRow?.id}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{viewModal && tableType === "vehicle" && (
|
{viewModal && tableType === "vehicle" && (
|
||||||
<VehicleViewModal
|
<VehicleViewModal
|
||||||
handleView={() => handleViewButton(selectedRow?.id)}
|
handleView={() => handleViewButton(selectedRow?.id)}
|
||||||
|
@ -669,26 +860,6 @@ const handleToggleStatus = () => {
|
||||||
id={selectedRow?.id}
|
id={selectedRow?.id}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{tableType === "role" && (
|
|
||||||
<Button
|
|
||||||
variant="text"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
handleToggleStatus();
|
|
||||||
}}
|
|
||||||
color="secondary"
|
|
||||||
sx={{
|
|
||||||
justifyContent: "flex-start",
|
|
||||||
py: 0,
|
|
||||||
fontWeight: "bold",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{selectedRow?.statusValue === 1 ? "Deactivate" : "Activate"}
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Modals */}
|
|
||||||
{deleteModal && (
|
{deleteModal && (
|
||||||
<DeleteModal
|
<DeleteModal
|
||||||
handleDelete={() => handleDeleteButton(selectedRow?.id)}
|
handleDelete={() => handleDeleteButton(selectedRow?.id)}
|
||||||
|
|
|
@ -114,7 +114,7 @@ const EditManagerModal: React.FC<EditManagerModalProps> = ({
|
||||||
left: "50%",
|
left: "50%",
|
||||||
transform: "translate(-50%, -50%)",
|
transform: "translate(-50%, -50%)",
|
||||||
width: 400,
|
width: 400,
|
||||||
bgcolor: "background.paper",
|
bgcolor: "#000000",
|
||||||
boxShadow: 24,
|
boxShadow: 24,
|
||||||
p: 3,
|
p: 3,
|
||||||
borderRadius: 2,
|
borderRadius: 2,
|
||||||
|
@ -128,7 +128,7 @@ const EditManagerModal: React.FC<EditManagerModalProps> = ({
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="h6" fontWeight={600}>
|
<Typography variant="h6" fontWeight={600} color="#D0E1E9">
|
||||||
Edit Manager
|
Edit Manager
|
||||||
</Typography>
|
</Typography>
|
||||||
<CustomIconButton onClick={handleClose}>
|
<CustomIconButton onClick={handleClose}>
|
||||||
|
@ -143,7 +143,12 @@ const EditManagerModal: React.FC<EditManagerModalProps> = ({
|
||||||
<Box sx={{ display: "flex", flexWrap: "wrap", gap: 2 }}>
|
<Box sx={{ display: "flex", flexWrap: "wrap", gap: 2 }}>
|
||||||
{/* Manager Name */}
|
{/* Manager Name */}
|
||||||
<Box sx={{ flex: "1 1 48%" }}>
|
<Box sx={{ flex: "1 1 48%" }}>
|
||||||
<Typography variant="body2" fontWeight={500} mb={0.5}>
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
fontWeight={500}
|
||||||
|
mb={0.5}
|
||||||
|
color="#D0E1E9"
|
||||||
|
>
|
||||||
Manager Name
|
Manager Name
|
||||||
</Typography>
|
</Typography>
|
||||||
<Controller
|
<Controller
|
||||||
|
@ -172,7 +177,6 @@ const EditManagerModal: React.FC<EditManagerModalProps> = ({
|
||||||
placeholder="Enter Manager Name"
|
placeholder="Enter Manager Name"
|
||||||
size="small"
|
size="small"
|
||||||
sx={{ marginTop: 1 }}
|
sx={{ marginTop: 1 }}
|
||||||
|
|
||||||
error={!!errors.name}
|
error={!!errors.name}
|
||||||
helperText={errors.name?.message}
|
helperText={errors.name?.message}
|
||||||
/>
|
/>
|
||||||
|
@ -182,13 +186,25 @@ const EditManagerModal: React.FC<EditManagerModalProps> = ({
|
||||||
|
|
||||||
{/* Email */}
|
{/* Email */}
|
||||||
<Box sx={{ flex: "1 1 48%" }}>
|
<Box sx={{ flex: "1 1 48%" }}>
|
||||||
<Typography variant="body2" fontWeight={500} mb={0.5}>
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
fontWeight={500}
|
||||||
|
mb={0.5}
|
||||||
|
color="#D0E1E9"
|
||||||
|
>
|
||||||
Email
|
Email
|
||||||
</Typography>
|
</Typography>
|
||||||
<Controller
|
<Controller
|
||||||
name="email"
|
name="email"
|
||||||
control={control}
|
control={control}
|
||||||
rules={{ required: "Email is required" }}
|
rules={{
|
||||||
|
required: "Email is required",
|
||||||
|
pattern: {
|
||||||
|
value: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
|
||||||
|
message:
|
||||||
|
"Please enter a valid email address (e.g., example@domain.com).",
|
||||||
|
},
|
||||||
|
}}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<CustomTextField
|
<CustomTextField
|
||||||
{...field}
|
{...field}
|
||||||
|
@ -196,7 +212,6 @@ const EditManagerModal: React.FC<EditManagerModalProps> = ({
|
||||||
placeholder="Enter Email"
|
placeholder="Enter Email"
|
||||||
size="small"
|
size="small"
|
||||||
sx={{ marginTop: 1 }}
|
sx={{ marginTop: 1 }}
|
||||||
|
|
||||||
error={!!errors.email}
|
error={!!errors.email}
|
||||||
helperText={errors.email?.message}
|
helperText={errors.email?.message}
|
||||||
/>
|
/>
|
||||||
|
@ -206,7 +221,12 @@ const EditManagerModal: React.FC<EditManagerModalProps> = ({
|
||||||
|
|
||||||
{/* Phone Number */}
|
{/* Phone Number */}
|
||||||
<Box sx={{ flex: "1 1 48%" }}>
|
<Box sx={{ flex: "1 1 48%" }}>
|
||||||
<Typography variant="body2" fontWeight={500} mb={0.5}>
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
fontWeight={500}
|
||||||
|
mb={0.5}
|
||||||
|
color="#D0E1E9"
|
||||||
|
>
|
||||||
Phone Number
|
Phone Number
|
||||||
</Typography>
|
</Typography>
|
||||||
<Controller
|
<Controller
|
||||||
|
@ -234,7 +254,6 @@ const EditManagerModal: React.FC<EditManagerModalProps> = ({
|
||||||
placeholder="Enter Phone Number"
|
placeholder="Enter Phone Number"
|
||||||
size="small"
|
size="small"
|
||||||
sx={{ marginTop: 1 }}
|
sx={{ marginTop: 1 }}
|
||||||
|
|
||||||
error={!!errors.phone}
|
error={!!errors.phone}
|
||||||
helperText={errors.phone?.message}
|
helperText={errors.phone?.message}
|
||||||
/>
|
/>
|
||||||
|
@ -250,11 +269,11 @@ const EditManagerModal: React.FC<EditManagerModalProps> = ({
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
sx={{
|
sx={{
|
||||||
backgroundColor: "#52ACDF",
|
backgroundColor: "#D0E1E9",
|
||||||
color: "white",
|
color: "#000000",
|
||||||
borderRadius: "8px",
|
borderRadius: "8px",
|
||||||
width: "117px",
|
width: "125px",
|
||||||
"&:hover": { backgroundColor: "#439BC1" },
|
"&:hover": { backgroundColor: "#DFECF1" },
|
||||||
whiteSpace: "pre",
|
whiteSpace: "pre",
|
||||||
}}
|
}}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
|
|
|
@ -55,6 +55,7 @@ const EditStationModal: React.FC<EditStationModalProps> = ({
|
||||||
setValue,
|
setValue,
|
||||||
reset,
|
reset,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
|
register,
|
||||||
} = useForm<FormData>({
|
} = useForm<FormData>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
name: "",
|
name: "",
|
||||||
|
@ -197,7 +198,7 @@ const EditStationModal: React.FC<EditStationModalProps> = ({
|
||||||
left: "50%",
|
left: "50%",
|
||||||
transform: "translate(-50%, -50%)",
|
transform: "translate(-50%, -50%)",
|
||||||
width: 400,
|
width: 400,
|
||||||
bgcolor: "background.paper",
|
bgcolor: "#000000",
|
||||||
boxShadow: 24,
|
boxShadow: 24,
|
||||||
p: 3,
|
p: 3,
|
||||||
borderRadius: 2,
|
borderRadius: 2,
|
||||||
|
@ -211,7 +212,12 @@ const EditStationModal: React.FC<EditStationModalProps> = ({
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="h6" fontWeight={600} fontSize={"16px"}>
|
<Typography
|
||||||
|
variant="h6"
|
||||||
|
fontWeight={600}
|
||||||
|
fontSize={"16px"}
|
||||||
|
color="#D0E1E9"
|
||||||
|
>
|
||||||
Edit Charging Station
|
Edit Charging Station
|
||||||
</Typography>
|
</Typography>
|
||||||
<CustomIconButton onClick={handleClose}>
|
<CustomIconButton onClick={handleClose}>
|
||||||
|
@ -237,6 +243,7 @@ const EditStationModal: React.FC<EditStationModalProps> = ({
|
||||||
variant="body2"
|
variant="body2"
|
||||||
fontWeight={500}
|
fontWeight={500}
|
||||||
mb={0.5}
|
mb={0.5}
|
||||||
|
color="#D0E1E9"
|
||||||
>
|
>
|
||||||
Station Name
|
Station Name
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -256,6 +263,20 @@ const EditStationModal: React.FC<EditStationModalProps> = ({
|
||||||
? errors.name.message
|
? errors.name.message
|
||||||
: ""
|
: ""
|
||||||
}
|
}
|
||||||
|
{...register("name", {
|
||||||
|
required:
|
||||||
|
"Station Name is required",
|
||||||
|
minLength: {
|
||||||
|
value: 3,
|
||||||
|
message:
|
||||||
|
"Minimum 3 characters required",
|
||||||
|
},
|
||||||
|
maxLength: {
|
||||||
|
value: 30,
|
||||||
|
message:
|
||||||
|
"Maximum 30 characters allowed",
|
||||||
|
},
|
||||||
|
})}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -271,6 +292,7 @@ const EditStationModal: React.FC<EditStationModalProps> = ({
|
||||||
variant="body2"
|
variant="body2"
|
||||||
fontWeight={500}
|
fontWeight={500}
|
||||||
mb={0.5}
|
mb={0.5}
|
||||||
|
color="#D0E1E9"
|
||||||
>
|
>
|
||||||
Station Location
|
Station Location
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -291,6 +313,10 @@ const EditStationModal: React.FC<EditStationModalProps> = ({
|
||||||
.message
|
.message
|
||||||
: ""
|
: ""
|
||||||
}
|
}
|
||||||
|
{...register("registeredAddress", {
|
||||||
|
required:
|
||||||
|
"Station Location is required",
|
||||||
|
})}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -310,6 +336,7 @@ const EditStationModal: React.FC<EditStationModalProps> = ({
|
||||||
variant="body2"
|
variant="body2"
|
||||||
fontWeight={500}
|
fontWeight={500}
|
||||||
mb={0.5}
|
mb={0.5}
|
||||||
|
color="#D0E1E9"
|
||||||
>
|
>
|
||||||
Total Slots
|
Total Slots
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -330,6 +357,15 @@ const EditStationModal: React.FC<EditStationModalProps> = ({
|
||||||
? errors.totalSlots.message
|
? errors.totalSlots.message
|
||||||
: ""
|
: ""
|
||||||
}
|
}
|
||||||
|
{...register("totalSlots", {
|
||||||
|
required:
|
||||||
|
"Total Slots are required",
|
||||||
|
min: {
|
||||||
|
value: 1,
|
||||||
|
message:
|
||||||
|
"At least 1 slot is required",
|
||||||
|
},
|
||||||
|
})}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -345,7 +381,11 @@ const EditStationModal: React.FC<EditStationModalProps> = ({
|
||||||
width: "100%",
|
width: "100%",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
fontWeight={500}
|
||||||
|
color="#D0E1E9"
|
||||||
|
>
|
||||||
Select Vehicle Brands
|
Select Vehicle Brands
|
||||||
</Typography>
|
</Typography>
|
||||||
<FormControl fullWidth>
|
<FormControl fullWidth>
|
||||||
|
@ -385,6 +425,7 @@ const EditStationModal: React.FC<EditStationModalProps> = ({
|
||||||
<Typography
|
<Typography
|
||||||
key={index}
|
key={index}
|
||||||
variant="body2"
|
variant="body2"
|
||||||
|
color="#454545"
|
||||||
>
|
>
|
||||||
{brand
|
{brand
|
||||||
? brand.name
|
? brand.name
|
||||||
|
@ -396,7 +437,7 @@ const EditStationModal: React.FC<EditStationModalProps> = ({
|
||||||
{moreCount > 0 && (
|
{moreCount > 0 && (
|
||||||
<Typography
|
<Typography
|
||||||
variant="body2"
|
variant="body2"
|
||||||
color="textSecondary"
|
color="#454545"
|
||||||
>
|
>
|
||||||
+{moreCount} more
|
+{moreCount} more
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -438,7 +479,11 @@ const EditStationModal: React.FC<EditStationModalProps> = ({
|
||||||
width: "100%",
|
width: "100%",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
fontWeight={500}
|
||||||
|
color="#D0E1E9"
|
||||||
|
>
|
||||||
Vehicle Name
|
Vehicle Name
|
||||||
</Typography>
|
</Typography>
|
||||||
<FormControl fullWidth>
|
<FormControl fullWidth>
|
||||||
|
@ -471,6 +516,7 @@ const EditStationModal: React.FC<EditStationModalProps> = ({
|
||||||
<Typography
|
<Typography
|
||||||
key={index}
|
key={index}
|
||||||
variant="body2"
|
variant="body2"
|
||||||
|
color="#454545"
|
||||||
>
|
>
|
||||||
{name}
|
{name}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -479,7 +525,7 @@ const EditStationModal: React.FC<EditStationModalProps> = ({
|
||||||
{moreCount > 0 && (
|
{moreCount > 0 && (
|
||||||
<Typography
|
<Typography
|
||||||
variant="body2"
|
variant="body2"
|
||||||
color="textSecondary"
|
color="#454545"
|
||||||
>
|
>
|
||||||
+{moreCount} more
|
+{moreCount} more
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -528,12 +574,12 @@ const EditStationModal: React.FC<EditStationModalProps> = ({
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
sx={{
|
sx={{
|
||||||
backgroundColor: "#52ACDF",
|
backgroundColor: "#D0E1E9",
|
||||||
color: "white",
|
color: "#000000",
|
||||||
borderRadius: "8px",
|
borderRadius: "8px",
|
||||||
fontSize: "16px",
|
fontSize: "16px",
|
||||||
width: "117px",
|
width: "150px",
|
||||||
"&:hover": { backgroundColor: "#439BC1" },
|
"&:hover": { backgroundColor: "#DFECF1" },
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Update Station
|
Update Station
|
||||||
|
|
|
@ -15,14 +15,27 @@ const style = {
|
||||||
left: "50%",
|
left: "50%",
|
||||||
transform: "translate(-50%, -50%)",
|
transform: "translate(-50%, -50%)",
|
||||||
width: 330,
|
width: 330,
|
||||||
bgcolor: "#272727",
|
bgcolor: "#000000",
|
||||||
|
color: "#D0E1E9",
|
||||||
borderRadius: 1.5,
|
borderRadius: 1.5,
|
||||||
boxShadow: 24,
|
boxShadow: 24,
|
||||||
p: 3,
|
p: 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
const btnStyle = { py: 1, px: 5, width: "50%", textTransform: "capitalize" };
|
const btnStyle = {
|
||||||
|
py: 1,
|
||||||
|
px: 5,
|
||||||
|
width: "50%",
|
||||||
|
textTransform: "capitalize",
|
||||||
|
backgroundColor: "#D0E1E9",
|
||||||
|
color: "#000000",
|
||||||
|
};
|
||||||
|
const btnStyleCancel = {
|
||||||
|
py: 1,
|
||||||
|
px: 5,
|
||||||
|
width: "50%",
|
||||||
|
textTransform: "capitalize",
|
||||||
|
};
|
||||||
export default function DeleteModal({
|
export default function DeleteModal({
|
||||||
open,
|
open,
|
||||||
setDeleteModal,
|
setDeleteModal,
|
||||||
|
@ -54,6 +67,7 @@ export default function DeleteModal({
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "flex-end",
|
justifyContent: "flex-end",
|
||||||
marginTop: -3.5,
|
marginTop: -3.5,
|
||||||
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CustomIconButton
|
<CustomIconButton
|
||||||
|
@ -89,10 +103,10 @@ export default function DeleteModal({
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
|
||||||
type="button"
|
type="button"
|
||||||
color="primary"
|
variant="contained"
|
||||||
sx={btnStyle}
|
color="error"
|
||||||
|
sx={btnStyleCancel}
|
||||||
onClick={() => handleDelete(id || "")}
|
onClick={() => handleDelete(id || "")}
|
||||||
>
|
>
|
||||||
Delete
|
Delete
|
||||||
|
|
|
@ -18,7 +18,7 @@ const style = {
|
||||||
left: "50%",
|
left: "50%",
|
||||||
transform: "translate(-50%, -50%)",
|
transform: "translate(-50%, -50%)",
|
||||||
width: 400,
|
width: 400,
|
||||||
bgcolor: "background.paper",
|
bgcolor: "#000000",
|
||||||
borderRadius: 2,
|
borderRadius: 2,
|
||||||
boxShadow: "0px 4px 20px rgba(0, 0, 0, 0.15)",
|
boxShadow: "0px 4px 20px rgba(0, 0, 0, 0.15)",
|
||||||
p: 4,
|
p: 4,
|
||||||
|
@ -62,7 +62,10 @@ export default function StationViewModal({ open, setViewModal, id }: Props) {
|
||||||
width: "100%",
|
width: "100%",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box sx={{ flex: 1, textAlign: "center" }}>
|
<Box
|
||||||
|
sx={{ flex: 1, textAlign: "center" }}
|
||||||
|
color="#D0E1E9"
|
||||||
|
>
|
||||||
{selectedStation?.name || "Station"}'s Details
|
{selectedStation?.name || "Station"}'s Details
|
||||||
</Box>
|
</Box>
|
||||||
<CustomIconButton
|
<CustomIconButton
|
||||||
|
@ -79,33 +82,33 @@ export default function StationViewModal({ open, setViewModal, id }: Props) {
|
||||||
{selectedStation ? (
|
{selectedStation ? (
|
||||||
<Grid container spacing={2} sx={{ width: "80%" }}>
|
<Grid container spacing={2} sx={{ width: "80%" }}>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Typography variant="body1">
|
<Typography variant="body1" color="#D0E1E9">
|
||||||
<strong>Station Name:</strong>{" "}
|
<strong>Station Name:</strong>{" "}
|
||||||
<Typography variant="body2">
|
<Typography variant="body2" color="#D0E1E9">
|
||||||
{selectedStation.name}
|
{selectedStation.name}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Typography variant="body1">
|
<Typography variant="body1" color="#D0E1E9">
|
||||||
<strong>Station Location:</strong>{" "}
|
<strong>Station Location:</strong>{" "}
|
||||||
<Typography variant="body2">
|
<Typography variant="body2" color="#D0E1E9">
|
||||||
{selectedStation.registeredAddress}
|
{selectedStation.registeredAddress}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Typography variant="body1">
|
<Typography variant="body1" color="#D0E1E9">
|
||||||
<strong>Total Slots:</strong>
|
<strong>Total Slots:</strong>
|
||||||
<Typography variant="body2">
|
<Typography variant="body2" color="#D0E1E9">
|
||||||
{selectedStation.totalSlots}
|
{selectedStation.totalSlots}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Typography variant="body1">
|
<Typography variant="body1" color="#D0E1E9">
|
||||||
<strong>Status:</strong>
|
<strong>Status:</strong>
|
||||||
<Typography variant="body2">
|
<Typography variant="body2" color="#D0E1E9">
|
||||||
{selectedStation.status === 1
|
{selectedStation.status === 1
|
||||||
? "Available"
|
? "Available"
|
||||||
: "Not Available"}
|
: "Not Available"}
|
||||||
|
@ -115,7 +118,7 @@ export default function StationViewModal({ open, setViewModal, id }: Props) {
|
||||||
|
|
||||||
{/* Display Vehicles */}
|
{/* Display Vehicles */}
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="body1">
|
<Typography variant="body1" color="#D0E1E9">
|
||||||
<strong>Vehicles:</strong>
|
<strong>Vehicles:</strong>
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box
|
<Box
|
||||||
|
@ -125,6 +128,7 @@ export default function StationViewModal({ open, setViewModal, id }: Props) {
|
||||||
gap: 1,
|
gap: 1,
|
||||||
marginTop: 1,
|
marginTop: 1,
|
||||||
}}
|
}}
|
||||||
|
color="#D0E1E9"
|
||||||
>
|
>
|
||||||
{selectedStation.allowedCars &&
|
{selectedStation.allowedCars &&
|
||||||
selectedStation.allowedCars.length > 0 ? (
|
selectedStation.allowedCars.length > 0 ? (
|
||||||
|
@ -138,15 +142,13 @@ export default function StationViewModal({ open, setViewModal, id }: Props) {
|
||||||
fontWeight: 500,
|
fontWeight: 500,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{car.name}{","}
|
{car.name}
|
||||||
|
{","}
|
||||||
</Typography>
|
</Typography>
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
) : (
|
) : (
|
||||||
<Typography
|
<Typography variant="body2" color="#D0E1E9">
|
||||||
variant="body2"
|
|
||||||
color="text.secondary"
|
|
||||||
>
|
|
||||||
No vehicles available
|
No vehicles available
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -17,7 +17,7 @@ const style = {
|
||||||
left: "50%",
|
left: "50%",
|
||||||
transform: "translate(-50%, -50%)",
|
transform: "translate(-50%, -50%)",
|
||||||
width: 400,
|
width: 400,
|
||||||
bgcolor: "background.paper",
|
bgcolor: "#000000",
|
||||||
borderRadius: 2,
|
borderRadius: 2,
|
||||||
boxShadow: "0px 4px 20px rgba(0, 0, 0, 0.15)",
|
boxShadow: "0px 4px 20px rgba(0, 0, 0, 0.15)",
|
||||||
p: 4,
|
p: 4,
|
||||||
|
@ -61,7 +61,13 @@ export default function VehicleViewModal({ open, setViewModal, id }: Props) {
|
||||||
width: "100%",
|
width: "100%",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box sx={{ flex: 1, textAlign: "center" }}>
|
<Box
|
||||||
|
sx={{
|
||||||
|
flex: 1,
|
||||||
|
textAlign: "center",
|
||||||
|
color: "#D0E1E9",
|
||||||
|
}}
|
||||||
|
>
|
||||||
{selectedVehicle?.name || "Vehicle"}'s Details
|
{selectedVehicle?.name || "Vehicle"}'s Details
|
||||||
</Box>
|
</Box>
|
||||||
<Box
|
<Box
|
||||||
|
@ -82,39 +88,43 @@ export default function VehicleViewModal({ open, setViewModal, id }: Props) {
|
||||||
{selectedVehicle ? (
|
{selectedVehicle ? (
|
||||||
<Grid container spacing={2} sx={{ width: "80%" }}>
|
<Grid container spacing={2} sx={{ width: "80%" }}>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Typography variant="body1">
|
<Typography variant="body1" color="#D0E1E9">
|
||||||
<strong>Name:</strong>{" "}
|
<strong>Name:</strong>{" "}
|
||||||
<Typography variant="body2">
|
<Typography variant="body2" color="#D0E1E9">
|
||||||
{selectedVehicle.name}
|
{selectedVehicle.name}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Typography variant="body1">
|
<Typography variant="body1" color="#D0E1E9">
|
||||||
<strong>Company:</strong>{" "}
|
<strong>Company:</strong>{" "}
|
||||||
<Typography variant="body2">
|
<Typography variant="body2" color="#D0E1E9">
|
||||||
{selectedVehicle.company}
|
{selectedVehicle.company}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Typography variant="body1">
|
<Typography variant="body1" color="#D0E1E9">
|
||||||
<strong>Model Name:</strong>
|
<strong>Model Name:</strong>
|
||||||
<Typography variant="body2">
|
<Typography variant="body2" color="#D0E1E9">
|
||||||
{selectedVehicle.modelName}
|
{selectedVehicle.modelName}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Typography variant="body1">
|
<Typography variant="body1" color="#D0E1E9">
|
||||||
<strong>Charge Type:</strong>
|
<strong>Charge Type:</strong>
|
||||||
<Typography variant="body2">
|
<Typography variant="body2" color="#D0E1E9">
|
||||||
{selectedVehicle.chargeType}
|
{selectedVehicle.chargeType}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="body1" gutterBottom>
|
<Typography
|
||||||
|
variant="body1"
|
||||||
|
gutterBottom
|
||||||
|
color="#D0E1E9"
|
||||||
|
>
|
||||||
<strong>Image:</strong>
|
<strong>Image:</strong>
|
||||||
</Typography>
|
</Typography>
|
||||||
{selectedVehicle.imageUrl ? (
|
{selectedVehicle.imageUrl ? (
|
||||||
|
@ -139,7 +149,7 @@ export default function VehicleViewModal({ open, setViewModal, id }: Props) {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Typography variant="body2">
|
<Typography variant="body2" color="#D0E1E9">
|
||||||
No image available
|
No image available
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -17,7 +17,7 @@ const style = {
|
||||||
left: "50%",
|
left: "50%",
|
||||||
transform: "translate(-50%, -50%)",
|
transform: "translate(-50%, -50%)",
|
||||||
width: 400,
|
width: 400,
|
||||||
bgcolor: "background.paper",
|
bgcolor: "#000000",
|
||||||
borderRadius: 2,
|
borderRadius: 2,
|
||||||
boxShadow: "0px 4px 20px rgba(0, 0, 0, 0.15)",
|
boxShadow: "0px 4px 20px rgba(0, 0, 0, 0.15)",
|
||||||
p: 4,
|
p: 4,
|
||||||
|
@ -35,7 +35,6 @@ export default function ManagerViewModal({ open, setViewModal, id }: Props) {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (id) {
|
if (id) {
|
||||||
|
|
||||||
const manager = managers.find((manager) => manager.id === id);
|
const manager = managers.find((manager) => manager.id === id);
|
||||||
setSelectedManager(manager || null);
|
setSelectedManager(manager || null);
|
||||||
}
|
}
|
||||||
|
@ -62,7 +61,13 @@ export default function ManagerViewModal({ open, setViewModal, id }: Props) {
|
||||||
width: "100%",
|
width: "100%",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box sx={{ flex: 1, textAlign: "center" }}>
|
<Box
|
||||||
|
sx={{
|
||||||
|
flex: 1,
|
||||||
|
textAlign: "center",
|
||||||
|
color: "#D0E1E9",
|
||||||
|
}}
|
||||||
|
>
|
||||||
{selectedManager?.name || "Manager"}'s Details
|
{selectedManager?.name || "Manager"}'s Details
|
||||||
</Box>
|
</Box>
|
||||||
<Box
|
<Box
|
||||||
|
@ -71,6 +76,7 @@ export default function ManagerViewModal({ open, setViewModal, id }: Props) {
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
|
color: "#D0E1E9",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CloseIcon />
|
<CloseIcon />
|
||||||
|
@ -83,42 +89,42 @@ export default function ManagerViewModal({ open, setViewModal, id }: Props) {
|
||||||
{selectedManager ? (
|
{selectedManager ? (
|
||||||
<Grid container spacing={2} sx={{ width: "80%" }}>
|
<Grid container spacing={2} sx={{ width: "80%" }}>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Typography variant="body1">
|
<Typography variant="body1" color="#D0E1E9">
|
||||||
<strong>Name:</strong>
|
<strong>Name:</strong>
|
||||||
<Typography variant="body2">
|
<Typography variant="body2" color="#D0E1E9">
|
||||||
{selectedManager.name}
|
{selectedManager.name}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Typography variant="body1">
|
<Typography variant="body1" color="#D0E1E9">
|
||||||
<strong>Email:</strong>
|
<strong>Email:</strong>
|
||||||
<Typography variant="body2">
|
<Typography variant="body2" color="#D0E1E9">
|
||||||
{selectedManager.email}
|
{selectedManager.email}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Typography variant="body1">
|
<Typography variant="body1" color="#D0E1E9">
|
||||||
<strong>Phone:</strong>
|
<strong>Phone:</strong>
|
||||||
<Typography variant="body2">
|
<Typography variant="body2" color="#D0E1E9">
|
||||||
{selectedManager.phone}
|
{selectedManager.phone}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Typography variant="body1">
|
<Typography variant="body1" color="#D0E1E9">
|
||||||
<strong>Station Location:</strong>
|
<strong>Station Location:</strong>
|
||||||
<Typography variant="body2">
|
<Typography variant="body2" color="#D0E1E9">
|
||||||
{selectedManager.chargingStation
|
{selectedManager.chargingStation
|
||||||
?.registeredAddress || "Not Available"}
|
?.registeredAddress || "Not Available"}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Typography variant="body1">
|
<Typography variant="body1" color="#D0E1E9">
|
||||||
<strong>Station Name:</strong>
|
<strong>Station Name:</strong>
|
||||||
<Typography variant="body2">
|
<Typography variant="body2" color="#D0E1E9">
|
||||||
{selectedManager.chargingStation?.name ||
|
{selectedManager.chargingStation?.name ||
|
||||||
"Not Available"}
|
"Not Available"}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { ThemeProvider, Theme, createTheme } from "@mui/material/styles";
|
import { ThemeProvider, Theme, createTheme } from "@mui/material/styles";
|
||||||
import type { ThemeOptions } from "@mui/material/styles";
|
import type { ThemeOptions } from "@mui/material/styles";
|
||||||
|
@ -28,7 +27,7 @@ export default function AppTheme(props: AppThemeProps) {
|
||||||
paper: "#D0E1E9", // Dark cards
|
paper: "#D0E1E9", // Dark cards
|
||||||
},
|
},
|
||||||
text: {
|
text: {
|
||||||
primary: "#000000", // Already matches the image
|
primary: "#454545", // Already matches the image
|
||||||
secondary: "#272727", // Already matches the image
|
secondary: "#272727", // Already matches the image
|
||||||
},
|
},
|
||||||
success: {
|
success: {
|
||||||
|
@ -55,6 +54,7 @@ export default function AppTheme(props: AppThemeProps) {
|
||||||
body2: {
|
body2: {
|
||||||
fontSize: "0.875rem",
|
fontSize: "0.875rem",
|
||||||
color: "#b0b0b0",
|
color: "#b0b0b0",
|
||||||
|
fontWeight: 300,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
cssVariables: {
|
cssVariables: {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
export const autofillFix = {
|
export const autofillFix = {
|
||||||
"& input:-webkit-autofill": {
|
"& input:-webkit-autofill": {
|
||||||
WebkitBoxShadow: "0 0 0 1000px transparent inset !important",
|
WebkitBoxShadow: "0 0 0 1000px transparent inset !important",
|
||||||
WebkitTextFillColor: "white !important",
|
WebkitTextFillColor: "#454545 !important",
|
||||||
transition: "background-color 5000s ease-in-out 0s",
|
transition: "background-color 5000s ease-in-out 0s",
|
||||||
},
|
},
|
||||||
"& input:-webkit-autofill:hover": {
|
"& input:-webkit-autofill:hover": {
|
||||||
|
@ -15,12 +15,12 @@ export const autofillFix = {
|
||||||
},
|
},
|
||||||
"& input:-moz-autofill": {
|
"& input:-moz-autofill": {
|
||||||
boxShadow: "0 0 0 1000px transparent inset !important",
|
boxShadow: "0 0 0 1000px transparent inset !important",
|
||||||
MozTextFillColor: "white !important",
|
MozTextFillColor: "#454545 !important",
|
||||||
transition: "background-color 5000s ease-in-out 0s",
|
transition: "background-color 5000s ease-in-out 0s",
|
||||||
},
|
},
|
||||||
"& input:autofill": {
|
"& input:autofill": {
|
||||||
boxShadow: "0 0 0 1000px transparent inset !important",
|
boxShadow: "0 0 0 1000px transparent inset !important",
|
||||||
textFillColor: "transparent !important",
|
textFillColor: "#454545 !important",
|
||||||
transition: "background-color 5000s ease-in-out 0s",
|
transition: "background-color 5000s ease-in-out 0s",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -385,7 +385,7 @@ export const inputsCustomizations: Components<Theme> = {
|
||||||
input: {
|
input: {
|
||||||
"&::placeholder": {
|
"&::placeholder": {
|
||||||
opacity: 0.7,
|
opacity: 0.7,
|
||||||
color: gray[500],
|
color: gray[600],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue
Color codes are already defined in the theme; use theme values instead of hardcoded colors.
Theme file path src/shared-theme/AppTheme.tsx