dev-jaanvi #1
9509
pnpm-lock.yaml
9509
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
BIN
public/logo.png
Normal file
BIN
public/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.3 KiB |
0
public/mobileLogo.png
Normal file
0
public/mobileLogo.png
Normal file
|
@ -373,4 +373,4 @@ export default function AddBookingModal({
|
||||||
</Box>
|
</Box>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
|
@ -5,6 +5,7 @@ import Visibility from "@mui/icons-material/Visibility";
|
||||||
import VisibilityOff from "@mui/icons-material/VisibilityOff";
|
import VisibilityOff from "@mui/icons-material/VisibilityOff";
|
||||||
import { useForm, Controller } from "react-hook-form";
|
import { useForm, Controller } from "react-hook-form";
|
||||||
import { CustomIconButton, CustomTextField } from "../AddUserModal/styled.css";
|
import { CustomIconButton, CustomTextField } from "../AddUserModal/styled.css";
|
||||||
|
import { autofillFix } from "../../shared-theme/customizations/autoFill";
|
||||||
|
|
||||||
//By Jaanvi : Edit Model :: 11-feb-25
|
//By Jaanvi : Edit Model :: 11-feb-25
|
||||||
interface AddEditCategoryModalProps {
|
interface AddEditCategoryModalProps {
|
||||||
|
@ -157,6 +158,7 @@ const AddEditCategoryModal: React.FC<AddEditCategoryModalProps> = ({
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
width: "50%",
|
width: "50%",
|
||||||
|
...autofillFix,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography variant="body2" fontWeight={500}>
|
||||||
|
@ -188,8 +190,11 @@ const AddEditCategoryModal: React.FC<AddEditCategoryModalProps> = ({
|
||||||
{...field}
|
{...field}
|
||||||
required
|
required
|
||||||
placeholder="Enter Admin Name"
|
placeholder="Enter Admin Name"
|
||||||
|
// autoComplete="new-username"
|
||||||
|
type="text"
|
||||||
fullWidth
|
fullWidth
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
error={!!errors.name}
|
error={!!errors.name}
|
||||||
helperText={errors.name?.message}
|
helperText={errors.name?.message}
|
||||||
/>
|
/>
|
||||||
|
@ -202,6 +207,7 @@ const AddEditCategoryModal: React.FC<AddEditCategoryModalProps> = ({
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
width: "50%",
|
width: "50%",
|
||||||
|
...autofillFix,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography variant="body2" fontWeight={500}>
|
||||||
|
@ -226,6 +232,8 @@ const AddEditCategoryModal: React.FC<AddEditCategoryModalProps> = ({
|
||||||
id="email"
|
id="email"
|
||||||
type="email"
|
type="email"
|
||||||
placeholder="Email"
|
placeholder="Email"
|
||||||
|
autoComplete="new-email"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
required
|
required
|
||||||
fullWidth
|
fullWidth
|
||||||
color={
|
color={
|
||||||
|
@ -247,6 +255,7 @@ const AddEditCategoryModal: React.FC<AddEditCategoryModalProps> = ({
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
width: "50%",
|
width: "50%",
|
||||||
|
...autofillFix,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography
|
<Typography
|
||||||
|
@ -276,6 +285,7 @@ const AddEditCategoryModal: React.FC<AddEditCategoryModalProps> = ({
|
||||||
{...field}
|
{...field}
|
||||||
required
|
required
|
||||||
placeholder="Enter Password"
|
placeholder="Enter Password"
|
||||||
|
autoComplete="new-password"
|
||||||
type={
|
type={
|
||||||
showPassword
|
showPassword
|
||||||
? "text"
|
? "text"
|
||||||
|
@ -289,6 +299,7 @@ const AddEditCategoryModal: React.FC<AddEditCategoryModalProps> = ({
|
||||||
: "primary"
|
: "primary"
|
||||||
}
|
}
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
slotProps={{
|
slotProps={{
|
||||||
input: {
|
input: {
|
||||||
endAdornment: (
|
endAdornment: (
|
||||||
|
@ -324,6 +335,7 @@ const AddEditCategoryModal: React.FC<AddEditCategoryModalProps> = ({
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
width: "50%",
|
width: "50%",
|
||||||
|
...autofillFix,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography variant="body2" fontWeight={500}>
|
||||||
|
@ -353,6 +365,7 @@ const AddEditCategoryModal: React.FC<AddEditCategoryModalProps> = ({
|
||||||
required
|
required
|
||||||
placeholder="Enter Phone Number"
|
placeholder="Enter Phone Number"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
error={!!errors.phone}
|
error={!!errors.phone}
|
||||||
helperText={errors.phone?.message}
|
helperText={errors.phone?.message}
|
||||||
/>
|
/>
|
||||||
|
@ -367,6 +380,7 @@ const AddEditCategoryModal: React.FC<AddEditCategoryModalProps> = ({
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
width: "50%",
|
width: "50%",
|
||||||
|
...autofillFix,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography variant="body2" fontWeight={500}>
|
||||||
|
@ -387,6 +401,7 @@ const AddEditCategoryModal: React.FC<AddEditCategoryModalProps> = ({
|
||||||
<CustomTextField
|
<CustomTextField
|
||||||
{...field}
|
{...field}
|
||||||
required
|
required
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
placeholder="Enter Address"
|
placeholder="Enter Address"
|
||||||
fullWidth
|
fullWidth
|
||||||
size="small"
|
size="small"
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { CustomIconButton, CustomTextField } from "../AddUserModal/styled.css";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { RootState } from "../../redux/reducers.ts";
|
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";
|
||||||
|
|
||||||
export default function AddManagerModal({
|
export default function AddManagerModal({
|
||||||
open,
|
open,
|
||||||
|
@ -120,7 +121,7 @@ export default function AddManagerModal({
|
||||||
<form onSubmit={handleSubmit(onSubmit)}>
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
{/* Manager Name */}
|
{/* Manager Name */}
|
||||||
<Box sx={{ display: "flex", gap: 2, mb: 2 }}>
|
<Box sx={{ display: "flex", gap: 2, mb: 2 }}>
|
||||||
<Box sx={{ flex: 1 }}>
|
<Box sx={{ flex: 1, ...autofillFix }}>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography variant="body2" fontWeight={500}>
|
||||||
Manager Name
|
Manager Name
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -128,6 +129,8 @@ export default function AddManagerModal({
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Manager Name"
|
placeholder="Enter Manager Name"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
|
|
||||||
error={!!errors.name}
|
error={!!errors.name}
|
||||||
helperText={
|
helperText={
|
||||||
errors.name ? errors.name.message : ""
|
errors.name ? errors.name.message : ""
|
||||||
|
@ -157,17 +160,43 @@ 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}
|
||||||
|
>
|
||||||
Select Station
|
Select Station
|
||||||
</Typography>
|
</Typography>
|
||||||
<FormControl fullWidth error={!!errors.stationName}>
|
<FormControl
|
||||||
<InputLabel>Select Station</InputLabel>
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
error={!!errors.stationName}
|
||||||
|
>
|
||||||
<Select
|
<Select
|
||||||
{...register("stationName", {
|
{...register("stationName", {
|
||||||
required: "Station Name is required",
|
required: "Station Name is required",
|
||||||
})}
|
})}
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
|
|
||||||
|
displayEmpty
|
||||||
defaultValue=""
|
defaultValue=""
|
||||||
size="small"
|
renderValue={(selected) => {
|
||||||
|
if (!selected) {
|
||||||
|
return (
|
||||||
|
<Typography color="text.secondary">
|
||||||
|
Choose Station
|
||||||
|
</Typography>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return selected;
|
||||||
|
}}
|
||||||
|
MenuProps={{
|
||||||
|
PaperProps: {
|
||||||
|
style: {
|
||||||
|
maxHeight: 224,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{Array.isArray(stations) &&
|
{Array.isArray(stations) &&
|
||||||
stations.length > 0 ? (
|
stations.length > 0 ? (
|
||||||
|
@ -186,7 +215,11 @@ export default function AddManagerModal({
|
||||||
)}
|
)}
|
||||||
</Select>
|
</Select>
|
||||||
{errors.stationName && (
|
{errors.stationName && (
|
||||||
<Typography color="error" variant="body2">
|
<Typography
|
||||||
|
color="error"
|
||||||
|
variant="body2"
|
||||||
|
sx={{ mt: 0.5 }}
|
||||||
|
>
|
||||||
{errors.stationName.message}
|
{errors.stationName.message}
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
|
@ -197,7 +230,7 @@ export default function AddManagerModal({
|
||||||
{/* Email and Password */}
|
{/* Email and Password */}
|
||||||
<Box sx={{ display: "flex", gap: 2, mb: 2 }}>
|
<Box sx={{ display: "flex", gap: 2, mb: 2 }}>
|
||||||
{/* Email */}
|
{/* Email */}
|
||||||
<Box sx={{ flex: 1 }}>
|
<Box sx={{ flex: 1, ...autofillFix }}>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography variant="body2" fontWeight={500}>
|
||||||
Email
|
Email
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -205,6 +238,9 @@ export default function AddManagerModal({
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Manager Email"
|
placeholder="Enter Manager Email"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
|
|
||||||
|
autoComplete="new-email"
|
||||||
error={!!errors.email}
|
error={!!errors.email}
|
||||||
helperText={
|
helperText={
|
||||||
errors.email ? errors.email.message : ""
|
errors.email ? errors.email.message : ""
|
||||||
|
@ -220,7 +256,7 @@ export default function AddManagerModal({
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Password */}
|
{/* Password */}
|
||||||
<Box sx={{ flex: 1 }}>
|
<Box sx={{ flex: 1, ...autofillFix }}>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography variant="body2" fontWeight={500}>
|
||||||
Password
|
Password
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -244,6 +280,9 @@ export default function AddManagerModal({
|
||||||
<CustomTextField
|
<CustomTextField
|
||||||
{...field}
|
{...field}
|
||||||
required
|
required
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
|
|
||||||
|
autoComplete="new-password"
|
||||||
placeholder="Enter Password"
|
placeholder="Enter Password"
|
||||||
type={
|
type={
|
||||||
showPassword ? "text" : "password"
|
showPassword ? "text" : "password"
|
||||||
|
@ -286,7 +325,7 @@ 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 }}>
|
<Box sx={{ flex: 1, ...autofillFix }}>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography variant="body2" fontWeight={500}>
|
||||||
Phone Number
|
Phone Number
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -294,6 +333,8 @@ export default function AddManagerModal({
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Phone Number"
|
placeholder="Enter Phone Number"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
|
|
||||||
error={!!errors.phone}
|
error={!!errors.phone}
|
||||||
helperText={
|
helperText={
|
||||||
errors.phone ? errors.phone.message : ""
|
errors.phone ? errors.phone.message : ""
|
||||||
|
|
|
@ -38,13 +38,17 @@ const AddSlotModal = ({ open, handleClose, handleAddSlot }: any) => {
|
||||||
<DialogTitle>Add EV Slot</DialogTitle>
|
<DialogTitle>Add EV Slot</DialogTitle>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<form onSubmit={handleSubmit(onSubmit)}>
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<Typography variant="body2" fontWeight={500}>
|
||||||
|
Date
|
||||||
|
</Typography>
|
||||||
<TextField
|
<TextField
|
||||||
{...register("date", {
|
{...register("date", {
|
||||||
required: "Date is required",
|
required: "Date is required",
|
||||||
validate: (value) =>
|
validate: (value) =>
|
||||||
value >= today || "Date cannot be in the past",
|
value >= today || "Date cannot be in the past",
|
||||||
})}
|
})}
|
||||||
label="Date"
|
// label="Date"
|
||||||
|
// sx={{ marginTop: 1 }}
|
||||||
type="date"
|
type="date"
|
||||||
fullWidth
|
fullWidth
|
||||||
margin="normal"
|
margin="normal"
|
||||||
|
@ -58,12 +62,16 @@ const AddSlotModal = ({ open, handleClose, handleAddSlot }: any) => {
|
||||||
// Set the min value to today's date
|
// Set the min value to today's date
|
||||||
inputProps={{ min: today }}
|
inputProps={{ min: today }}
|
||||||
/>
|
/>
|
||||||
|
<Typography variant="body2" fontWeight={500}>
|
||||||
|
Start Hour
|
||||||
|
</Typography>
|
||||||
<TextField
|
<TextField
|
||||||
{...register("startHour", {
|
{...register("startHour", {
|
||||||
required: "Start hour is required",
|
required: "Start hour is required",
|
||||||
})}
|
})}
|
||||||
label="Start Hour"
|
// label="Start Hour"
|
||||||
type="time"
|
type="time"
|
||||||
|
// sx={{ marginTop: 1 }}
|
||||||
fullWidth
|
fullWidth
|
||||||
margin="normal"
|
margin="normal"
|
||||||
slotProps={{
|
slotProps={{
|
||||||
|
@ -74,12 +82,16 @@ const AddSlotModal = ({ open, handleClose, handleAddSlot }: any) => {
|
||||||
error={!!errors.startHour}
|
error={!!errors.startHour}
|
||||||
helperText={errors.startHour?.message}
|
helperText={errors.startHour?.message}
|
||||||
/>
|
/>
|
||||||
|
<Typography variant="body2" fontWeight={500}>
|
||||||
|
End Hour
|
||||||
|
</Typography>
|
||||||
<TextField
|
<TextField
|
||||||
{...register("endHour", {
|
{...register("endHour", {
|
||||||
required: "End hour is required",
|
required: "End hour is required",
|
||||||
})}
|
})}
|
||||||
label="End Hour"
|
// label="End Hour"
|
||||||
type="time"
|
type="time"
|
||||||
|
// sx={{ marginTop: 1 }}
|
||||||
fullWidth
|
fullWidth
|
||||||
margin="normal"
|
margin="normal"
|
||||||
InputLabelProps={{
|
InputLabelProps={{
|
||||||
|
@ -95,10 +107,13 @@ const AddSlotModal = ({ open, handleClose, handleAddSlot }: any) => {
|
||||||
justifyContent="space-between"
|
justifyContent="space-between"
|
||||||
gap={2}
|
gap={2}
|
||||||
>
|
>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
onClick={() => setIsAvailable((prev) => !prev)}
|
onClick={() => setIsAvailable((prev) => !prev)}
|
||||||
variant={isAvailable ? "contained" : "outlined"}
|
variant={isAvailable ? "contained" : "outlined"}
|
||||||
color="primary"
|
color="primary"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
|
|
||||||
>
|
>
|
||||||
Check Availability
|
Check Availability
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
@ -44,7 +44,8 @@ const AddStationLocationModal = ({
|
||||||
"City name must be at least 2 characters",
|
"City name must be at least 2 characters",
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
label="City Name"
|
// label="City Name"
|
||||||
|
placeholder="Enter City Name"
|
||||||
fullWidth
|
fullWidth
|
||||||
margin="normal"
|
margin="normal"
|
||||||
error={!!errors.city}
|
error={!!errors.city}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
Checkbox,
|
Checkbox,
|
||||||
ListItemText,
|
ListItemText,
|
||||||
InputLabel,
|
InputLabel,
|
||||||
|
Chip,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import CloseIcon from "@mui/icons-material/Close";
|
import CloseIcon from "@mui/icons-material/Close";
|
||||||
import { useSelector, useDispatch } from "react-redux";
|
import { useSelector, useDispatch } from "react-redux";
|
||||||
|
@ -20,7 +21,9 @@ import {
|
||||||
fetchVehicleBrands,
|
fetchVehicleBrands,
|
||||||
vehicleList,
|
vehicleList,
|
||||||
} from "../../redux/slices/VehicleSlice.ts"; // Adjust this import path accordingly
|
} from "../../redux/slices/VehicleSlice.ts"; // Adjust this import path accordingly
|
||||||
import { CustomIconButton, CustomTextField } from "../AddUserModal/styled.css";// Assuming custom styled components
|
import { CustomIconButton, CustomTextField } from "../AddUserModal/styled.css"; // Assuming custom styled components
|
||||||
|
import React from "react";
|
||||||
|
import { autofillFix } from "../../shared-theme/customizations/autoFill.tsx";
|
||||||
|
|
||||||
export default function AddStationModal({
|
export default function AddStationModal({
|
||||||
open,
|
open,
|
||||||
|
@ -157,6 +160,7 @@ export default function AddStationModal({
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
width: "100%",
|
width: "100%",
|
||||||
|
...autofillFix,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography variant="body2" fontWeight={500}>
|
||||||
|
@ -166,6 +170,7 @@ export default function AddStationModal({
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Station Name"
|
placeholder="Enter Station Name"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
error={!!errors.name}
|
error={!!errors.name}
|
||||||
helperText={
|
helperText={
|
||||||
errors.name ? errors.name.message : ""
|
errors.name ? errors.name.message : ""
|
||||||
|
@ -191,6 +196,7 @@ export default function AddStationModal({
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
width: "100%",
|
width: "100%",
|
||||||
|
...autofillFix,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography variant="body2" fontWeight={500}>
|
||||||
|
@ -200,6 +206,8 @@ export default function AddStationModal({
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Charging Station Address"
|
placeholder="Enter Charging Station Address"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
|
|
||||||
error={!!errors.registeredAddress}
|
error={!!errors.registeredAddress}
|
||||||
helperText={
|
helperText={
|
||||||
errors.registeredAddress
|
errors.registeredAddress
|
||||||
|
@ -230,6 +238,8 @@ export default function AddStationModal({
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Total Slots"
|
placeholder="Enter Total Slots"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
|
|
||||||
type="number"
|
type="number"
|
||||||
error={!!errors.totalSlots}
|
error={!!errors.totalSlots}
|
||||||
helperText={
|
helperText={
|
||||||
|
@ -251,6 +261,120 @@ 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
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
width: "100%",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
fontWeight={500}
|
||||||
|
sx={{ mb: 1 }}
|
||||||
|
>
|
||||||
|
Vehicle Brand
|
||||||
|
</Typography>
|
||||||
|
<FormControl fullWidth size="small">
|
||||||
|
<Select
|
||||||
|
multiple
|
||||||
|
displayEmpty
|
||||||
|
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 (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
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: {
|
||||||
|
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",
|
||||||
|
@ -258,145 +382,80 @@ export default function AddStationModal({
|
||||||
width: "100%",
|
width: "100%",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography
|
||||||
Vehicle Brand
|
variant="body2"
|
||||||
|
fontWeight={500}
|
||||||
|
sx={{ mb: 1 }}
|
||||||
|
>
|
||||||
|
Vehicle Name
|
||||||
</Typography>
|
</Typography>
|
||||||
<FormControl fullWidth>
|
<FormControl
|
||||||
<InputLabel>Choose Brands</InputLabel>
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
disabled={selectedBrands.length === 0}
|
||||||
|
>
|
||||||
<Select
|
<Select
|
||||||
multiple
|
multiple
|
||||||
value={selectedBrands}
|
displayEmpty
|
||||||
onChange={handleBrandChange}
|
sx={{ marginTop: 1 }}
|
||||||
|
|
||||||
|
value={selectedVehicles}
|
||||||
|
onChange={handleVehicleChange}
|
||||||
renderValue={(selected) => {
|
renderValue={(selected) => {
|
||||||
const selectedArray =
|
if (selected.length === 0) {
|
||||||
selected as string[];
|
return (
|
||||||
const displayNames =
|
<Typography color="text.secondary">
|
||||||
selectedArray.slice(0, 1); // First 2 brands
|
{selectedBrands.length ===
|
||||||
|
0
|
||||||
|
? "Select brand first"
|
||||||
|
: "Choose Vehicles"}
|
||||||
|
</Typography>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const displayNames = (
|
||||||
|
selected as string[]
|
||||||
|
).slice(0, 1);
|
||||||
const moreCount =
|
const moreCount =
|
||||||
selectedArray.length - 1;
|
(selected as string[]).length -
|
||||||
|
1;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
flexWrap: "wrap",
|
||||||
gap: 1,
|
gap: 0.5,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{displayNames.map(
|
{displayNames.map(
|
||||||
(id, index) => {
|
(name) => (
|
||||||
const brand =
|
<Chip
|
||||||
vehicleBrands.find(
|
key={name}
|
||||||
(b) =>
|
label={name}
|
||||||
b.id ===
|
size="small"
|
||||||
id
|
sx={{
|
||||||
);
|
height: 24,
|
||||||
return (
|
}}
|
||||||
<Typography
|
/>
|
||||||
key={index}
|
)
|
||||||
variant="body2"
|
|
||||||
>
|
|
||||||
{brand
|
|
||||||
? brand.name
|
|
||||||
: ""}
|
|
||||||
</Typography>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
)}
|
)}
|
||||||
{moreCount > 0 && (
|
{moreCount > 0 && (
|
||||||
<Typography
|
<Chip
|
||||||
variant="body2"
|
label={`+${moreCount} more`}
|
||||||
color="textSecondary"
|
size="small"
|
||||||
>
|
sx={{ height: 24 }}
|
||||||
+{moreCount} more
|
/>
|
||||||
</Typography>
|
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
>
|
MenuProps={{
|
||||||
{vehicleBrands.length > 0 ? (
|
PaperProps: {
|
||||||
vehicleBrands.map((brand) => (
|
style: {
|
||||||
<MenuItem
|
maxHeight: 224,
|
||||||
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.length > 0 ? (
|
||||||
|
|
|
@ -12,6 +12,7 @@ import Visibility from "@mui/icons-material/Visibility";
|
||||||
import VisibilityOff from "@mui/icons-material/VisibilityOff";
|
import VisibilityOff from "@mui/icons-material/VisibilityOff";
|
||||||
import { useForm, Controller } from "react-hook-form";
|
import { useForm, Controller } from "react-hook-form";
|
||||||
import { CustomIconButton, CustomTextField } from "./styled.css.tsx";
|
import { CustomIconButton, CustomTextField } from "./styled.css.tsx";
|
||||||
|
import { autofillFix } from "../../shared-theme/customizations/autoFill.tsx";
|
||||||
|
|
||||||
interface FormData {
|
interface FormData {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -109,6 +110,7 @@ const AddUserModal: React.FC<AddUserModalProps> = ({
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
flex: 1,
|
flex: 1,
|
||||||
|
...autofillFix,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography variant="body2" fontWeight={500}>
|
||||||
|
@ -134,9 +136,11 @@ const AddUserModal: React.FC<AddUserModalProps> = ({
|
||||||
<CustomTextField
|
<CustomTextField
|
||||||
{...field}
|
{...field}
|
||||||
required
|
required
|
||||||
|
autoComplete="username"
|
||||||
placeholder="Enter User Name"
|
placeholder="Enter User Name"
|
||||||
fullWidth
|
fullWidth
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
error={!!errors.name}
|
error={!!errors.name}
|
||||||
helperText={errors.name?.message}
|
helperText={errors.name?.message}
|
||||||
/>
|
/>
|
||||||
|
@ -149,6 +153,7 @@ const AddUserModal: React.FC<AddUserModalProps> = ({
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
flex: 1,
|
flex: 1,
|
||||||
|
...autofillFix,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography variant="body2" fontWeight={500}>
|
||||||
|
@ -172,6 +177,8 @@ const AddUserModal: React.FC<AddUserModalProps> = ({
|
||||||
helperText={errors.email?.message}
|
helperText={errors.email?.message}
|
||||||
type="email"
|
type="email"
|
||||||
placeholder="Email"
|
placeholder="Email"
|
||||||
|
autoComplete="new-email"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
required
|
required
|
||||||
fullWidth
|
fullWidth
|
||||||
color={
|
color={
|
||||||
|
@ -190,6 +197,7 @@ const AddUserModal: React.FC<AddUserModalProps> = ({
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
flex: 1,
|
flex: 1,
|
||||||
|
...autofillFix,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography variant="body2" fontWeight={500}>
|
||||||
|
@ -211,6 +219,7 @@ const AddUserModal: React.FC<AddUserModalProps> = ({
|
||||||
{...field}
|
{...field}
|
||||||
required
|
required
|
||||||
placeholder="Enter Password"
|
placeholder="Enter Password"
|
||||||
|
autoComplete="new-password"
|
||||||
type={
|
type={
|
||||||
showPassword ? "text" : "password"
|
showPassword ? "text" : "password"
|
||||||
}
|
}
|
||||||
|
@ -221,6 +230,7 @@ const AddUserModal: React.FC<AddUserModalProps> = ({
|
||||||
: "primary"
|
: "primary"
|
||||||
}
|
}
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
slotProps={{
|
slotProps={{
|
||||||
input: {
|
input: {
|
||||||
endAdornment: (
|
endAdornment: (
|
||||||
|
@ -254,6 +264,7 @@ const AddUserModal: React.FC<AddUserModalProps> = ({
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
flex: 1,
|
flex: 1,
|
||||||
|
...autofillFix,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="body2" fontWeight={500}>
|
<Typography variant="body2" fontWeight={500}>
|
||||||
|
@ -283,6 +294,7 @@ const AddUserModal: React.FC<AddUserModalProps> = ({
|
||||||
required
|
required
|
||||||
placeholder="Enter Phone Number"
|
placeholder="Enter Phone Number"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
error={!!errors.phone}
|
error={!!errors.phone}
|
||||||
helperText={errors.phone?.message}
|
helperText={errors.phone?.message}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -94,6 +94,8 @@ export default function AddVehicleModal({
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Company Name"
|
placeholder="Enter Company Name"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
|
|
||||||
error={!!errors.company}
|
error={!!errors.company}
|
||||||
helperText={
|
helperText={
|
||||||
errors.company
|
errors.company
|
||||||
|
@ -124,6 +126,8 @@ export default function AddVehicleModal({
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Vehicle Name"
|
placeholder="Enter Vehicle Name"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
|
|
||||||
error={!!errors.name}
|
error={!!errors.name}
|
||||||
helperText={
|
helperText={
|
||||||
errors.name ? errors.name.message : ""
|
errors.name ? errors.name.message : ""
|
||||||
|
@ -166,6 +170,8 @@ export default function AddVehicleModal({
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Model Name"
|
placeholder="Enter Model Name"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
|
|
||||||
error={!!errors.modelName}
|
error={!!errors.modelName}
|
||||||
helperText={
|
helperText={
|
||||||
errors.modelName
|
errors.modelName
|
||||||
|
@ -192,6 +198,8 @@ export default function AddVehicleModal({
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Charge Type"
|
placeholder="Enter Charge Type"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
|
|
||||||
error={!!errors.chargeType}
|
error={!!errors.chargeType}
|
||||||
helperText={
|
helperText={
|
||||||
errors.chargeType
|
errors.chargeType
|
||||||
|
@ -220,6 +228,8 @@ export default function AddVehicleModal({
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Image URL"
|
placeholder="Enter Image URL"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
|
|
||||||
error={!!errors.imageUrl}
|
error={!!errors.imageUrl}
|
||||||
helperText={
|
helperText={
|
||||||
errors.imageUrl
|
errors.imageUrl
|
||||||
|
|
|
@ -9,8 +9,16 @@ import Typography from "@mui/material/Typography";
|
||||||
import MenuRoundedIcon from "@mui/icons-material/MenuRounded";
|
import MenuRoundedIcon from "@mui/icons-material/MenuRounded";
|
||||||
import DashboardRoundedIcon from "@mui/icons-material/DashboardRounded";
|
import DashboardRoundedIcon from "@mui/icons-material/DashboardRounded";
|
||||||
import ColorModeIconDropdown from "../../shared-theme/ColorModeIconDropdown";
|
import ColorModeIconDropdown from "../../shared-theme/ColorModeIconDropdown";
|
||||||
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
import { AppDispatch, RootState } from "../../redux/store/store";
|
||||||
|
import { fetchAdminProfile } from "../../redux/slices/profileSlice";
|
||||||
|
import NotificationsNoneIcon from "@mui/icons-material/NotificationsNone";
|
||||||
|
import InputBase from "@mui/material/InputBase";
|
||||||
|
import SearchIcon from "@mui/icons-material/Search";
|
||||||
import MenuButton from "../MenuButton";
|
import MenuButton from "../MenuButton";
|
||||||
import SideMenuMobile from "../SideMenuMobile";
|
import SideMenuMobile from "../SideMenuMobile";
|
||||||
|
import { Avatar } from "@mui/material";
|
||||||
|
import OptionsMenu from "../OptionsMenu";
|
||||||
|
|
||||||
const Toolbar = styled(MuiToolbar)({
|
const Toolbar = styled(MuiToolbar)({
|
||||||
width: "100%",
|
width: "100%",
|
||||||
|
@ -30,18 +38,28 @@ const Toolbar = styled(MuiToolbar)({
|
||||||
|
|
||||||
export default function AppNavbar() {
|
export default function AppNavbar() {
|
||||||
const [open, setOpen] = React.useState(false);
|
const [open, setOpen] = React.useState(false);
|
||||||
|
const [showNotifications, setShowNotifications] = React.useState(false);
|
||||||
|
const toggleNotifications = () => {
|
||||||
|
setShowNotifications((prev) => !prev);
|
||||||
|
};
|
||||||
|
|
||||||
|
const dispatch = useDispatch<AppDispatch>();
|
||||||
|
const { user } = useSelector((state: RootState) => state?.profileReducer);
|
||||||
const toggleDrawer = (newOpen: boolean) => () => {
|
const toggleDrawer = (newOpen: boolean) => () => {
|
||||||
setOpen(newOpen);
|
setOpen(newOpen);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
dispatch(fetchAdminProfile());
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppBar
|
<AppBar
|
||||||
position="fixed"
|
position="fixed"
|
||||||
sx={{
|
sx={{
|
||||||
display: { xs: "auto", md: "none" },
|
display: { xs: "auto", md: "none" },
|
||||||
boxShadow: 0,
|
boxShadow: 0,
|
||||||
backgroundColor:"#1C1C1C",
|
backgroundColor: "#1C1C1C",
|
||||||
backgroundImage: "none",
|
backgroundImage: "none",
|
||||||
borderBottom: "1px solid",
|
borderBottom: "1px solid",
|
||||||
borderColor: "divider",
|
borderColor: "divider",
|
||||||
|
@ -64,13 +82,64 @@ export default function AppNavbar() {
|
||||||
sx={{ justifyContent: "center", mr: "auto" }}
|
sx={{ justifyContent: "center", mr: "auto" }}
|
||||||
>
|
>
|
||||||
<CustomIcon />
|
<CustomIcon />
|
||||||
<Typography
|
{/* <Typography
|
||||||
variant="h4"
|
variant="h4"
|
||||||
component="h1"
|
component="h1"
|
||||||
sx={{ color: "#202020" }}
|
sx={{ color: "#202020" }}
|
||||||
>
|
>
|
||||||
Dashboard
|
Dashboard
|
||||||
|
</Typography> */}
|
||||||
|
</Stack>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
// width: { xs: "100%", sm: "360px" },
|
||||||
|
height: "40px",
|
||||||
|
|
||||||
|
borderRadius: "8px",
|
||||||
|
border: "1px solid #424242",
|
||||||
|
display: {
|
||||||
|
md: "none",
|
||||||
|
xs: "flex",
|
||||||
|
sm: "flex",
|
||||||
|
lg: "none",
|
||||||
|
},
|
||||||
|
alignItems: "center",
|
||||||
|
padding: "0 12px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SearchIcon sx={{ color: "#FFFFFF" }} />
|
||||||
|
<InputBase
|
||||||
|
sx={{
|
||||||
|
marginLeft: 1,
|
||||||
|
flex: 1,
|
||||||
|
color: "#FFFFFF",
|
||||||
|
fontSize: { xs: "12px", sm: "14px" },
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Stack
|
||||||
|
direction="row"
|
||||||
|
spacing={2}
|
||||||
|
alignItems="center"
|
||||||
|
sx={{
|
||||||
|
pointer: "cursor",
|
||||||
|
display: { xs: "none", sm: "flex" }, // Hide on mobile, show on larger screens
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<NotificationsNoneIcon
|
||||||
|
sx={{ cursor: "pointer" }}
|
||||||
|
onClick={toggleNotifications}
|
||||||
|
/>
|
||||||
|
<Avatar
|
||||||
|
alt="User Avatar"
|
||||||
|
src="/avatar.png"
|
||||||
|
sx={{ width: 36, height: 36 }}
|
||||||
|
/>
|
||||||
|
<Typography variant="body1" sx={{ color: "#FFFFFF" }}>
|
||||||
|
{user?.name || "No Adminsss"}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
|
<OptionsMenu />
|
||||||
</Stack>
|
</Stack>
|
||||||
{/* <ColorModeIconDropdown /> */}
|
{/* <ColorModeIconDropdown /> */}
|
||||||
<MenuButton aria-label="menu" onClick={toggleDrawer(true)}>
|
<MenuButton aria-label="menu" onClick={toggleDrawer(true)}>
|
||||||
|
@ -85,26 +154,29 @@ export default function AppNavbar() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CustomIcon() {
|
export function CustomIcon() {
|
||||||
|
const [open, setOpen] = React.useState(true);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
width: "1.5rem",
|
|
||||||
height: "1.5rem",
|
|
||||||
bgcolor: "black",
|
|
||||||
borderRadius: "999px",
|
|
||||||
display: "flex",
|
display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
alignSelf: "center",
|
pt: 2,
|
||||||
backgroundImage:
|
|
||||||
"linear-gradient(135deg, hsl(210, 98%, 60%) 0%, hsl(210, 100%, 35%) 100%)",
|
|
||||||
color: "hsla(210, 100%, 95%, 0.9)",
|
|
||||||
border: "1px solid",
|
|
||||||
borderColor: "hsl(210, 100%, 55%)",
|
|
||||||
boxShadow: "inset 0 2px 5px rgba(255, 255, 255, 0.3)",
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DashboardRoundedIcon color="inherit" sx={{ fontSize: "1rem" }} />
|
<img
|
||||||
|
src="/evLogo.png"
|
||||||
|
alt="Logo"
|
||||||
|
style={{
|
||||||
|
justifyContent: "center",
|
||||||
|
width: open ? "120px" : "60px",
|
||||||
|
height: "auto",
|
||||||
|
transition: "width 0.5s ease",
|
||||||
|
marginBottom: "10px",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,9 +58,13 @@ const StyledTableRow = styled(TableRow)(({ theme }) => ({
|
||||||
"&:nth-of-type(odd)": {
|
"&:nth-of-type(odd)": {
|
||||||
backgroundColor: theme.palette.action.hover,
|
backgroundColor: theme.palette.action.hover,
|
||||||
},
|
},
|
||||||
|
"&:nth-of-type(even)": {
|
||||||
|
backgroundColor: theme.palette.action.hover,
|
||||||
|
},
|
||||||
"& td, th": {
|
"& td, th": {
|
||||||
borderColor: "#454545", // Applying border color to both td and th
|
borderColor: "#454545", // Applying border color to both td and th
|
||||||
borderWidth: "1px", // Set border width to ensure it appears
|
borderWidth: "1px", // Set border width to ensure it appears
|
||||||
|
borderBottom: "1px solid #454545",
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -227,11 +231,16 @@ const CustomTable: React.FC<CustomTableProps> = ({
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
width: "calc(100% - 48px)",
|
width: { xs: "100%", sm: "100%" },
|
||||||
margin: "0 auto",
|
margin: "0 auto",
|
||||||
padding: "24px",
|
padding: "24px",
|
||||||
backgroundColor: "#1C1C1C",
|
backgroundColor: "#1C1C1C",
|
||||||
borderRadius: "12px",
|
borderRadius: "12px",
|
||||||
|
overflowX: "auto",
|
||||||
|
boxSizing: "border-box",
|
||||||
|
// Ensure CustomTable doesn't affect layout above it
|
||||||
|
position: "relative",
|
||||||
|
zIndex: 1,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography
|
<Typography
|
||||||
|
@ -276,22 +285,24 @@ const CustomTable: React.FC<CustomTableProps> = ({
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
|
flexDirection: { xs: "column", sm: "column", md: "row" },
|
||||||
|
gap: { xs: "16px", sm: "16px", md: "0" },
|
||||||
marginTop: "16px",
|
marginTop: "16px",
|
||||||
alignItems: "center",
|
alignItems: { xs: "stretch", sm: "stretch", md: "center" },
|
||||||
|
width: "100%",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TextField
|
<TextField
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
placeholder="Search"
|
placeholder="Search"
|
||||||
sx={{
|
sx={{
|
||||||
width: "422px",
|
width: { xs: "100%", sm: "100%", md: "380px" },
|
||||||
borderRadius: "12px",
|
borderRadius: "12px",
|
||||||
input: { color: "#FFFFFF" },
|
input: { color: "#FFFFFF" },
|
||||||
backgroundColor: "#272727",
|
backgroundColor: "#272727",
|
||||||
"& .MuiOutlinedInput-root": {
|
"& .MuiOutlinedInput-root": {
|
||||||
borderRadius: "12px",
|
borderRadius: "12px",
|
||||||
width: "422px",
|
width: { xs: "100%", sm: "100%", md: "380px" },
|
||||||
height: "44px",
|
height: "44px",
|
||||||
borderWidth: "1px",
|
borderWidth: "1px",
|
||||||
padding: "14px 12px 14px 12px",
|
padding: "14px 12px 14px 12px",
|
||||||
|
@ -319,6 +330,7 @@ const CustomTable: React.FC<CustomTableProps> = ({
|
||||||
value={searchQuery}
|
value={searchQuery}
|
||||||
onChange={(e) => setSearchQuery(e.target.value)}
|
onChange={(e) => setSearchQuery(e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
|
@ -374,7 +386,7 @@ const CustomTable: React.FC<CustomTableProps> = ({
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<IconButton
|
{/* <IconButton
|
||||||
sx={{
|
sx={{
|
||||||
width: "44px",
|
width: "44px",
|
||||||
height: "44px",
|
height: "44px",
|
||||||
|
@ -388,7 +400,7 @@ const CustomTable: React.FC<CustomTableProps> = ({
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TuneIcon />
|
<TuneIcon />
|
||||||
</IconButton>
|
</IconButton> */}
|
||||||
</Box>
|
</Box>
|
||||||
{/* Table Section */}
|
{/* Table Section */}
|
||||||
<TableContainer
|
<TableContainer
|
||||||
|
@ -397,10 +409,21 @@ const CustomTable: React.FC<CustomTableProps> = ({
|
||||||
marginTop: "24px",
|
marginTop: "24px",
|
||||||
backgroundColor: "#1C1C1C",
|
backgroundColor: "#1C1C1C",
|
||||||
borderRadius: "12px",
|
borderRadius: "12px",
|
||||||
overflow: "hidden",
|
overflow: "auto",
|
||||||
|
maxWidth: "100%",
|
||||||
|
"&::-webkit-scrollbar": {
|
||||||
|
height: "3px",
|
||||||
|
},
|
||||||
|
"&::-webkit-scrollbar-track": {
|
||||||
|
background: "#1C1C1C",
|
||||||
|
},
|
||||||
|
"&::-webkit-scrollbar-thumb": {
|
||||||
|
background: "#52ACDF",
|
||||||
|
borderRadius: "4px",
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Table>
|
<Table sx={{ minWidth: "750px", tableLayout: "auto" }}>
|
||||||
<TableHead
|
<TableHead
|
||||||
sx={{
|
sx={{
|
||||||
backgroundColor: "#272727",
|
backgroundColor: "#272727",
|
||||||
|
@ -408,6 +431,7 @@ const CustomTable: React.FC<CustomTableProps> = ({
|
||||||
".css-1ex4ubw-MuiTableCell-root.MuiTableCell-head ":
|
".css-1ex4ubw-MuiTableCell-root.MuiTableCell-head ":
|
||||||
{
|
{
|
||||||
backgroundColor: "#272727",
|
backgroundColor: "#272727",
|
||||||
|
borderBottom: "1px solid #454545",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -419,6 +443,16 @@ const CustomTable: React.FC<CustomTableProps> = ({
|
||||||
sx={{
|
sx={{
|
||||||
color: "#FFFFFF",
|
color: "#FFFFFF",
|
||||||
fontWeight: "600",
|
fontWeight: "600",
|
||||||
|
...(column.id === "action" && {
|
||||||
|
position: "sticky",
|
||||||
|
right: 0,
|
||||||
|
zIndex: 2,
|
||||||
|
backgroundColor: "#272727",
|
||||||
|
boxShadow:
|
||||||
|
"-5px 0 5px -2px rgba(0,0,0,0.15)",
|
||||||
|
borderBottom:
|
||||||
|
"1px solid #454545",
|
||||||
|
}),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{column.label}
|
{column.label}
|
||||||
|
@ -433,51 +467,103 @@ const CustomTable: React.FC<CustomTableProps> = ({
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{currentRows.map((row, rowIndex) => (
|
{/* This is where the modification starts */}
|
||||||
<StyledTableRow key={rowIndex}>
|
{currentRows.length === 0 ? (
|
||||||
{columns.map((column) => (
|
<StyledTableRow>
|
||||||
<StyledTableCell
|
<StyledTableCell
|
||||||
key={column.id}
|
colSpan={columns.length}
|
||||||
sx={{
|
sx={{
|
||||||
color: "#D9D8D8",
|
color: "#D9D8D8",
|
||||||
backgroundColor: "#272727",
|
backgroundColor: "#272727",
|
||||||
}}
|
textAlign: "center",
|
||||||
>
|
padding: "32px 0",
|
||||||
{isImage(row[column.id]) ? (
|
}}
|
||||||
<img
|
>
|
||||||
src={row[column.id]}
|
{(() => {
|
||||||
alt="Row "
|
switch (tableType) {
|
||||||
style={{
|
case "admin":
|
||||||
width: "50px",
|
return "No admins found";
|
||||||
height: "50px",
|
case "role":
|
||||||
objectFit: "cover",
|
return "No roles found";
|
||||||
}}
|
case "user":
|
||||||
/>
|
return "No users found";
|
||||||
) : column.id !== "action" ? (
|
case "manager":
|
||||||
row[column.id]
|
return "No managers found";
|
||||||
) : (
|
case "vehicle":
|
||||||
<CustomIconButton
|
return "No vehicles found";
|
||||||
onClick={(e) => {
|
case "station":
|
||||||
handleClick(e, row);
|
return "No charging stations found";
|
||||||
setRowData(row); // Store the selected row
|
case "external-station":
|
||||||
}}
|
return "No charging stations found";
|
||||||
sx={{
|
case "booking":
|
||||||
padding: 0,
|
return "No bookings found";
|
||||||
minWidth: 0,
|
case "slots":
|
||||||
width: "auto",
|
return "No slots found";
|
||||||
height: "auto",
|
case "all-available-slots":
|
||||||
color: "#FFFFFF",
|
return "No available slots found";
|
||||||
}}
|
default:
|
||||||
>
|
return "No data available";
|
||||||
<MoreHorizRoundedIcon
|
}
|
||||||
sx={{ fontSize: "24px" }}
|
})()}
|
||||||
/>
|
</StyledTableCell>
|
||||||
</CustomIconButton>
|
|
||||||
)}
|
|
||||||
</StyledTableCell>
|
|
||||||
))}
|
|
||||||
</StyledTableRow>
|
</StyledTableRow>
|
||||||
))}
|
) : (
|
||||||
|
currentRows.map((row, rowIndex) => (
|
||||||
|
<StyledTableRow key={rowIndex}>
|
||||||
|
{columns.map((column) => (
|
||||||
|
<StyledTableCell
|
||||||
|
key={column.id}
|
||||||
|
sx={{
|
||||||
|
color: "#D9D8D8",
|
||||||
|
backgroundColor: "#272727",
|
||||||
|
...(column.id === "action" && {
|
||||||
|
position: "sticky",
|
||||||
|
right: 0,
|
||||||
|
zIndex: 2,
|
||||||
|
backgroundColor: "#272727",
|
||||||
|
boxShadow:
|
||||||
|
"-5px 0 5px -2px rgba(0,0,0,0.15)",
|
||||||
|
}),
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{isImage(row[column.id]) ? (
|
||||||
|
<img
|
||||||
|
src={row[column.id]}
|
||||||
|
alt="Row "
|
||||||
|
style={{
|
||||||
|
width: "50px",
|
||||||
|
height: "50px",
|
||||||
|
objectFit: "cover",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : column.id !== "action" ? (
|
||||||
|
row[column.id]
|
||||||
|
) : (
|
||||||
|
<CustomIconButton
|
||||||
|
onClick={(e) => {
|
||||||
|
handleClick(e, row);
|
||||||
|
setRowData(row);
|
||||||
|
}}
|
||||||
|
sx={{
|
||||||
|
padding: 0,
|
||||||
|
minWidth: 0,
|
||||||
|
width: "auto",
|
||||||
|
height: "auto",
|
||||||
|
color: "#FFFFFF",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MoreHorizRoundedIcon
|
||||||
|
sx={{
|
||||||
|
fontSize: "24px",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</CustomIconButton>
|
||||||
|
)}
|
||||||
|
</StyledTableCell>
|
||||||
|
))}
|
||||||
|
</StyledTableRow>
|
||||||
|
))
|
||||||
|
)}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
</TableContainer>
|
</TableContainer>
|
||||||
|
|
|
@ -171,6 +171,8 @@ const EditManagerModal: React.FC<EditManagerModalProps> = ({
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Manager Name"
|
placeholder="Enter Manager Name"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
|
|
||||||
error={!!errors.name}
|
error={!!errors.name}
|
||||||
helperText={errors.name?.message}
|
helperText={errors.name?.message}
|
||||||
/>
|
/>
|
||||||
|
@ -193,6 +195,8 @@ const EditManagerModal: React.FC<EditManagerModalProps> = ({
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Email"
|
placeholder="Enter Email"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
|
|
||||||
error={!!errors.email}
|
error={!!errors.email}
|
||||||
helperText={errors.email?.message}
|
helperText={errors.email?.message}
|
||||||
/>
|
/>
|
||||||
|
@ -229,6 +233,8 @@ const EditManagerModal: React.FC<EditManagerModalProps> = ({
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Phone Number"
|
placeholder="Enter Phone Number"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
|
|
||||||
error={!!errors.phone}
|
error={!!errors.phone}
|
||||||
helperText={errors.phone?.message}
|
helperText={errors.phone?.message}
|
||||||
/>
|
/>
|
||||||
|
@ -249,6 +255,7 @@ const EditManagerModal: React.FC<EditManagerModalProps> = ({
|
||||||
borderRadius: "8px",
|
borderRadius: "8px",
|
||||||
width: "117px",
|
width: "117px",
|
||||||
"&:hover": { backgroundColor: "#439BC1" },
|
"&:hover": { backgroundColor: "#439BC1" },
|
||||||
|
whiteSpace: "pre",
|
||||||
}}
|
}}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
>
|
>
|
||||||
|
|
|
@ -20,10 +20,7 @@ import {
|
||||||
fetchVehicleBrands,
|
fetchVehicleBrands,
|
||||||
vehicleList,
|
vehicleList,
|
||||||
} from "../../redux/slices/VehicleSlice";
|
} from "../../redux/slices/VehicleSlice";
|
||||||
import {
|
import { CustomIconButton, CustomTextField } from "../AddUserModal/styled.css"; // Assuming custom styled components
|
||||||
CustomIconButton,
|
|
||||||
CustomTextField,
|
|
||||||
} from "../AddUserModal/styled.css"; // Assuming custom styled components
|
|
||||||
|
|
||||||
interface FormData {
|
interface FormData {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -81,11 +78,33 @@ const EditStationModal: React.FC<EditStationModalProps> = ({
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch(fetchVehicleBrands());
|
dispatch(fetchVehicleBrands());
|
||||||
dispatch(vehicleList()); // Fetch vehicles when the component mounts
|
dispatch(vehicleList());
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (editRow) {
|
if (editRow) {
|
||||||
|
// Determine the brand based on the first vehicle's company
|
||||||
|
const firstVehicle = vehicles.find(
|
||||||
|
(vehicle) =>
|
||||||
|
editRow.allowedCarIds &&
|
||||||
|
editRow.allowedCarIds.includes(vehicle.name)
|
||||||
|
);
|
||||||
|
|
||||||
|
const brandId = firstVehicle ? firstVehicle.company : "";
|
||||||
|
setSelectedBrands(brandId);
|
||||||
|
|
||||||
|
// Populate selected vehicles
|
||||||
|
const vehicleNames = vehicles
|
||||||
|
.filter(
|
||||||
|
(vehicle) =>
|
||||||
|
editRow.allowedCarIds &&
|
||||||
|
editRow.allowedCarIds.includes(vehicle.name)
|
||||||
|
)
|
||||||
|
.map((vehicle) => vehicle.name);
|
||||||
|
|
||||||
|
setSelectedVehicles(vehicleNames);
|
||||||
|
|
||||||
|
// Set form values
|
||||||
setValue("name", editRow.name);
|
setValue("name", editRow.name);
|
||||||
setValue("registeredAddress", editRow.registeredAddress);
|
setValue("registeredAddress", editRow.registeredAddress);
|
||||||
setValue("totalSlots", editRow.totalSlots);
|
setValue("totalSlots", editRow.totalSlots);
|
||||||
|
@ -94,15 +113,13 @@ const EditStationModal: React.FC<EditStationModalProps> = ({
|
||||||
setSelectedVehicles(editRow.allowedCarIds || []);
|
setSelectedVehicles(editRow.allowedCarIds || []);
|
||||||
|
|
||||||
// Set selectedBrands based on the vehicles associated with the station
|
// Set selectedBrands based on the vehicles associated with the station
|
||||||
const brands = editRow?.allowedCarIds
|
const brands = editRow?.allowedCarIds
|
||||||
? vehicles
|
? vehicles
|
||||||
.filter((vehicle) =>
|
.filter((vehicle) =>
|
||||||
editRow.allowedCarIds.includes(vehicle.id)
|
editRow.allowedCarIds.includes(vehicle.id)
|
||||||
)
|
)
|
||||||
.map((vehicle) => vehicle.company)
|
.map((vehicle) => vehicle.company)
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
setSelectedBrands(brands);
|
setSelectedBrands(brands);
|
||||||
} else {
|
} else {
|
||||||
|
@ -112,13 +129,11 @@ const EditStationModal: React.FC<EditStationModalProps> = ({
|
||||||
}
|
}
|
||||||
}, [editRow, setValue, reset, vehicles]);
|
}, [editRow, setValue, reset, vehicles]);
|
||||||
|
|
||||||
|
|
||||||
// Filter vehicles based on selected brands
|
// Filter vehicles based on selected brands
|
||||||
const filteredVehicles = vehicles.filter((vehicle) =>
|
const filteredVehicles = vehicles.filter((vehicle) =>
|
||||||
selectedBrands.includes(vehicle.company)
|
selectedBrands.includes(vehicle.company)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// Handle changes in vehicle brand selection
|
// Handle changes in vehicle brand selection
|
||||||
const handleBrandChange = (
|
const handleBrandChange = (
|
||||||
event: React.ChangeEvent<{ value: unknown }>
|
event: React.ChangeEvent<{ value: unknown }>
|
||||||
|
@ -133,37 +148,35 @@ const EditStationModal: React.FC<EditStationModalProps> = ({
|
||||||
setSelectedVehicles(filtered.map((v) => v.name)); // Automatically select vehicles for the selected brands
|
setSelectedVehicles(filtered.map((v) => v.name)); // Automatically select vehicles for the selected brands
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Handle changes in vehicle selection
|
// Handle changes in vehicle selection
|
||||||
const handleCheckboxChange = (
|
const handleCheckboxChange = (
|
||||||
event: React.ChangeEvent<{ value: unknown }>
|
event: React.ChangeEvent<{ value: unknown }>
|
||||||
) => {
|
) => {
|
||||||
const value = event.target.value as string[];
|
const value = event.target.value as string[];
|
||||||
setSelectedVehicles(value);
|
setSelectedVehicles(value);
|
||||||
setValue("allowedCarIds", value); // Update allowedCarIds in form state
|
setValue("allowedCarIds", value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSubmit = (data: FormData) => {
|
const onSubmit = (data: FormData) => {
|
||||||
const vehicleIds = vehicles
|
const vehicleIds = vehicles
|
||||||
.filter((vehicle) => selectedVehicles.includes(vehicle.name))
|
.filter((vehicle) => selectedVehicles.includes(vehicle.name))
|
||||||
.map((vehicle) => Number(vehicle.id));
|
.map((vehicle) => Number(vehicle.id));
|
||||||
|
|
||||||
handleUpdate(
|
handleUpdate(
|
||||||
editRow.id,
|
editRow.id,
|
||||||
data.name,
|
data.name,
|
||||||
data.registeredAddress,
|
data.registeredAddress,
|
||||||
data.totalSlots,
|
data.totalSlots,
|
||||||
vehicleIds
|
vehicleIds
|
||||||
);
|
);
|
||||||
handleClose();
|
handleClose();
|
||||||
reset();
|
reset();
|
||||||
setSelectedBrands([]); // Reset brands after submit
|
setSelectedBrands([]); // Reset brands after submit
|
||||||
setSelectedVehicles([]); // Reset selected vehicles
|
setSelectedVehicles([]); // Reset selected vehicles
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log("editRow:", editRow);
|
console.log("editRow:", editRow);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
open={open}
|
open={open}
|
||||||
|
@ -236,6 +249,7 @@ const onSubmit = (data: FormData) => {
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Station Name"
|
placeholder="Enter Station Name"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
error={!!errors.name}
|
error={!!errors.name}
|
||||||
helperText={
|
helperText={
|
||||||
errors.name
|
errors.name
|
||||||
|
@ -269,6 +283,7 @@ const onSubmit = (data: FormData) => {
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Registered Address"
|
placeholder="Enter Registered Address"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
error={!!errors.registeredAddress}
|
error={!!errors.registeredAddress}
|
||||||
helperText={
|
helperText={
|
||||||
errors.registeredAddress
|
errors.registeredAddress
|
||||||
|
@ -307,6 +322,7 @@ const onSubmit = (data: FormData) => {
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Total Slots"
|
placeholder="Enter Total Slots"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
type="number"
|
type="number"
|
||||||
error={!!errors.totalSlots}
|
error={!!errors.totalSlots}
|
||||||
helperText={
|
helperText={
|
||||||
|
@ -336,6 +352,7 @@ const onSubmit = (data: FormData) => {
|
||||||
<InputLabel>Choose Brand</InputLabel>
|
<InputLabel>Choose Brand</InputLabel>
|
||||||
<Select
|
<Select
|
||||||
multiple
|
multiple
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
value={selectedBrands}
|
value={selectedBrands}
|
||||||
onChange={handleBrandChange}
|
onChange={handleBrandChange}
|
||||||
label="Choose Brands"
|
label="Choose Brands"
|
||||||
|
@ -426,6 +443,7 @@ const onSubmit = (data: FormData) => {
|
||||||
<InputLabel>Choose Vehicles</InputLabel>
|
<InputLabel>Choose Vehicles</InputLabel>
|
||||||
<Select
|
<Select
|
||||||
multiple
|
multiple
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
value={selectedVehicles}
|
value={selectedVehicles}
|
||||||
onChange={handleCheckboxChange}
|
onChange={handleCheckboxChange}
|
||||||
renderValue={(selected) => {
|
renderValue={(selected) => {
|
||||||
|
|
|
@ -133,6 +133,7 @@ const EditUserModal: React.FC<EditUserModalProps> = ({
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Full Name"
|
placeholder="Enter Full Name"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
error={!!errors.name}
|
error={!!errors.name}
|
||||||
helperText={errors.name?.message}
|
helperText={errors.name?.message}
|
||||||
/>
|
/>
|
||||||
|
@ -163,6 +164,7 @@ const EditUserModal: React.FC<EditUserModalProps> = ({
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Email"
|
placeholder="Enter Email"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
error={!!errors.email}
|
error={!!errors.email}
|
||||||
helperText={errors.email?.message}
|
helperText={errors.email?.message}
|
||||||
/>
|
/>
|
||||||
|
@ -199,6 +201,7 @@ const EditUserModal: React.FC<EditUserModalProps> = ({
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Phone Number"
|
placeholder="Enter Phone Number"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
error={!!errors.phone}
|
error={!!errors.phone}
|
||||||
helperText={errors.phone?.message}
|
helperText={errors.phone?.message}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -174,6 +174,7 @@ const EditVehicleModal: React.FC<EditVehicleModalProps> = ({
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Vehicle Name"
|
placeholder="Enter Vehicle Name"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
error={!!errors.name}
|
error={!!errors.name}
|
||||||
helperText={errors.name?.message}
|
helperText={errors.name?.message}
|
||||||
|
|
||||||
|
@ -206,6 +207,7 @@ const EditVehicleModal: React.FC<EditVehicleModalProps> = ({
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Company Name"
|
placeholder="Enter Company Name"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
error={!!errors.company}
|
error={!!errors.company}
|
||||||
helperText={errors.company?.message}
|
helperText={errors.company?.message}
|
||||||
/>
|
/>
|
||||||
|
@ -240,6 +242,7 @@ const EditVehicleModal: React.FC<EditVehicleModalProps> = ({
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Model Name"
|
placeholder="Enter Model Name"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
error={!!errors.modelName}
|
error={!!errors.modelName}
|
||||||
helperText={errors.modelName?.message}
|
helperText={errors.modelName?.message}
|
||||||
/>
|
/>
|
||||||
|
@ -271,6 +274,7 @@ const EditVehicleModal: React.FC<EditVehicleModalProps> = ({
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Charge Type"
|
placeholder="Enter Charge Type"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
error={!!errors.chargeType}
|
error={!!errors.chargeType}
|
||||||
helperText={errors.chargeType?.message}
|
helperText={errors.chargeType?.message}
|
||||||
/>
|
/>
|
||||||
|
@ -300,6 +304,7 @@ const EditVehicleModal: React.FC<EditVehicleModalProps> = ({
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Image URL"
|
placeholder="Enter Image URL"
|
||||||
size="small"
|
size="small"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
error={!!errors.imageUrl}
|
error={!!errors.imageUrl}
|
||||||
helperText={errors.imageUrl?.message}
|
helperText={errors.imageUrl?.message}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -26,16 +26,25 @@ export default function Header() {
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: "84px",
|
height: "84px",
|
||||||
backgroundColor: "#1C1C1C",
|
minHeight: "84px",
|
||||||
padding: { xs: "20px 12px", sm: "20px 24px" },
|
maxHeight: "84px",
|
||||||
display: "flex",
|
backgroundColor: "#1C1C1C",
|
||||||
alignItems: "center",
|
padding: { xs: "20px 12px", sm: "20px 24px" },
|
||||||
justifyContent: "space-between",
|
display: {
|
||||||
flexDirection: { xs: "column", sm: "row" },
|
xs: "none",
|
||||||
}}
|
md: "flex",
|
||||||
|
},
|
||||||
|
marginTop: { xs: "0px", sm: "0px" },
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
flexDirection: { xs: "column", sm: "row" },
|
||||||
|
boxSizing: "border-box",
|
||||||
|
overflowX: "hidden",
|
||||||
|
flex: "0 0 84px",
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Stack
|
<Stack
|
||||||
direction="row"
|
direction="row"
|
||||||
|
@ -45,14 +54,17 @@ export default function Header() {
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
justifyContent: { xs: "center", sm: "flex-end" },
|
justifyContent: { xs: "center", sm: "flex-end" },
|
||||||
marginTop: { xs: 2, sm: 0 },
|
marginTop: { xs: 0, sm: 0 }, // Remove top margin on mobile
|
||||||
|
flexWrap: { xs: "wrap", sm: "nowrap" },
|
||||||
|
maxHeight: "100%", // Ensure content doesn't push height
|
||||||
|
overflow: "hidden", // Prevent overflow
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* Search Bar */}
|
{/* Search Bar */}
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
// width: { xs: "100%", sm: "360px" },
|
// width: { xs: "100%", sm: "360px" },
|
||||||
height: "44px",
|
height: "40px",
|
||||||
|
|
||||||
borderRadius: "8px",
|
borderRadius: "8px",
|
||||||
border: "1px solid #424242",
|
border: "1px solid #424242",
|
||||||
|
@ -78,17 +90,21 @@ export default function Header() {
|
||||||
spacing={2}
|
spacing={2}
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
sx={{
|
sx={{
|
||||||
|
pointer: "cursor",
|
||||||
display: { xs: "none", sm: "flex" }, // Hide on mobile, show on larger screens
|
display: { xs: "none", sm: "flex" }, // Hide on mobile, show on larger screens
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<NotificationsNoneIcon onClick={toggleNotifications} />
|
<NotificationsNoneIcon
|
||||||
|
sx={{ cursor: "pointer" }}
|
||||||
|
onClick={toggleNotifications}
|
||||||
|
/>
|
||||||
<Avatar
|
<Avatar
|
||||||
alt="User Avatar"
|
alt="User Avatar"
|
||||||
src="/avatar.png"
|
src="/avatar.png"
|
||||||
sx={{ width: 36, height: 36 }}
|
sx={{ width: 36, height: 36 }}
|
||||||
/>
|
/>
|
||||||
<Typography variant="body1" sx={{ color: "#FFFFFF" }}>
|
<Typography variant="body1" sx={{ color: "#FFFFFF" }}>
|
||||||
{user?.name || "No Admin"}
|
{user?.name || "No Adminsss"}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<OptionsMenu />
|
<OptionsMenu />
|
||||||
|
|
|
@ -10,6 +10,7 @@ import useMediaQuery from "@mui/material/useMediaQuery";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { AppDispatch, RootState } from "../../redux/store/store";
|
import { AppDispatch, RootState } from "../../redux/store/store";
|
||||||
import { fetchDashboardData } from "../../redux/slices/dashboardSlice";
|
import { fetchDashboardData } from "../../redux/slices/dashboardSlice";
|
||||||
|
import { Box } from "@mui/material";
|
||||||
|
|
||||||
function AreaGradient({ color, id }: { color: string; id: string }) {
|
function AreaGradient({ color, id }: { color: string; id: string }) {
|
||||||
return (
|
return (
|
||||||
|
@ -159,12 +160,13 @@ export default function LineChartCard() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Line Chart */}
|
{/* Line Chart */}
|
||||||
|
<Box sx={{ mt: 7.5 }}>
|
||||||
<LineChart
|
<LineChart
|
||||||
colors={[theme.palette.primary.main]}
|
colors={[theme.palette.primary.main]}
|
||||||
xAxis={[
|
xAxis={[
|
||||||
{
|
{
|
||||||
scaleType: "point",
|
scaleType: "point",
|
||||||
data: chartData.map((data) => data.label), // Use intervals as x-axis labels
|
data: chartData.map((data) => data.label),
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
series={[
|
series={[
|
||||||
|
@ -173,7 +175,7 @@ export default function LineChartCard() {
|
||||||
showMark: false,
|
showMark: false,
|
||||||
curve: "linear",
|
curve: "linear",
|
||||||
area: true,
|
area: true,
|
||||||
data: chartData.map((data) => data.value), // Use interval data for y-axis
|
data: chartData.map((data) => data.value),
|
||||||
color: theme.palette.primary.main,
|
color: theme.palette.primary.main,
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
@ -191,6 +193,7 @@ export default function LineChartCard() {
|
||||||
id="totalBookings"
|
id="totalBookings"
|
||||||
/>
|
/>
|
||||||
</LineChart>
|
</LineChart>
|
||||||
|
</Box>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
|
|
@ -12,43 +12,37 @@ import { fetchDashboardData } from "../../redux/slices/dashboardSlice";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
|
|
||||||
export default function MainGrid() {
|
export default function MainGrid() {
|
||||||
const dispatch = useDispatch<AppDispatch>();
|
const dispatch = useDispatch<AppDispatch>();
|
||||||
const {
|
const {
|
||||||
totalAdmins,
|
totalAdmins,
|
||||||
totalManagers,
|
totalManagers,
|
||||||
totalUsers,
|
totalUsers,
|
||||||
totalStations,
|
totalStations,
|
||||||
loading,
|
loading,
|
||||||
error,
|
error,
|
||||||
} = useSelector((state: RootState) => state.dashboardReducer);
|
} = useSelector((state: RootState) => state.dashboardReducer);
|
||||||
|
|
||||||
|
const staticData = {
|
||||||
|
|
||||||
const staticData = {
|
|
||||||
totalAdmins: 86,
|
totalAdmins: 86,
|
||||||
totalManagers: 12,
|
totalManagers: 12,
|
||||||
totalUsers: 24,
|
totalUsers: 24,
|
||||||
totalStations: 8,
|
totalStations: 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
dispatch(fetchDashboardData());
|
||||||
dispatch(fetchDashboardData());
|
|
||||||
|
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
const data =
|
const data = { totalAdmins, totalManagers, totalUsers, totalStations };
|
||||||
{ totalAdmins, totalManagers, totalUsers, totalStations }
|
|
||||||
|
|
||||||
|
|
||||||
const statCards = [
|
const statCards = [
|
||||||
{ title: "Total Admins", value: data.totalAdmins },
|
{ title: "Total Admins", value: data.totalAdmins },
|
||||||
{ title: "Total Managers", value: data.totalManagers },
|
{ title: "Total Managers", value: data.totalManagers },
|
||||||
{ title: "Total Users", value: data.totalUsers },
|
{ title: "Total Users", value: data.totalUsers },
|
||||||
{ title: "Total Stations", value: data.totalStations },
|
{ title: "Total Stations", value: data.totalStations },
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
|
@ -86,5 +80,5 @@ export default function MainGrid() {
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ export default function MenuButton({
|
||||||
invisible={!showBadge}
|
invisible={!showBadge}
|
||||||
sx={{ [`& .${badgeClasses.badge}`]: { right: 2, top: 2 } }}
|
sx={{ [`& .${badgeClasses.badge}`]: { right: 2, top: 2 } }}
|
||||||
>
|
>
|
||||||
<IconButton size="small" {...props} />
|
<IconButton sx={{ marginRight: "60px" }} size="small" {...props} />
|
||||||
</Badge>
|
</Badge>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,7 +144,9 @@ export default function MenuContent({ hidden }: PropType) {
|
||||||
fontSize: "16px",
|
fontSize: "16px",
|
||||||
letterSpacing: "0%",
|
letterSpacing: "0%",
|
||||||
lineHeight: "100%",
|
lineHeight: "100%",
|
||||||
color: "#D9D8D8",
|
whiteSpace: "pre",
|
||||||
|
color: "#FAFAFA",
|
||||||
|
marginTop: "5px",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
primary={item.text}
|
primary={item.text}
|
||||||
|
|
|
@ -12,10 +12,10 @@ import { useEffect } from "react";
|
||||||
import { fetchDashboardData } from "../../redux/slices/dashboardSlice";
|
import { fetchDashboardData } from "../../redux/slices/dashboardSlice";
|
||||||
|
|
||||||
const colorPalette = [
|
const colorPalette = [
|
||||||
"hsla(202, 69%, 60%, 1)",
|
"hsla(202, 69%, 60%, 1)",
|
||||||
"hsl(204, 48.60%, 72.50%)",
|
"hsl(204, 48.60%, 72.50%)",
|
||||||
"hsl(214, 56.40%, 30.60%)",
|
"hsl(214, 56.40%, 30.60%)",
|
||||||
"hsl(222, 6.80%, 50.80%)",
|
"hsl(222, 6.80%, 50.80%)",
|
||||||
];
|
];
|
||||||
|
|
||||||
// const data = [
|
// const data = [
|
||||||
|
@ -26,17 +26,17 @@ const colorPalette = [
|
||||||
// ];
|
// ];
|
||||||
|
|
||||||
export default function ResourcePieChart() {
|
export default function ResourcePieChart() {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isXsScreen = useMediaQuery(theme.breakpoints.down("sm"));
|
const isXsScreen = useMediaQuery(theme.breakpoints.down("sm"));
|
||||||
const isSmScreen = useMediaQuery(theme.breakpoints.between("sm", "md"));
|
const isSmScreen = useMediaQuery(theme.breakpoints.between("sm", "md"));
|
||||||
const dispatch = useDispatch<AppDispatch>();
|
const dispatch = useDispatch<AppDispatch>();
|
||||||
|
|
||||||
// // Fetch role and carPortCounts from Redux state
|
// // Fetch role and carPortCounts from Redux state
|
||||||
// const {user} = useSelector((state: RootState) => state.profileReducer); // Assuming user role is stored in Redux
|
// const {user} = useSelector((state: RootState) => state.profileReducer); // Assuming user role is stored in Redux
|
||||||
const { carPortCounts } = useSelector(
|
const { carPortCounts } = useSelector(
|
||||||
(state: RootState) => state.dashboardReducer
|
(state: RootState) => state.dashboardReducer
|
||||||
);
|
);
|
||||||
console.log("first",carPortCounts)
|
console.log("first", carPortCounts);
|
||||||
// Static data for non-superadmin roles
|
// Static data for non-superadmin roles
|
||||||
// const staticCarPorts = [
|
// const staticCarPorts = [
|
||||||
// { carPort: "240V", count: 5 },
|
// { carPort: "240V", count: 5 },
|
||||||
|
@ -45,52 +45,50 @@ export default function ResourcePieChart() {
|
||||||
// { carPort: "Other", count: 7 },
|
// { carPort: "Other", count: 7 },
|
||||||
// ];
|
// ];
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
||||||
dispatch(fetchDashboardData());
|
dispatch(fetchDashboardData());
|
||||||
|
}, [dispatch]);
|
||||||
}, [dispatch]);
|
|
||||||
|
|
||||||
// console.log("Raw CarPortCounts from API:", carPortCounts);
|
// console.log("Raw CarPortCounts from API:", carPortCounts);
|
||||||
|
|
||||||
const dataToDisplay =carPortCounts
|
const dataToDisplay = carPortCounts;
|
||||||
|
|
||||||
// const dataToDisplay =
|
// const dataToDisplay =
|
||||||
// user?.userType === "superadmin"
|
// user?.userType === "superadmin"
|
||||||
// ? carPortCounts.filter((entry) => entry.count > 0) // Exclude zero counts
|
// ? carPortCounts.filter((entry) => entry.count > 0) // Exclude zero counts
|
||||||
// : staticCarPorts.filter((entry) => entry.count > 0);
|
// : staticCarPorts.filter((entry) => entry.count > 0);
|
||||||
// console.log("Filtered Data to Display:", dataToDisplay);
|
// console.log("Filtered Data to Display:", dataToDisplay);
|
||||||
const getChartDimensions = () => {
|
const getChartDimensions = () => {
|
||||||
if (isXsScreen) {
|
if (isXsScreen) {
|
||||||
return {
|
return {
|
||||||
height: 240,
|
height: 240,
|
||||||
width: 240,
|
width: 240,
|
||||||
innerRadius: 40,
|
innerRadius: 40,
|
||||||
outerRadius: 80,
|
outerRadius: 80,
|
||||||
margin: { left: 20, right: 20, top: 40, bottom: 40 }
|
margin: { left: 20, right: 20, top: 40, bottom: 40 },
|
||||||
};
|
};
|
||||||
} else if (isSmScreen) {
|
} else if (isSmScreen) {
|
||||||
return {
|
return {
|
||||||
height: 260,
|
height: 260,
|
||||||
width: 260,
|
width: 260,
|
||||||
innerRadius: 50,
|
innerRadius: 50,
|
||||||
outerRadius: 90,
|
outerRadius: 90,
|
||||||
margin: { left: 40, right: 40, top: 60, bottom: 60 }
|
margin: { left: 40, right: 40, top: 60, bottom: 60 },
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
height: 350,
|
height: 350,
|
||||||
width: 350,
|
width: 350,
|
||||||
innerRadius: 55,
|
innerRadius: 55,
|
||||||
outerRadius: 110,
|
outerRadius: 110,
|
||||||
margin: { left: 60, right: 80, top: 80, bottom: 80 }
|
margin: { left: 60, right: 80, top: 80, bottom: 80 },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const dimensions = getChartDimensions();
|
const dimensions = getChartDimensions();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
sx={{
|
sx={{
|
||||||
|
@ -162,7 +160,6 @@ const dataToDisplay =carPortCounts
|
||||||
legend: { hidden: true },
|
legend: { hidden: true },
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Stack
|
<Stack
|
||||||
spacing={1}
|
spacing={1}
|
||||||
sx={{
|
sx={{
|
||||||
|
@ -170,6 +167,8 @@ const dataToDisplay =carPortCounts
|
||||||
ml: { xs: 0, sm: 2 },
|
ml: { xs: 0, sm: 2 },
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<Typography sx={{whiteSpace: "pre"}}>Car Port Types:</Typography>
|
||||||
|
|
||||||
{dataToDisplay.map((entry, index) => (
|
{dataToDisplay.map((entry, index) => (
|
||||||
<Stack
|
<Stack
|
||||||
key={index}
|
key={index}
|
||||||
|
@ -207,5 +206,5 @@ const dataToDisplay =carPortCounts
|
||||||
</Box>
|
</Box>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import CardAlert from "../CardAlert/CardAlert";
|
||||||
import { AppDispatch, RootState } from "../../redux/store/store";
|
import { AppDispatch, RootState } from "../../redux/store/store";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { fetchAdminProfile } from "../../redux/slices/profileSlice";
|
import { fetchAdminProfile } from "../../redux/slices/profileSlice";
|
||||||
|
import Logout from "../LogOutFunction/LogOutFunction";
|
||||||
|
|
||||||
interface SideMenuMobileProps {
|
interface SideMenuMobileProps {
|
||||||
open: boolean | undefined;
|
open: boolean | undefined;
|
||||||
|
@ -25,6 +26,7 @@ export default function SideMenuMobile({
|
||||||
toggleDrawer,
|
toggleDrawer,
|
||||||
}: SideMenuMobileProps) {
|
}: SideMenuMobileProps) {
|
||||||
const dispatch = useDispatch<AppDispatch>();
|
const dispatch = useDispatch<AppDispatch>();
|
||||||
|
const [logoutModal, setLogoutModal] = React.useState<boolean>(false);
|
||||||
const { user } = useSelector((state: RootState) => state?.profileReducer);
|
const { user } = useSelector((state: RootState) => state?.profileReducer);
|
||||||
// React.useEffect(() => {
|
// React.useEffect(() => {
|
||||||
// dispatch(fetchAdminProfile());
|
// dispatch(fetchAdminProfile());
|
||||||
|
@ -79,9 +81,18 @@ export default function SideMenuMobile({
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
fullWidth
|
fullWidth
|
||||||
startIcon={<LogoutRoundedIcon />}
|
startIcon={<LogoutRoundedIcon />}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
setLogoutModal(true);
|
||||||
|
}}
|
||||||
|
sx={{ color: "red" }}
|
||||||
>
|
>
|
||||||
Logout
|
Logout
|
||||||
</Button>
|
</Button>
|
||||||
|
<Logout
|
||||||
|
setLogoutModal={setLogoutModal}
|
||||||
|
logoutModal={logoutModal}
|
||||||
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
|
|
|
@ -16,9 +16,11 @@ const DashboardLayout: React.FC<LayoutProps> = ({ customStyles }) => {
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
height: "auto",
|
// height: "auto",
|
||||||
flexDirection: { xs: "column", md: "row" },
|
flexDirection: { xs: "column", md: "row" },
|
||||||
width: "100%",
|
width: "100%",
|
||||||
|
height: "100vh", // Full height from root, not auto
|
||||||
|
overflow: "hidden",
|
||||||
margin: 0,
|
margin: 0,
|
||||||
padding: 0,
|
padding: 0,
|
||||||
}}
|
}}
|
||||||
|
@ -43,29 +45,32 @@ const DashboardLayout: React.FC<LayoutProps> = ({ customStyles }) => {
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
height: "100vh",
|
height: "100vh",
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
// backgroundColor: theme.vars
|
|
||||||
// ? `rgba(${theme.vars.palette.background.defaultChannel} / 1)`
|
|
||||||
// : theme.palette.background.default,
|
|
||||||
backgroundColor: theme.palette.background.default,
|
backgroundColor: theme.palette.background.default,
|
||||||
overflow: "auto",
|
overflow: "auto",
|
||||||
|
overflowX: "hidden",
|
||||||
...customStyles,
|
...customStyles,
|
||||||
mt: { xs: 8, md: 0 },
|
mt: { xs: 8, md: 0 },
|
||||||
padding: 0,
|
padding: 0,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
|
<Box sx={{ height: "84px", flex: "0 0 84px" }}>
|
||||||
|
<Header />
|
||||||
|
</Box>
|
||||||
<Stack
|
<Stack
|
||||||
spacing={2}
|
spacing={2}
|
||||||
sx={{
|
sx={{
|
||||||
|
padding: "30px",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyItems: "center",
|
justifyItems: "center",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
mx: 3,
|
// mx: { xs: 1, sm: 3 },
|
||||||
pb: 5,
|
// pb: 5,
|
||||||
mt: { xs: 3, md: 0 },
|
mt: { xs: 3, md: 0 },
|
||||||
|
width: "100%",
|
||||||
|
boxSizing: "border-box",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Header />
|
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</Stack>
|
</Stack>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
@ -22,6 +22,7 @@ import { Visibility, VisibilityOff } from "@mui/icons-material";
|
||||||
import { Card, SignInContainer } from "./styled.css.tsx";
|
import { Card, SignInContainer } from "./styled.css.tsx";
|
||||||
import { CustomIconButton } from "../../../components/AddUserModal/styled.css.tsx";
|
import { CustomIconButton } from "../../../components/AddUserModal/styled.css.tsx";
|
||||||
import { AppDispatch } from "../../../redux/store/store.ts";
|
import { AppDispatch } from "../../../redux/store/store.ts";
|
||||||
|
import { autofillFix } from "../../../shared-theme/customizations/autoFill.tsx";
|
||||||
|
|
||||||
interface ILoginForm {
|
interface ILoginForm {
|
||||||
email: string;
|
email: string;
|
||||||
|
@ -50,14 +51,14 @@ export default function Login(props: { disableCustomTheme?: boolean }) {
|
||||||
};
|
};
|
||||||
|
|
||||||
const togglePasswordVisibility = (e: React.MouseEvent) => {
|
const togglePasswordVisibility = (e: React.MouseEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setShowPassword((prev) => !prev);
|
setShowPassword((prev) => !prev);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSubmit: SubmitHandler<ILoginForm> = async (data: ILoginForm) => {
|
const onSubmit: SubmitHandler<ILoginForm> = async (data: ILoginForm) => {
|
||||||
const isValid = await trigger();
|
const isValid = await trigger();
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const response = await dispatch(loginUser(data)).unwrap();
|
const response = await dispatch(loginUser(data)).unwrap();
|
||||||
|
@ -73,7 +74,6 @@ export default function Login(props: { disableCustomTheme?: boolean }) {
|
||||||
<AppTheme {...props}>
|
<AppTheme {...props}>
|
||||||
<SignInContainer direction="column" justifyContent="space-between">
|
<SignInContainer direction="column" justifyContent="space-between">
|
||||||
<Grid container sx={{ minHeight: "100vh" }}>
|
<Grid container sx={{ minHeight: "100vh" }}>
|
||||||
|
|
||||||
<Grid
|
<Grid
|
||||||
item
|
item
|
||||||
xs={0}
|
xs={0}
|
||||||
|
@ -82,11 +82,10 @@ export default function Login(props: { disableCustomTheme?: boolean }) {
|
||||||
sx={{
|
sx={{
|
||||||
background: `url('/Login.svg') center/cover no-repeat`,
|
background: `url('/Login.svg') center/cover no-repeat`,
|
||||||
backgroundSize: "cover",
|
backgroundSize: "cover",
|
||||||
display: { xs: "none", md: "block" },
|
display: { xs: "none", md: "block" },
|
||||||
position: "relative",
|
position: "relative",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
|
@ -122,7 +121,6 @@ export default function Login(props: { disableCustomTheme?: boolean }) {
|
||||||
position: "relative",
|
position: "relative",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: { xs: "flex", md: "none" },
|
display: { xs: "flex", md: "none" },
|
||||||
|
@ -164,7 +162,12 @@ export default function Login(props: { disableCustomTheme?: boolean }) {
|
||||||
<Card
|
<Card
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
sx={{
|
sx={{
|
||||||
width: { xs: "100%", sm: "90%", md: "90%", lg: "408px" },
|
width: {
|
||||||
|
xs: "100%",
|
||||||
|
sm: "90%",
|
||||||
|
md: "90%",
|
||||||
|
lg: "408px",
|
||||||
|
},
|
||||||
maxWidth: "408px",
|
maxWidth: "408px",
|
||||||
minHeight: { xs: "auto", md: "428px" },
|
minHeight: { xs: "auto", md: "428px" },
|
||||||
padding: { xs: "16px", sm: "20px", md: "24px" },
|
padding: { xs: "16px", sm: "20px", md: "24px" },
|
||||||
|
@ -201,7 +204,7 @@ export default function Login(props: { disableCustomTheme?: boolean }) {
|
||||||
variant="subtitle2"
|
variant="subtitle2"
|
||||||
sx={{
|
sx={{
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
color: "white",
|
color: "#D9D8D8",
|
||||||
fontSize: { xs: "14px", md: "16px" },
|
fontSize: { xs: "14px", md: "16px" },
|
||||||
mb: 1,
|
mb: 1,
|
||||||
}}
|
}}
|
||||||
|
@ -214,12 +217,14 @@ export default function Login(props: { disableCustomTheme?: boolean }) {
|
||||||
<FormLabel
|
<FormLabel
|
||||||
htmlFor="email"
|
htmlFor="email"
|
||||||
sx={{
|
sx={{
|
||||||
|
borderRadius: "8px",
|
||||||
fontSize: {
|
fontSize: {
|
||||||
xs: "0.875rem",
|
xs: "0.875rem",
|
||||||
sm: "1rem",
|
sm: "1rem",
|
||||||
},
|
},
|
||||||
color: "white",
|
color: "white",
|
||||||
mb: 0.5,
|
mb: 0.5,
|
||||||
|
...autofillFix,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Email
|
Email
|
||||||
|
@ -258,7 +263,10 @@ export default function Login(props: { disableCustomTheme?: boolean }) {
|
||||||
}
|
}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
sx: {
|
sx: {
|
||||||
height: { xs: "45px", md: "50px" },
|
height: {
|
||||||
|
xs: "45px",
|
||||||
|
md: "50px",
|
||||||
|
},
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
"#1E1F1F",
|
"#1E1F1F",
|
||||||
|
@ -269,7 +277,7 @@ export default function Login(props: { disableCustomTheme?: boolean }) {
|
||||||
{
|
{
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
"#1E1F1F",
|
"#1E1F1F",
|
||||||
borderRadius: "4px",
|
borderRadius: "8px",
|
||||||
"& fieldset": {
|
"& fieldset": {
|
||||||
borderColor:
|
borderColor:
|
||||||
"#4b5255",
|
"#4b5255",
|
||||||
|
@ -302,6 +310,7 @@ export default function Login(props: { disableCustomTheme?: boolean }) {
|
||||||
fontFamily:
|
fontFamily:
|
||||||
"Gilroy, sans-serif",
|
"Gilroy, sans-serif",
|
||||||
},
|
},
|
||||||
|
...autofillFix,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -313,6 +322,7 @@ export default function Login(props: { disableCustomTheme?: boolean }) {
|
||||||
<FormLabel
|
<FormLabel
|
||||||
htmlFor="password"
|
htmlFor="password"
|
||||||
sx={{
|
sx={{
|
||||||
|
borderRadius: "8px",
|
||||||
fontSize: {
|
fontSize: {
|
||||||
xs: "0.875rem",
|
xs: "0.875rem",
|
||||||
sm: "1rem",
|
sm: "1rem",
|
||||||
|
@ -350,13 +360,13 @@ export default function Login(props: { disableCustomTheme?: boolean }) {
|
||||||
}
|
}
|
||||||
name="password"
|
name="password"
|
||||||
placeholder="Password"
|
placeholder="Password"
|
||||||
|
autoComplete="current-password"
|
||||||
type={
|
type={
|
||||||
showPassword
|
showPassword
|
||||||
? "text"
|
? "text"
|
||||||
: "password"
|
: "password"
|
||||||
}
|
}
|
||||||
id="password"
|
id="password"
|
||||||
autoComplete="current-password"
|
|
||||||
required
|
required
|
||||||
fullWidth
|
fullWidth
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
@ -367,15 +377,20 @@ export default function Login(props: { disableCustomTheme?: boolean }) {
|
||||||
}
|
}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
sx: {
|
sx: {
|
||||||
height: { xs: "45px", md: "50px" },
|
height: {
|
||||||
|
xs: "45px",
|
||||||
|
md: "50px",
|
||||||
|
},
|
||||||
|
...autofillFix,
|
||||||
},
|
},
|
||||||
|
|
||||||
endAdornment: (
|
endAdornment: (
|
||||||
<InputAdornment position="end">
|
<InputAdornment position="end">
|
||||||
<CustomIconButton
|
<CustomIconButton
|
||||||
aria-label="toggle password visibility"
|
aria-label="toggle password visibility"
|
||||||
onClick={
|
onClick={
|
||||||
togglePasswordVisibility
|
togglePasswordVisibility
|
||||||
}
|
} // Only the button triggers visibility toggle
|
||||||
edge="end"
|
edge="end"
|
||||||
>
|
>
|
||||||
{showPassword ? (
|
{showPassword ? (
|
||||||
|
@ -392,7 +407,7 @@ export default function Login(props: { disableCustomTheme?: boolean }) {
|
||||||
{
|
{
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
"#1E1F1F",
|
"#1E1F1F",
|
||||||
borderRadius: "4px",
|
borderRadius: "8px",
|
||||||
"& fieldset": {
|
"& fieldset": {
|
||||||
borderColor:
|
borderColor:
|
||||||
"#4b5255",
|
"#4b5255",
|
||||||
|
@ -468,11 +483,11 @@ export default function Login(props: { disableCustomTheme?: boolean }) {
|
||||||
label={
|
label={
|
||||||
<Typography
|
<Typography
|
||||||
sx={{
|
sx={{
|
||||||
fontSize: {
|
fontSize: {
|
||||||
xs: "0.75rem",
|
xs: "0.75rem",
|
||||||
sm: "0.875rem",
|
sm: "0.875rem",
|
||||||
md: "1rem"
|
md: "1rem",
|
||||||
}
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Remember me
|
Remember me
|
||||||
|
@ -489,21 +504,21 @@ export default function Login(props: { disableCustomTheme?: boolean }) {
|
||||||
alignSelf: "center",
|
alignSelf: "center",
|
||||||
color: "#01579b",
|
color: "#01579b",
|
||||||
textDecoration: "none",
|
textDecoration: "none",
|
||||||
fontSize: {
|
fontSize: {
|
||||||
xs: "0.75rem",
|
xs: "0.75rem",
|
||||||
sm: "0.875rem",
|
sm: "0.875rem",
|
||||||
md: "1rem"
|
md: "1rem",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Forgot password?
|
Forgot password?
|
||||||
</Link>
|
</Link>
|
||||||
</Box>
|
</Box>
|
||||||
<ForgotPassword
|
{/* <ForgotPassword
|
||||||
open={open}
|
open={open}
|
||||||
handleClose={handleClose}
|
handleClose={handleClose}
|
||||||
/>
|
/> */}
|
||||||
|
|
||||||
{/* Login Button */}
|
{/* Login Button */}
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
|
@ -518,7 +533,10 @@ export default function Login(props: { disableCustomTheme?: boolean }) {
|
||||||
},
|
},
|
||||||
padding: { xs: "8px 0", md: "10px 0" },
|
padding: { xs: "8px 0", md: "10px 0" },
|
||||||
mt: { xs: 2, md: 3 },
|
mt: { xs: 2, md: 3 },
|
||||||
fontSize: { xs: "0.875rem", md: "1rem" },
|
fontSize: {
|
||||||
|
xs: "0.875rem",
|
||||||
|
md: "1rem",
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Login
|
Login
|
||||||
|
@ -530,4 +548,4 @@ export default function Login(props: { disableCustomTheme?: boolean }) {
|
||||||
</SignInContainer>
|
</SignInContainer>
|
||||||
</AppTheme>
|
</AppTheme>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,48 +52,40 @@ const ProfilePage = () => {
|
||||||
</Typography>
|
</Typography>
|
||||||
<Card
|
<Card
|
||||||
sx={{
|
sx={{
|
||||||
width: "1132px",
|
borderRadius: 2,
|
||||||
height: "331px",
|
p: { xs: 2, sm: 3 },
|
||||||
gap: "24px",
|
mx: "auto",
|
||||||
borderRadius: "12px",
|
|
||||||
padding: "16px",
|
|
||||||
maxWidth: "100%",
|
|
||||||
margin: "0 auto",
|
|
||||||
backgroundColor: "#1C1C1C",
|
backgroundColor: "#1C1C1C",
|
||||||
}}
|
}}
|
||||||
|
// sx={{
|
||||||
|
// width: "1132px",
|
||||||
|
// height: "331px",
|
||||||
|
// gap: "24px",
|
||||||
|
// borderRadius: "12px",
|
||||||
|
// padding: "16px",
|
||||||
|
// maxWidth: "100%",
|
||||||
|
// margin: "0 auto",
|
||||||
|
// backgroundColor: "#1C1C1C",
|
||||||
|
// }}
|
||||||
>
|
>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<Stack direction="column" spacing={2}>
|
<Stack direction="column" spacing={2}>
|
||||||
<Stack
|
<Stack direction="row" spacing={2} alignItems="center">
|
||||||
direction="row"
|
|
||||||
spacing={1.5}
|
|
||||||
alignItems="center"
|
|
||||||
>
|
|
||||||
<Avatar
|
<Avatar
|
||||||
alt="User Avatar"
|
alt="User Avatar"
|
||||||
src="/avatar.png"
|
src="/avatar.png"
|
||||||
sx={{ width: "60px", height: "60px" }}
|
sx={{ width: 60, height: 60 }}
|
||||||
/>
|
/>
|
||||||
<Box>
|
<Box>
|
||||||
<Typography
|
<Typography
|
||||||
variant="body1"
|
variant="body1"
|
||||||
width="1028px"
|
sx={{ color: "#FFFFFF", fontWeight: 500 }}
|
||||||
height="24px"
|
|
||||||
fontWeight={500}
|
|
||||||
fontSize={"20px"}
|
|
||||||
lineHeight={"100%"}
|
|
||||||
sx={{ color: "#FFFFFF" }}
|
|
||||||
>
|
>
|
||||||
{user?.name || "No Admin"}
|
{user?.name || "No Admin"}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography
|
<Typography
|
||||||
variant="body2"
|
variant="body2"
|
||||||
color="#D9D8D8"
|
sx={{ color: "#D9D8D8" }}
|
||||||
fontWeight={400}
|
|
||||||
fontSize={"16px"}
|
|
||||||
lineHeight={"100%"}
|
|
||||||
width="46px"
|
|
||||||
height="19px"
|
|
||||||
>
|
>
|
||||||
{user?.userType || "N/A"}
|
{user?.userType || "N/A"}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -105,18 +97,13 @@ const ProfilePage = () => {
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Stack
|
<Stack
|
||||||
direction="row"
|
direction={{ xs: "column", sm: "row" }}
|
||||||
justifyContent="space-between"
|
justifyContent="space-between"
|
||||||
alignItems="center"
|
alignItems={{ xs: "flex-start", sm: "center" }}
|
||||||
>
|
>
|
||||||
<Typography
|
<Typography
|
||||||
variant="body1"
|
variant="body1"
|
||||||
width="1048px"
|
sx={{ color: "#FFFFFF", fontWeight: 500 }}
|
||||||
height="19px"
|
|
||||||
fontWeight={500}
|
|
||||||
fontSize={"16px"}
|
|
||||||
lineHeight={"100%"}
|
|
||||||
sx={{ color: "#FFFFFF" }}
|
|
||||||
>
|
>
|
||||||
Personal Information
|
Personal Information
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -129,40 +116,22 @@ const ProfilePage = () => {
|
||||||
</Link> */}
|
</Link> */}
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<Grid
|
<Grid container spacing={3} sx={{ overflowX: "auto" }}>
|
||||||
container
|
<Grid item xs={12} sm={4}>
|
||||||
width="1100px"
|
|
||||||
height="38px"
|
|
||||||
// gap={"100px"}
|
|
||||||
>
|
|
||||||
<Grid
|
|
||||||
item
|
|
||||||
xs={12}
|
|
||||||
sm={4}
|
|
||||||
width="64px"
|
|
||||||
height="16px"
|
|
||||||
fontSize={"14px"}
|
|
||||||
lineHeight={"100%"}
|
|
||||||
>
|
|
||||||
<Typography
|
<Typography
|
||||||
variant="body1"
|
variant="body2"
|
||||||
fontWeight={500}
|
sx={{ color: "#FFFFFF", fontWeight: 500 }}
|
||||||
sx={{ color: "#FFFFFF" }}
|
|
||||||
>
|
>
|
||||||
Full Name:
|
Full Name:
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography
|
<Typography variant="body2" color="#D9D8D8">
|
||||||
variant="body2"
|
|
||||||
fontWeight={400}
|
|
||||||
color="#D9D8D8"
|
|
||||||
>
|
|
||||||
{user?.name || "N/A"}
|
{user?.name || "N/A"}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} sm={4}>
|
<Grid item xs={12} sm={4}>
|
||||||
<Typography
|
<Typography
|
||||||
variant="body1"
|
variant="body2"
|
||||||
sx={{ color: "#FFFFFF" }}
|
sx={{ color: "#FFFFFF", fontWeight: 500 }}
|
||||||
>
|
>
|
||||||
Phone:
|
Phone:
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -172,8 +141,8 @@ const ProfilePage = () => {
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} sm={4}>
|
<Grid item xs={12} sm={4}>
|
||||||
<Typography
|
<Typography
|
||||||
variant="body1"
|
variant="body2"
|
||||||
sx={{ color: "#FFFFFF" }}
|
sx={{ color: "#FFFFFF", fontWeight: 500 }}
|
||||||
>
|
>
|
||||||
Email:
|
Email:
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -181,24 +150,18 @@ const ProfilePage = () => {
|
||||||
{user?.email || "N/A"}
|
{user?.email || "N/A"}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<Grid item xs={12} sm={4}>
|
||||||
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
sx={{ color: "#FFFFFF", fontWeight: 500 }}
|
||||||
|
>
|
||||||
|
Bio:
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body2" color="#D9D8D8">
|
||||||
|
{user?.bio || "No bio available."}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Typography
|
|
||||||
variant="body1"
|
|
||||||
width="21px"
|
|
||||||
height="16px"
|
|
||||||
sx={{ color: "#FFFFFF" }}
|
|
||||||
>
|
|
||||||
Bio:
|
|
||||||
</Typography>
|
|
||||||
<Typography
|
|
||||||
variant="body2"
|
|
||||||
width="1100px"
|
|
||||||
height="32px"
|
|
||||||
color="#D9D8D8"
|
|
||||||
>
|
|
||||||
{user?.bio || "No bio available."}
|
|
||||||
</Typography>
|
|
||||||
</Stack>
|
</Stack>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
|
@ -64,6 +64,7 @@ export const getCarPorts = createAsyncThunk<
|
||||||
const response = await http.get("/get-vehicle-port-dropdown");
|
const response = await http.get("/get-vehicle-port-dropdown");
|
||||||
|
|
||||||
return response.data.data; // Adjust based on actual API response
|
return response.data.data; // Adjust based on actual API response
|
||||||
|
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
return rejectWithValue(
|
return rejectWithValue(
|
||||||
error?.response?.data?.message || "An error occurred"
|
error?.response?.data?.message || "An error occurred"
|
||||||
|
@ -214,4 +215,4 @@ const bookSlice = createSlice({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default bookSlice.reducer;
|
export default bookSlice.reducer;
|
|
@ -1,5 +1,5 @@
|
||||||
import { createSlice, createAsyncThunk, PayloadAction } from "@reduxjs/toolkit";
|
import { createSlice, createAsyncThunk, PayloadAction } from "@reduxjs/toolkit";
|
||||||
import axios from "axios";
|
// import axios from "axios";
|
||||||
import http from "../../lib/https";
|
import http from "../../lib/https";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
|
||||||
|
@ -384,4 +384,4 @@ const stationSlice = createSlice({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default stationSlice.reducer;
|
export default stationSlice.reducer;
|
|
@ -1,5 +1,5 @@
|
||||||
import { createSlice, createAsyncThunk, PayloadAction } from "@reduxjs/toolkit";
|
import { createSlice, createAsyncThunk, PayloadAction } from "@reduxjs/toolkit";
|
||||||
import axios from "axios";
|
// import axios from "axios";
|
||||||
import http from "../../lib/https";
|
import http from "../../lib/https";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,9 @@ const StationList = lazy(() => import("./pages/StationList"));
|
||||||
const EVSlotManagement = lazy(() => import("./pages/EVSlotManagement"));
|
const EVSlotManagement = lazy(() => import("./pages/EVSlotManagement"));
|
||||||
const BookingList = lazy(() => import("./pages/BookingList"));
|
const BookingList = lazy(() => import("./pages/BookingList"));
|
||||||
const EvSlotList = lazy(() => import("./pages/EvSlotList"));
|
const EvSlotList = lazy(() => import("./pages/EvSlotList"));
|
||||||
const ExternalStationList = lazy(() => import("./pages/ExternalStationList/externalStationList.tsx"));
|
const ExternalStationList = lazy(
|
||||||
|
() => import("./pages/ExternalStationList/externalStationList.tsx")
|
||||||
|
);
|
||||||
const AllManagersList = lazy(() => import("./pages/AllMangersList"));
|
const AllManagersList = lazy(() => import("./pages/AllMangersList"));
|
||||||
const AvailableSlotsList = lazy(() => import("./pages/AvailableSlotsList"));
|
const AvailableSlotsList = lazy(() => import("./pages/AvailableSlotsList"));
|
||||||
interface ProtectedRouteProps {
|
interface ProtectedRouteProps {
|
||||||
|
@ -32,7 +34,7 @@ interface ProtectedRouteProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Protected Route Component
|
// Protected Route Component
|
||||||
const ProtectedRoute: React.FC<ProtectedRouteProps> = ({ component }) => {
|
const ProtectedRoute: React.FC<ProtectedRouteProps> = ({ component }) => {
|
||||||
if (!localStorage.getItem("authToken")) {
|
if (!localStorage.getItem("authToken")) {
|
||||||
return <Navigate to="/login" replace />;
|
return <Navigate to="/login" replace />;
|
||||||
}
|
}
|
||||||
|
@ -127,7 +129,9 @@ export default function AppRouter() {
|
||||||
<Route
|
<Route
|
||||||
path="all-available-slots"
|
path="all-available-slots"
|
||||||
element={
|
element={
|
||||||
<ProtectedRoute component={<AvailableSlotsList />} />
|
<ProtectedRoute
|
||||||
|
component={<AvailableSlotsList />}
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</Route>
|
</Route>
|
||||||
|
|
27
src/shared-theme/customizations/autoFill.tsx
Normal file
27
src/shared-theme/customizations/autoFill.tsx
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
export const autofillFix = {
|
||||||
|
"& input:-webkit-autofill": {
|
||||||
|
WebkitBoxShadow: "0 0 0 1000px transparent inset !important",
|
||||||
|
WebkitTextFillColor: "white !important",
|
||||||
|
transition: "background-color 5000s ease-in-out 0s",
|
||||||
|
},
|
||||||
|
"& input:-webkit-autofill:hover": {
|
||||||
|
WebkitBoxShadow: "0 0 0 1000px transparent inset !important",
|
||||||
|
},
|
||||||
|
"& input:-webkit-autofill:focus": {
|
||||||
|
WebkitBoxShadow: "0 0 0 1000px transparent inset !important",
|
||||||
|
},
|
||||||
|
"& input:-webkit-autofill:active": {
|
||||||
|
WebkitBoxShadow: "0 0 0 1000px transparent inset !important",
|
||||||
|
},
|
||||||
|
"& input:-moz-autofill": {
|
||||||
|
boxShadow: "0 0 0 1000px transparent inset !important",
|
||||||
|
MozTextFillColor: "white !important",
|
||||||
|
transition: "background-color 5000s ease-in-out 0s",
|
||||||
|
},
|
||||||
|
"& input:autofill": {
|
||||||
|
boxShadow: "0 0 0 1000px transparent inset !important",
|
||||||
|
textFillColor: "white !important",
|
||||||
|
transition: "background-color 5000s ease-in-out 0s",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
|
@ -8,6 +8,7 @@ import CheckBoxOutlineBlankRoundedIcon from '@mui/icons-material/CheckBoxOutline
|
||||||
import CheckRoundedIcon from '@mui/icons-material/CheckRounded';
|
import CheckRoundedIcon from '@mui/icons-material/CheckRounded';
|
||||||
import RemoveRoundedIcon from '@mui/icons-material/RemoveRounded';
|
import RemoveRoundedIcon from '@mui/icons-material/RemoveRounded';
|
||||||
import { gray, brand } from '../themePrimitives';
|
import { gray, brand } from '../themePrimitives';
|
||||||
|
import {autofillFix} from './autoFill';
|
||||||
|
|
||||||
/* eslint-disable import/prefer-default-export */
|
/* eslint-disable import/prefer-default-export */
|
||||||
export const inputsCustomizations = {
|
export const inputsCustomizations = {
|
||||||
|
@ -379,6 +380,7 @@ export const inputsCustomizations = {
|
||||||
styleOverrides: {
|
styleOverrides: {
|
||||||
input: {
|
input: {
|
||||||
padding: 0,
|
padding: 0,
|
||||||
|
...autofillFix,
|
||||||
},
|
},
|
||||||
root: ({ theme }) => ({
|
root: ({ theme }) => ({
|
||||||
padding: '8px 12px',
|
padding: '8px 12px',
|
||||||
|
|
|
@ -8,6 +8,7 @@ import CheckBoxOutlineBlankRoundedIcon from "@mui/icons-material/CheckBoxOutline
|
||||||
import CheckRoundedIcon from "@mui/icons-material/CheckRounded";
|
import CheckRoundedIcon from "@mui/icons-material/CheckRounded";
|
||||||
import RemoveRoundedIcon from "@mui/icons-material/RemoveRounded";
|
import RemoveRoundedIcon from "@mui/icons-material/RemoveRounded";
|
||||||
import { gray, brand } from "../themePrimitives";
|
import { gray, brand } from "../themePrimitives";
|
||||||
|
import { autofillFix } from "./autoFill";
|
||||||
|
|
||||||
/* eslint-disable import/prefer-default-export */
|
/* eslint-disable import/prefer-default-export */
|
||||||
export const inputsCustomizations: Components<Theme> = {
|
export const inputsCustomizations: Components<Theme> = {
|
||||||
|
@ -393,6 +394,7 @@ export const inputsCustomizations: Components<Theme> = {
|
||||||
styleOverrides: {
|
styleOverrides: {
|
||||||
input: {
|
input: {
|
||||||
padding: 0,
|
padding: 0,
|
||||||
|
...autofillFix,
|
||||||
},
|
},
|
||||||
root: ({ theme }) => ({
|
root: ({ theme }) => ({
|
||||||
padding: "8px 12px",
|
padding: "8px 12px",
|
||||||
|
|
Loading…
Reference in a new issue