dev-jaanvi #1

Open
jaanvi wants to merge 155 commits from dev-jaanvi into main
7 changed files with 265 additions and 175 deletions
Showing only changes of commit a90c9b643d - Show all commits

View file

@ -23,7 +23,7 @@ import { toast } from "sonner";
import { CustomIconButton, CustomTextField } from "../AddUserModal/styled.css"; import { CustomIconButton, CustomTextField } from "../AddUserModal/styled.css";
import { getAllStations } from "../../redux/slices/stationSlice.ts"; import { getAllStations } from "../../redux/slices/stationSlice.ts";
import { fetchAvailableSlots } from "../../redux/slices/slotSlice.ts"; import { fetchAvailableSlots } from "../../redux/slices/slotSlice.ts";
import { autofillFix } from "../../shared-theme/customizations/autoFill";
export default function AddBookingModal({ export default function AddBookingModal({
open, open,
handleClose, handleClose,
@ -108,11 +108,14 @@ export default function AddBookingModal({
top: "50%", top: "50%",
left: "50%", left: "50%",
transform: "translate(-50%, -50%)", transform: "translate(-50%, -50%)",
width: 400, // width: 400,
bgcolor: "background.paper", bgcolor: "background.paper",
boxShadow: 24, boxShadow: 24,
p: 3, p: 3,
borderRadius: 2, borderRadius: 2,
width: "100%",
maxWidth: 600,
overflow: "auto",
}} }}
> >
<Box <Box
@ -135,19 +138,40 @@ export default function AddBookingModal({
{/* Station ID and Car Name */} {/* Station ID and Car Name */}
<Box sx={{ display: "flex", gap: 2, mb: 2 }}> <Box sx={{ display: "flex", gap: 2, mb: 2 }}>
{/* Station ID */} {/* Station ID */}
<Box sx={{ flex: 1 }}> <Box
<Typography variant="body2" fontWeight={500}> sx={{
display: "flex",
flexDirection: "column",
width: "50%",
...autofillFix,
}}
>
<Typography variant="body2" fontWeight={500} mb={1}>
Select Station Select Station
</Typography> </Typography>
<FormControl fullWidth error={!!errors.stationName}> {/* Station ID Field */}
<InputLabel>Select Station</InputLabel> <FormControl fullWidth error={!!errors.stationId}>
<Select <Select
{...register("stationId", { {...register("stationId", {
required: "Station Name is required", // Change to stationId required: "Station Name is required", // Validation rule
})} })}
defaultValue="" defaultValue=""
size="small" size="small"
displayEmpty
sx={{
textOverflow: "ellipsis", // Truncate long text
whiteSpace: "nowrap",
overflow: "hidden",
}}
> >
{/* Placeholder */}
<MenuItem value="" disabled>
<Typography color="text.secondary">
Choose Station
</Typography>
</MenuItem>
{/* Station Options */}
{stations.map((station) => ( {stations.map((station) => (
<MenuItem <MenuItem
key={station.id} key={station.id}
@ -157,16 +181,24 @@ export default function AddBookingModal({
</MenuItem> </MenuItem>
))} ))}
</Select> </Select>
{/* Safely render the error message */}
{errors.stationId && ( {errors.stationId && (
<Typography color="error" variant="body2"> <Typography color="error" variant="body2">
{errors.stationName.message} {errors.stationId.message}
</Typography> </Typography>
)} )}
</FormControl> </FormControl>
</Box> </Box>
<Box sx={{ flex: 1 }}> <Box
<Typography variant="body2" fontWeight={500}> sx={{
display: "flex",
flexDirection: "column",
width: "50%",
...autofillFix,
}}
>
<Typography variant="body2" fontWeight={500} mb={1}>
Date Date
</Typography> </Typography>
<CustomTextField <CustomTextField
@ -185,10 +217,10 @@ export default function AddBookingModal({
})} })}
slotProps={{ slotProps={{
inputLabel: { inputLabel: {
shrink: true, shrink: true,
}, },
htmlInput: { htmlInput: {
min: today, min: today,
}, },
}} }}
/> />
@ -198,8 +230,15 @@ export default function AddBookingModal({
{/* Car Port and Date */} {/* Car Port and Date */}
<Box sx={{ display: "flex", gap: 2, mb: 2 }}> <Box sx={{ display: "flex", gap: 2, mb: 2 }}>
{/* Car Name */} {/* Car Name */}
<Box sx={{ flex: 1 }}> <Box
<Typography variant="body2" fontWeight={500}> sx={{
display: "flex",
flexDirection: "column",
width: "50%",
...autofillFix,
}}
>
<Typography variant="body2" fontWeight={500} mb={1}>
Car Name Car Name
</Typography> </Typography>
<Controller <Controller
@ -213,10 +252,24 @@ export default function AddBookingModal({
> >
<Select <Select
{...field} {...field}
label="Car Name"
defaultValue="" defaultValue=""
size="small"
displayEmpty
sx={{
textOverflow: "ellipsis",
whiteSpace: "nowrap",
overflow: "hidden",
}}
> >
{carNames.map((car, index) => ( {/* Placeholder item */}
<MenuItem value="" disabled>
<Typography color="text.secondary">
Choose Car Name
</Typography>
</MenuItem>
{/* Car names */}
{carNames.map((car) => (
<MenuItem <MenuItem
key={car.id} key={car.id}
value={car.name} value={car.name}
@ -225,6 +278,7 @@ export default function AddBookingModal({
</MenuItem> </MenuItem>
))} ))}
</Select> </Select>
{errors.carName && ( {errors.carName && (
<Typography <Typography
color="error" color="error"
@ -240,8 +294,15 @@ export default function AddBookingModal({
/> />
</Box> </Box>
{/* Car Port */} {/* Car Port */}
<Box sx={{ flex: 1 }}> <Box
<Typography variant="body2" fontWeight={500}> sx={{
display: "flex",
flexDirection: "column",
width: "50%",
...autofillFix,
}}
>
<Typography variant="body2" fontWeight={500} mb={1}>
Car Port Car Port
</Typography> </Typography>
<Controller <Controller
@ -253,12 +314,20 @@ export default function AddBookingModal({
size="small" size="small"
error={!!errors.carPort} error={!!errors.carPort}
> >
<InputLabel>Car Port</InputLabel>
<Select <Select
{...field} {...field}
label="Car Port" defaultValue="" // Set the default value as empty
defaultValue="" size="small"
displayEmpty // Ensures the placeholder is visible by default
> >
{/* Placeholder MenuItem */}
<MenuItem value="" disabled>
<Typography color="text.secondary">
Choose Car Port
</Typography>
</MenuItem>
{/* Car Ports */}
{carPorts.map((port, index) => ( {carPorts.map((port, index) => (
<MenuItem <MenuItem
key={index} key={index}
@ -268,6 +337,7 @@ export default function AddBookingModal({
</MenuItem> </MenuItem>
))} ))}
</Select> </Select>
{errors.carPort && ( {errors.carPort && (
<Typography <Typography
color="error" color="error"
@ -286,8 +356,15 @@ export default function AddBookingModal({
{/* Start Time and End Time */} {/* Start Time and End Time */}
<Box sx={{ display: "flex", gap: 2, mb: 2 }}> <Box sx={{ display: "flex", gap: 2, mb: 2 }}>
<Box sx={{ flex: 1 }}> <Box
<Typography variant="body2" fontWeight={500}> sx={{
display: "flex",
flexDirection: "column",
width: "50%",
...autofillFix,
}}
>
<Typography variant="body2" fontWeight={500} mb={1}>
Start Time Start Time
</Typography> </Typography>
<CustomTextField <CustomTextField
@ -306,8 +383,15 @@ export default function AddBookingModal({
/> />
</Box> </Box>
<Box sx={{ flex: 1 }}> <Box
<Typography variant="body2" fontWeight={500}> sx={{
display: "flex",
flexDirection: "column",
width: "50%",
...autofillFix,
}}
>
<Typography variant="body2" fontWeight={500} mb={1}>
End Time End Time
</Typography> </Typography>
<CustomTextField <CustomTextField
@ -327,8 +411,15 @@ export default function AddBookingModal({
{/* Car Number */} {/* Car Number */}
<Box sx={{ display: "flex", gap: 2, mb: 2 }}> <Box sx={{ display: "flex", gap: 2, mb: 2 }}>
<Box sx={{ flex: 1 }}> <Box
<Typography variant="body2" fontWeight={500}> sx={{
display: "flex",
flexDirection: "column",
width: "50%",
...autofillFix,
}}
>
<Typography variant="body2" fontWeight={500} mb={1}>
Car Number Car Number
</Typography> </Typography>
<CustomTextField <CustomTextField
@ -373,4 +464,4 @@ export default function AddBookingModal({
</Box> </Box>
</Modal> </Modal>
); );
} }

View file

@ -207,7 +207,6 @@ export default function AddStationModal({
placeholder="Enter Charging Station Address" placeholder="Enter Charging Station Address"
size="small" size="small"
sx={{ marginTop: 1 }} sx={{ marginTop: 1 }}
error={!!errors.registeredAddress} error={!!errors.registeredAddress}
helperText={ helperText={
errors.registeredAddress errors.registeredAddress
@ -239,7 +238,6 @@ export default function AddStationModal({
placeholder="Enter Total Slots" placeholder="Enter Total Slots"
size="small" size="small"
sx={{ marginTop: 1 }} sx={{ marginTop: 1 }}
type="number" type="number"
error={!!errors.totalSlots} error={!!errors.totalSlots}
helperText={ helperText={
@ -261,120 +259,118 @@ export default function AddStationModal({
{/* Vehicle Brand Dropdown with Checkboxes */} {/* Vehicle Brand Dropdown with Checkboxes */}
<Box sx={{ display: "flex", gap: 2 }}> <Box sx={{ display: "flex", gap: 2 }}>
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
width: "100%", width: "100%",
}} }}
>
<Typography
variant="body2"
fontWeight={500}
sx={{ mb: 1 }}
> >
<Typography Vehicle Brand
variant="body2" </Typography>
fontWeight={500} <FormControl fullWidth size="small">
sx={{ mb: 1 }} <Select
> multiple
Vehicle Brand displayEmpty
</Typography> sx={{ marginTop: 1 }}
<FormControl fullWidth size="small"> value={selectedBrands}
<Select onChange={handleBrandChange}
multiple renderValue={(selected) => {
displayEmpty if (selected.length === 0) {
sx={{ marginTop: 1 }}
value={selectedBrands}
onChange={handleBrandChange}
renderValue={(selected) => {
if (selected.length === 0) {
return (
<Typography color="text.secondary">
Choose Brands
</Typography>
);
}
const displayNames = (
selected as string[]
).slice(0, 1);
const moreCount =
(selected as string[]).length -
1;
return ( return (
<Box <Typography color="text.secondary">
sx={{ Choose Brands
display: "flex", </Typography>
flexWrap: "wrap",
gap: 0.5,
}}
>
{displayNames.map((id) => {
const brand =
vehicleBrands.find(
(b) =>
b.id === id
);
return brand ? (
<Chip
key={id}
label={
brand.name
}
size="small"
sx={{
height: 24,
}}
/>
) : null;
})}
{moreCount > 0 && (
<Chip
label={`+${moreCount} more`}
size="small"
sx={{ height: 24 }}
/>
)}
</Box>
); );
}} }
MenuProps={{
PaperProps: { const displayNames = (
style: { selected as string[]
maxHeight: 224, ).slice(0, 1);
}, const moreCount =
}, (selected as string[]).length -
}} 1;
>
{vehicleBrands.length > 0 ? ( return (
vehicleBrands.map((brand) => ( <Box
<MenuItem sx={{
key={brand.id} display: "flex",
value={brand.id} flexWrap: "wrap",
> gap: 0.5,
<Checkbox }}
checked={selectedBrands.includes( >
brand.id {displayNames.map((id,index) => {
)} const brand =
/> vehicleBrands.find(
<ListItemText (b) =>
primary={brand.name} b.id === id
/> );
</MenuItem> return brand ? (
)) <Typography
) : ( key={index}
<MenuItem disabled> variant="body2"
No vehicle brands available >
</MenuItem> {brand
)} ? brand.name
</Select> : ""}
<FormHelperText> </Typography>
{errors.vehicleBrand ) : null;
? errors.vehicleBrand.message })}
: ""}
</FormHelperText> {moreCount > 0 && (
</FormControl> <Typography
</Box> variant="body2"
color="textSecondary"
>
+{moreCount} more
</Typography>
)}
</Box>
);
}}
MenuProps={{
PaperProps: {
style: {
maxHeight: 224,
},
},
}}
>
{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>
{/* Replace the Vehicle Name Dropdown code with this */}
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",
@ -398,7 +394,6 @@ export default function AddStationModal({
multiple multiple
displayEmpty displayEmpty
sx={{ marginTop: 1 }} sx={{ marginTop: 1 }}
value={selectedVehicles} value={selectedVehicles}
onChange={handleVehicleChange} onChange={handleVehicleChange}
renderValue={(selected) => { renderValue={(selected) => {
@ -424,28 +419,29 @@ export default function AddStationModal({
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",
flexWrap: "wrap", alignItems: "center",
gap: 0.5, gap: 0.5,
whiteSpace: "nowrap",
}} }}
> >
{displayNames.map( {displayNames.map(
(name) => ( (name, index) => (
<Chip <Typography
key={name} key={index}
label={name} variant="body2"
size="small" >
sx={{ {name}
height: 24, </Typography>
}}
/>
) )
)} )}
{moreCount > 0 && ( {moreCount > 0 && (
<Chip <Typography
label={`+${moreCount} more`} variant="body2"
size="small" color="textSecondary"
sx={{ height: 24 }} >
/> +{moreCount} more
</Typography>
)} )}
</Box> </Box>
); );

View file

@ -624,6 +624,8 @@ const CustomTable: React.FC<CustomTableProps> = ({
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
setViewModal(true); setViewModal(true);
}} }}
color="primary" color="primary"
sx={{ sx={{
@ -640,6 +642,7 @@ const CustomTable: React.FC<CustomTableProps> = ({
<ViewModal <ViewModal
handleView={() => handleView={() =>
handleViewButton(selectedRow?.id) handleViewButton(selectedRow?.id)
} }
open={viewModal} open={viewModal}
setViewModal={setViewModal} setViewModal={setViewModal}
@ -698,6 +701,7 @@ const CustomTable: React.FC<CustomTableProps> = ({
setModalOpen(true); // Only open if a row is selected setModalOpen(true); // Only open if a row is selected
setRowData(selectedRow); setRowData(selectedRow);
} }
handleClose();
}} }}
color="primary" color="primary"
sx={{ sx={{
@ -755,6 +759,7 @@ const CustomTable: React.FC<CustomTableProps> = ({
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
setDeleteModal(true); setDeleteModal(true);
handleClose();
}} }}
color="error" color="error"
sx={{ sx={{

View file

@ -110,7 +110,7 @@ export default function Header() {
<OptionsMenu /> <OptionsMenu />
</Stack> </Stack>
{showNotifications && ( {/* {showNotifications && (
<Box <Box
sx={{ sx={{
p: 2, p: 2,
@ -125,14 +125,12 @@ export default function Header() {
width: "250px", width: "250px",
}} }}
> >
{/* <Typography variant="h6" color="text.primary">
Notifications
</Typography> */}
<Typography variant="body2" color="text.secondary"> <Typography variant="body2" color="text.secondary">
No notifications yet No notifications yet
</Typography> </Typography>
</Box> </Box>
)} )} */}
</Stack> </Stack>
</Box> </Box>
); );

View file

@ -78,7 +78,7 @@ export default function ViewModal({ open, setViewModal, id }: Props) {
<Divider sx={{ width: "100%" }} /> <Divider sx={{ width: "100%" }} />
{selectedAdmin ? ( {selectedAdmin ? (
<Grid container spacing={2} sx={{ width: "80%" }}> <Grid container spacing={2} sx={{ width: "90%" }}>
<Grid item xs={6}> <Grid item xs={6}>
<Typography variant="body1"> <Typography variant="body1">
<strong>Name:</strong> <strong>Name:</strong>

View file

@ -66,13 +66,13 @@ export default function SideMenuMobile({
Super Admin Super Admin
</Typography> </Typography>
</Stack> </Stack>
<MenuButton showBadge> {/* <MenuButton showBadge>
<NotificationsRoundedIcon /> <NotificationsRoundedIcon />
</MenuButton> </MenuButton> */}
</Stack> </Stack>
<Divider /> <Divider />
<Stack sx={{ flexGrow: 1 }}> <Stack sx={{ flexGrow: 1 }}>
<MenuContent hidden={false} /> <MenuContent hidden={true} />
<Divider /> <Divider />
</Stack> </Stack>
<CardAlert /> <CardAlert />
@ -85,7 +85,7 @@ export default function SideMenuMobile({
e.stopPropagation(); e.stopPropagation();
setLogoutModal(true); setLogoutModal(true);
}} }}
sx={{ color: "red" }}
> >
Logout Logout
</Button> </Button>

View file

@ -288,8 +288,8 @@ const LandingPage = () => {
spacing={2} spacing={2}
textAlign="center" textAlign="center"
sx={{ sx={{
display: { xs: "grid", }, display: { xs: "grid" },
gridTemplateColumns: { gridTemplateColumns: {
xs: "repeat(2, 1fr)", // Two items per row on mobile xs: "repeat(2, 1fr)", // Two items per row on mobile
sm: "repeat(4, 1fr)", sm: "repeat(4, 1fr)",
@ -670,7 +670,7 @@ const LandingPage = () => {
borderRadius: "16px", borderRadius: "16px",
mt: { xs: 6, md: 10 }, mt: { xs: 6, md: 10 },
fontFamily: "Neue Montreal", fontFamily: "Gilory",
}} }}
> >
Key Features Key Features
@ -690,7 +690,7 @@ const LandingPage = () => {
py: { xs: 2, md: 5 }, py: { xs: 2, md: 5 },
px: { xs: 2, md: 3 }, px: { xs: 2, md: 3 },
mt: { xs: 6, md: 5 }, mt: { xs: 6, md: 5 },
fontFamily: "Neue Montreal", fontFamily: "Gilory",
}} }}
> >
<Box <Box
@ -1184,7 +1184,7 @@ const LandingPage = () => {
px: { xs: 2, sm: 3, md: 4 }, px: { xs: 2, sm: 3, md: 4 },
mt: { xs: 6, sm: 8, md: 10 }, mt: { xs: 6, sm: 8, md: 10 },
// height: { xs: "auto", lg: "261px", sm: "208px" }, // height: { xs: "auto", lg: "261px", sm: "208px" },
fontFamily: "Neue Montreal", fontFamily: "Gilory",
borderRadius: "12px", borderRadius: "12px",
}} }}
> >
@ -1271,7 +1271,7 @@ const LandingPage = () => {
lg: "54px", lg: "54px",
md: "44px", md: "44px",
}, },
fontFamily: "Neue Montreal", fontFamily: "Gilory",
textTransform: "none", textTransform: "none",
fontWeight: 500, fontWeight: 500,
fontSize: { fontSize: {
@ -1306,7 +1306,7 @@ const LandingPage = () => {
px: { xs: 2, sm: 3, md: 4 }, px: { xs: 2, sm: 3, md: 4 },
mt: { xs: 6, sm: 8, md: 10 }, mt: { xs: 6, sm: 8, md: 10 },
mb: { xs: 6, sm: 8, md: 10 }, mb: { xs: 6, sm: 8, md: 10 },
fontFamily: "Neue Montreal", fontFamily: "Gilory",
height: "auto", height: "auto",
borderRadius: { xs: "8px", lg: "12px" }, borderRadius: { xs: "8px", lg: "12px" },
}} }}
@ -1317,7 +1317,7 @@ const LandingPage = () => {
py: 4, py: 4,
px: 3, px: 3,
mt: 2, mt: 2,
fontFamily: "Neue Montreal", fontFamily: "Gilory",
}} }}
> >
<Typography <Typography
@ -1338,7 +1338,7 @@ const LandingPage = () => {
variant="body2" variant="body2"
sx={{ sx={{
my: { xs: 2, sm: 3 }, my: { xs: 2, sm: 3 },
fontFamily: "Inter", fontFamily: "Gilory",
fontWeight: 400, fontWeight: 400,
fontSize: { xs: "14px", sm: "18px", md: "20px" }, fontSize: { xs: "14px", sm: "18px", md: "20px" },
color: "#FFFFFF", color: "#FFFFFF",