bulk-email/src/components/AddStationModal/addStationModal.tsx
2025-04-01 18:39:17 +05:30

461 lines
11 KiB
TypeScript

import { useForm } from "react-hook-form";
import {
Box,
Button,
Typography,
Modal,
FormControl,
FormHelperText,
Select,
MenuItem,
Checkbox,
ListItemText,
InputLabel,
} from "@mui/material";
import CloseIcon from "@mui/icons-material/Close";
import { useSelector, useDispatch } from "react-redux";
import { useEffect, useState } from "react";
import { RootState } from "../../redux/reducers.ts";
import {
fetchVehicleBrands,
vehicleList,
} from "../../redux/slices/VehicleSlice.ts"; // Adjust this import path accordingly
import { CustomIconButton, CustomTextField } from "../AddUserModal/styled.css";// Assuming custom styled components
export default function AddStationModal({
open,
handleClose,
handleAddStation,
}) {
const {
register,
handleSubmit,
formState: { errors },
reset,
} = useForm();
const dispatch = useDispatch();
// Get vehicle names from the Redux store
const vehicles = useSelector(
(state: RootState) => state.vehicleReducer.vehicles
); // Adjust according to your actual state structure
const vehicleBrands = useSelector(
(state: RootState) => state.vehicleReducer.vehicleBrands
);
// State for selected vehicle brand and vehicles
const [selectedBrands, setSelectedBrands] = useState<string[]>([]);
const [selectedVehicles, setSelectedVehicles] = useState<string[]>([]);
// Fetch vehicle brands and vehicle list when the component mounts
useEffect(() => {
dispatch(fetchVehicleBrands());
dispatch(vehicleList());
}, [dispatch]);
// Filter vehicles based on selected vehicle brands
const filteredVehicles = vehicles.filter((vehicle) =>
selectedBrands.includes(vehicle.company)
);
// Handle changes in selected vehicle brands (checkboxes)
const handleBrandChange = (
event: React.ChangeEvent<{ value: unknown }>
) => {
const value = event.target.value as string[];
setSelectedBrands(value); // Update the selected vehicle brands
};
// Handle changes in selected vehicles (checkboxes)
const handleVehicleChange = (
event: React.ChangeEvent<{ value: unknown }>
) => {
setSelectedVehicles(event.target.value as string[]);
};
// Function to map selected vehicle names to corresponding vehicle ids
const getVehicleIds = () => {
return vehicles
.filter((vehicle) => selectedVehicles.includes(vehicle.name))
.map((vehicle) => vehicle.id);
};
const onSubmit = (data: any) => {
const vehicleIds = getVehicleIds(); // Get the ids of the selected vehicles
const payload = {
...data,
status: 1, // Default status
allowedCarIds: vehicleIds, // Pass the vehicle ids to the backend
totalSlots: Number(data.totalSlots), // Ensure this is a number
};
handleAddStation(payload);
handleClose(); // Close modal after adding
reset();
setSelectedVehicles([]);
setSelectedBrands([]); // Reset selected brands after submission
};
return (
<Modal
open={open}
onClose={(e, reason) => {
if (reason === "backdropClick") {
return;
}
handleClose(); // Close modal when clicking cross or cancel
}}
aria-labelledby="add-station-modal"
>
<Box
sx={{
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: 400,
bgcolor: "background.paper",
boxShadow: 24,
p: 3,
borderRadius: 2,
}}
>
{/* Header */}
<Box
sx={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
}}
>
<Typography variant="h6" fontWeight={600}>
Add Charging Station
</Typography>
<CustomIconButton onClick={handleClose}>
<CloseIcon />
</CustomIconButton>
</Box>
{/* Horizontal Line */}
<Box sx={{ borderBottom: "1px solid #ddd", my: 2 }} />
{/* Form */}
<form onSubmit={handleSubmit(onSubmit)}>
{/* Input Fields */}
<Box
sx={{
display: "flex",
flexDirection: "column",
gap: 2,
}}
>
<Box sx={{ display: "flex", gap: 2 }}>
<Box
sx={{
display: "flex",
flexDirection: "column",
width: "100%",
}}
>
<Typography variant="body2" fontWeight={500}>
Station Name
</Typography>
<CustomTextField
fullWidth
placeholder="Enter Station Name"
size="small"
error={!!errors.name}
helperText={
errors.name ? 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",
},
})}
/>
</Box>
<Box
sx={{
display: "flex",
flexDirection: "column",
width: "100%",
}}
>
<Typography variant="body2" fontWeight={500}>
Station Location
</Typography>
<CustomTextField
fullWidth
placeholder="Enter Charging Station Address"
size="small"
error={!!errors.registeredAddress}
helperText={
errors.registeredAddress
? errors.registeredAddress.message
: ""
}
{...register("registeredAddress", {
required:
"Registered Address is required",
})}
/>
</Box>
</Box>
{/* Second Row - Total Slots */}
<Box sx={{ display: "flex", gap: 2 }}>
<Box
sx={{
display: "flex",
flexDirection: "column",
width: "100%",
}}
>
<Typography variant="body2" fontWeight={500}>
Total Slots
</Typography>
<CustomTextField
fullWidth
placeholder="Enter Total Slots"
size="small"
type="number"
error={!!errors.totalSlots}
helperText={
errors.totalSlots
? errors.totalSlots.message
: ""
}
{...register("totalSlots", {
required: "Total Slots are required",
min: {
value: 1,
message:
"At least 1 slot is required",
},
})}
/>
</Box>
</Box>
{/* Vehicle Brand Dropdown with Checkboxes */}
<Box sx={{ display: "flex", gap: 2 }}>
<Box
sx={{
display: "flex",
flexDirection: "column",
width: "100%",
}}
>
<Typography variant="body2" fontWeight={500}>
Vehicle Brand
</Typography>
<FormControl fullWidth>
<InputLabel>Choose Brands</InputLabel>
<Select
multiple
value={selectedBrands}
onChange={handleBrandChange}
renderValue={(selected) => {
const selectedArray =
selected as string[];
const displayNames =
selectedArray.slice(0, 1); // First 2 brands
const moreCount =
selectedArray.length - 1;
return (
<Box
sx={{
display: "flex",
alignItems: "center",
gap: 1,
}}
>
{displayNames.map(
(id, index) => {
const brand =
vehicleBrands.find(
(b) =>
b.id ===
id
);
return (
<Typography
key={index}
variant="body2"
>
{brand
? brand.name
: ""}
</Typography>
);
}
)}
{moreCount > 0 && (
<Typography
variant="body2"
color="textSecondary"
>
+{moreCount} more
</Typography>
)}
</Box>
);
}}
>
{vehicleBrands.length > 0 ? (
vehicleBrands.map((brand) => (
<MenuItem
key={brand.id}
value={brand.id}
>
<Checkbox
checked={selectedBrands.includes(
brand.id
)}
/>
<ListItemText
primary={brand.name}
/>
</MenuItem>
))
) : (
<MenuItem disabled>
No vehicle brands available
</MenuItem>
)}
</Select>
<FormHelperText>
{errors.vehicleBrand
? errors.vehicleBrand.message
: ""}
</FormHelperText>
</FormControl>
</Box>
<Box
sx={{
display: "flex",
flexDirection: "column",
width: "100%",
}}
>
<Typography variant="body2" fontWeight={500}>
Vehicle Name
</Typography>
<FormControl fullWidth>
<InputLabel>Choose Vehicles</InputLabel>
<Select
multiple
value={selectedVehicles}
onChange={handleVehicleChange}
renderValue={(selected) => {
const selectedArray =
selected as string[];
const displayNames =
selectedArray.slice(0, 1); // First 2 vehicles
const moreCount =
selectedArray.length - 1;
return (
<Box
sx={{
display: "flex",
alignItems: "center",
gap: 1,
}}
>
{displayNames.map(
(name, index) => (
<Typography
key={index}
variant="body2"
>
{name}
</Typography>
)
)}
{moreCount > 0 && (
<Typography
variant="body2"
color="textSecondary"
>
+{moreCount} more
</Typography>
)}
</Box>
);
}}
>
{filteredVehicles.length > 0 ? (
filteredVehicles.map((vehicle) => (
<MenuItem
key={vehicle.id}
value={vehicle.name}
>
<Checkbox
checked={selectedVehicles.includes(
vehicle.name
)}
/>
<ListItemText
primary={vehicle.name}
/>
</MenuItem>
))
) : (
<MenuItem disabled>
No vehicles available for the
selected brands
</MenuItem>
)}
</Select>
<FormHelperText>
{errors.vehicleName
? errors.vehicleName.message
: ""}
</FormHelperText>
</FormControl>
</Box>
</Box>
</Box>
{/* Submit Button */}
<Box
sx={{
display: "flex",
justifyContent: "flex-end",
mt: 3,
}}
>
<Button
type="submit"
sx={{
backgroundColor: "#52ACDF",
color: "white",
borderRadius: "8px",
width: "117px",
"&:hover": { backgroundColor: "#439BC1" },
}}
>
Add Station
</Button>
</Box>
</form>
</Box>
</Modal>
);
}