dev-jaanvi #1

Open
jaanvi wants to merge 155 commits from dev-jaanvi into main
12 changed files with 977 additions and 605 deletions
Showing only changes of commit 86e0502256 - Show all commits

View file

@ -1,17 +1,20 @@
import React, { useEffect } from "react"; import React, { useEffect, useState } from "react";
import { import {
Box, Box,
Button, Button,
Dialog, Typography,
DialogActions, Modal,
DialogContent, InputAdornment,
DialogTitle,
IconButton,
TextField,
} from "@mui/material"; } from "@mui/material";
import CloseIcon from "@mui/icons-material/Close"; import CloseIcon from "@mui/icons-material/Close";
import Visibility from "@mui/icons-material/Visibility";
import VisibilityOff from "@mui/icons-material/VisibilityOff";
import { useForm, Controller } from "react-hook-form"; import { useForm, Controller } from "react-hook-form";
import { Visibility, VisibilityOff } from "@mui/icons-material"; import {
CustomIconButton,
CustomTextField,
} from "../AddUserModel/styled.css.tsx";
//By Jaanvi : Edit Model :: 11-feb-25 //By Jaanvi : Edit Model :: 11-feb-25
interface AddEditCategoryModalProps { interface AddEditCategoryModalProps {
@ -44,6 +47,7 @@ const AddEditCategoryModal: React.FC<AddEditCategoryModalProps> = ({
handleUpdate, handleUpdate,
editRow, editRow,
}) => { }) => {
const [showPassword, setShowPassword] = React.useState(false);
const { const {
control, control,
handleSubmit, handleSubmit,
@ -59,7 +63,7 @@ const AddEditCategoryModal: React.FC<AddEditCategoryModalProps> = ({
password: "", password: "",
}, },
}); });
const onSubmit = (data: FormData) => { const onSubmit = (data: FormData) => {
if (editRow) { if (editRow) {
handleUpdate( handleUpdate(
@ -77,6 +81,10 @@ const AddEditCategoryModal: React.FC<AddEditCategoryModalProps> = ({
reset(); reset();
}; };
const togglePasswordVisibility = () => {
setShowPassword((prev) => !prev);
};
useEffect(() => { useEffect(() => {
if (editRow) { if (editRow) {
setValue("name", editRow.name); setValue("name", editRow.name);
@ -88,217 +96,327 @@ const AddEditCategoryModal: React.FC<AddEditCategoryModalProps> = ({
} }
}, [editRow, setValue, reset]); }, [editRow, setValue, reset]);
const [showPassword, setShowPassword] = React.useState(false);
return ( return (
<Dialog <Modal
open={open} open={open}
onClose={handleClose} onClose={handleClose}
maxWidth="md" aria-labelledby="add-edit-category-modal"
fullWidth
PaperProps={{
component: "form",
onSubmit: handleSubmit(onSubmit),
}}
> >
<DialogTitle <Box
sx={{ sx={{
display: "flex", position: "absolute",
alignItems: "center", top: "50%",
justifyContent: "space-between", left: "50%",
transform: "translate(-50%, -50%)",
width: 600,
bgcolor: "background.paper",
boxShadow: 24,
p: 3,
borderRadius: 2,
}} }}
> >
{editRow ? "Edit Admin" : "Add Admin"} {/* Header */}
<Box <Box
onClick={handleClose}
sx={{ sx={{
cursor: "pointer",
display: "flex", display: "flex",
justifyContent: "space-between",
alignItems: "center", alignItems: "center",
}} }}
> >
<CloseIcon /> <Typography variant="h6" fontWeight={600}>
{editRow ? "Edit Admin" : "Add Admin"}
</Typography>
<CustomIconButton onClick={handleClose}>
<CloseIcon />
</CustomIconButton>
</Box> </Box>
</DialogTitle>
<DialogContent> {/* Horizontal Line */}
<Controller <Box sx={{ borderBottom: "1px solid #ddd", my: 2 }} />
name="name"
control={control}
rules={{
required: "Admin Name is required",
minLength: {
value: 3,
message: "Minimum 3 characters required",
},
maxLength: {
value: 30,
message: "Maximum 30 characters allowed",
},
}}
render={({ field }) => (
<TextField
{...field}
autoFocus
required
margin="dense"
label="Admin Name"
type="text"
fullWidth
variant="standard"
error={!!errors.name}
helperText={errors.name?.message}
/>
)}
/>
<Controller {/* Form */}
name="email" <form onSubmit={handleSubmit(onSubmit)}>
control={control} {/* Input Fields */}
rules={{ <Box
required: "Email is required", sx={{
pattern: { display: "flex",
value: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/, flexDirection: "column",
message: "Invalid email address", gap: 2,
},
}}
render={({ field }) => (
<TextField
{...field}
required
margin="dense"
label="Email"
type="email"
fullWidth
variant="standard"
error={!!errors.email}
helperText={errors.email?.message}
/>
)}
/>
{!editRow && (
<Controller
name="password"
control={control}
rules={{
required: "password is required",
}} }}
render={({ field }) => ( >
<> {/* First Row - Two Inputs */}
<Box sx={{ display: "flex", gap: 2 }}>
<Box
sx={{
display: "flex",
flexDirection: "column",
width: "50%",
}}
>
<Typography variant="body2" fontWeight={500}>
Admin Name
</Typography>
<Controller
name="name"
control={control}
rules={{
required: "Admin Name is required",
minLength: {
value: 3,
message:
"Minimum 3 characters required",
},
maxLength: {
value: 30,
message:
"Maximum 30 characters allowed",
},
}}
render={({ field }) => (
<CustomTextField
{...field}
required
placeholder="Enter Admin Name"
fullWidth
size="small"
error={!!errors.name}
helperText={errors.name?.message}
/>
)}
/>
</Box>
<Box
sx={{
display: "flex",
flexDirection: "column",
width: "50%",
}}
>
<Typography variant="body2" fontWeight={500}>
Email
</Typography>
<Controller
name="email"
control={control}
rules={{
required: "Email is required",
pattern: {
value: /\S+@\S+\.\S+/,
message:
"Please enter a valid email address.",
},
}}
render={({ field }) => (
<CustomTextField
{...field}
error={!!errors.email}
helperText={errors.email?.message}
id="email"
type="email"
placeholder="Email"
required
fullWidth
color={
errors.email
? "error"
: "primary"
}
/>
)}
/>
</Box>
</Box>
{/* Second Row - Two Inputs */}
<Box sx={{ display: "flex", gap: 2 }}>
{!editRow && (
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",
alignItems: "center", flexDirection: "column",
width: "50%",
}} }}
> >
<TextField <Typography
variant="body2"
fontWeight={500}
>
Password
</Typography>
<Controller
name="password"
control={control}
rules={{
required: "Password is required",
minLength: {
value: 6,
message:
"Password must be at least 6 characters long.",
},
pattern: {
value: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{6,}$/,
message:
"Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character.",
},
}}
render={({ field }) => (
<CustomTextField
{...field}
required
placeholder="Enter Password"
type={
showPassword
? "text"
: "password"
}
id="password"
fullWidth
color={
errors.password
? "error"
: "primary"
}
size="small"
InputProps={{
endAdornment: (
<InputAdornment position="end">
<CustomIconButton
aria-label="toggle password visibility"
onClick={
togglePasswordVisibility
}
edge="end"
>
{showPassword ? (
<VisibilityOff />
) : (
<Visibility />
)}
</CustomIconButton>
</InputAdornment>
),
}}
error={!!errors.password}
helperText={
errors.password?.message
}
/>
)}
/>
</Box>
)}
<Box
sx={{
display: "flex",
flexDirection: "column",
width: "50%",
}}
>
<Typography variant="body2" fontWeight={500}>
Phone Number
</Typography>
<Controller
name="phone"
control={control}
rules={{
required: "Phone number is required",
pattern: {
value: /^[0-9]*$/,
message: "Only numbers are allowed",
},
minLength: {
value: 6,
message:
"Phone number must be at least 6 digits",
},
maxLength: {
value: 14,
message:
"Phone number must be at most 14 digits",
},
}}
render={({ field }) => (
<CustomTextField
{...field}
required
placeholder="Enter Phone Number"
size="small"
error={!!errors.phone}
helperText={errors.phone?.message}
/>
)}
/>
</Box>
</Box>
{/* Third Row - One Input */}
<Box
sx={{
display: "flex",
flexDirection: "column",
width: "50%",
}}
>
<Typography variant="body2" fontWeight={500}>
Address
</Typography>
<Controller
name="registeredAddress"
control={control}
rules={{
required: "Address is required",
maxLength: {
value: 100,
message:
"Address cannot exceed 100 characters",
},
}}
render={({ field }) => (
<CustomTextField
{...field} {...field}
required required
margin="dense" placeholder="Enter Address"
label="Password"
type={
showPassword ? "text" : "password"
}
id="password"
autoComplete="current-password"
autoFocus
fullWidth fullWidth
variant="standard" size="small"
error={!!errors.password} error={!!errors.registeredAddress}
helperText={errors.password?.message} helperText={
/> errors.registeredAddress?.message
<IconButton
sx={{
position: "absolute",
right: "10px",
top: "50%",
transform: "translateY(-50%)", // Center vertically
backgroundColor: "transparent", // Remove background color
border: "none", // Remove any border
boxShadow: "none", // Remove any shadow
padding: 0, // Remove padding to ensure it's fully transparent
}}
onClick={() =>
setShowPassword((prev) => !prev)
} }
> />
{showPassword ? ( )}
<VisibilityOff /> />
) : ( </Box>
<Visibility /> </Box>
)}
</IconButton>
</Box>
</>
)}
/>
)}
<Controller
name="phone"
control={control}
rules={{
required: "Phone number is required",
pattern: {
value: /^[0-9]*$/,
message: "Only numbers are allowed",
},
minLength: {
value: 6,
message: "Phone number must be exactly 6 digits",
},
maxLength: {
value: 14,
message: "Phone number must be exactly 14 digits",
},
}}
render={({ field }) => (
<TextField
{...field}
required
margin="dense"
label="Phone Number"
type="tel"
fullWidth
variant="standard"
error={!!errors.phone}
helperText={errors.phone?.message}
/>
)}
/>
<Controller {/* Submit Button */}
name="registeredAddress" <Box
control={control} sx={{
rules={{ display: "flex",
required: "Address is required", justifyContent: "flex-end",
maxLength: { width: "100%",
value: 100, mt: 3,
message: "Address cannot exceed 100 characters", }}
}, >
}} <Button
render={({ field }) => ( type="submit"
<TextField sx={{
{...field} backgroundColor: "#52ACDF",
required color: "white",
margin="dense" borderRadius: "8px",
label="Address" width: "117px",
type="text" "&:hover": { backgroundColor: "#439BC1" },
fullWidth }}
variant="standard" >
error={!!errors.registeredAddress} {editRow ? "Update Admin" : "Add Admin"}
helperText={errors.registeredAddress?.message} </Button>
/> </Box>
)} </form>
/> </Box>
</DialogContent> </Modal>
<DialogActions>
<Button onClick={handleClose}>Cancel</Button>
<Button type="submit">{editRow ? "Update" : "Create"}</Button>
</DialogActions>
</Dialog>
); );
}; };

View file

@ -1,17 +1,27 @@
import React, { useEffect } from "react"; import React, { useEffect, useState } from "react";
import { import {
Box, Box,
Button, Button,
Dialog, Typography,
DialogActions,
DialogContent,
DialogTitle,
TextField, TextField,
Modal,
IconButton,
InputAdornment,
styled,
} from "@mui/material"; } from "@mui/material";
import CloseIcon from "@mui/icons-material/Close"; import CloseIcon from "@mui/icons-material/Close";
import Visibility from "@mui/icons-material/Visibility";
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";
//By Jaanvi : Edit Model :: 11-feb-25
interface FormData {
name: string;
email: string;
password: string;
phone: string;
}
interface AddUserModalProps { interface AddUserModalProps {
open: boolean; open: boolean;
handleClose: () => void; handleClose: () => void;
@ -20,52 +30,55 @@ interface AddUserModalProps {
id: string, id: string,
name: string, name: string,
email: string, email: string,
password: string,
phone: string, phone: string,
password: string
) => void; ) => void;
editRow: any; editRow: any;
} }
interface FormData {
name: string;
email: string;
phone: string;
password: string;
}
const AddUserModal: React.FC<AddUserModalProps> = ({ const AddUserModal: React.FC<AddUserModalProps> = ({
open, open,
handleClose, handleClose,
handleCreate, handleCreate,
handleUpdate,
editRow, editRow,
}) => { }) => {
const [showPassword, setShowPassword] = useState(false);
const { const {
control, control,
handleSubmit, handleSubmit,
formState: { errors }, formState: { errors },
setValue,
reset, reset,
} = useForm<FormData>({ } = useForm<FormData>({
defaultValues: { defaultValues: {
name: "", name: "",
email: "", email: "",
password: "",
phone: "", phone: "",
password: "",
}, },
}); });
// useEffect(() => {
// if (editRow) {
// setValue("name", editRow.name);
// setValue("email", editRow.email);
// setValue("password", editRow.password);
// setValue("phone", editRow.phone);
// } else {
// reset();
// }
// }, [editRow, setValue, reset]);
const onSubmit = (data: FormData) => { const onSubmit = (data: FormData) => {
if (editRow) { if (editRow) {
handleUpdate( handleUpdate(
editRow.id, editRow.id,
data.name, data.name,
data.email, data.email,
data.phone, data.password,
data.password data.phone
); );
} else { } else {
handleCreate(data); handleCreate(data);
} }
@ -73,156 +86,290 @@ const AddUserModal: React.FC<AddUserModalProps> = ({
reset(); reset();
}; };
const togglePasswordVisibility = () => {
setShowPassword((prev) => !prev);
};
return ( return (
<Dialog <Modal
open={open} open={open}
onClose={handleClose} onClose={handleClose}
maxWidth="md" aria-labelledby="add-user-modal"
fullWidth
PaperProps={{
component: "form",
onSubmit: handleSubmit(onSubmit),
}}
> >
<DialogTitle <Box
sx={{ sx={{
display: "flex", position: "absolute",
alignItems: "center", top: "50%",
justifyContent: "space-between", left: "50%",
transform: "translate(-50%, -50%)",
width: 600, // Adjusted the width for a wider modal
bgcolor: "background.paper",
boxShadow: 24,
p: 3,
borderRadius: 2,
}} }}
> >
{editRow ? "Edit User" : "Add User"} {/* Header */}
<Box <Box
onClick={handleClose}
sx={{ sx={{
cursor: "pointer",
display: "flex", display: "flex",
justifyContent: "space-between",
alignItems: "center", alignItems: "center",
}} }}
> >
<CloseIcon /> <Typography variant="h6" fontWeight={600}>
{editRow ? "Edit User" : "Add User"}
</Typography>
<CustomIconButton onClick={handleClose}>
<CloseIcon />
</CustomIconButton>
</Box> </Box>
</DialogTitle>
<DialogContent> {/* Horizontal Line */}
<Controller <Box sx={{ borderBottom: "1px solid #ddd", my: 2 }} />
name="name"
control={control}
rules={{
required: "Admin Name is required",
minLength: {
value: 3,
message: "Minimum 3 characters required",
},
maxLength: {
value: 30,
message: "Maximum 30 characters allowed",
},
}}
render={({ field }) => (
<TextField
{...field}
autoFocus
required
margin="dense"
label="User Name"
type="text"
fullWidth
variant="standard"
error={!!errors.name}
helperText={errors.name?.message}
/>
)}
/>
<Controller {/* Form */}
name="email" <form onSubmit={handleSubmit(onSubmit)}>
control={control} {/* Input Fields */}
rules={{ <Box
required: "Email is required", sx={{
pattern: { display: "flex",
value: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/, flexDirection: "column",
message: "Invalid email address", gap: 2,
}, }}
}} >
render={({ field }) => ( {/* First Row - Two Inputs */}
<TextField <Box sx={{ display: "flex", gap: 2 }}>
{...field} <Box
required sx={{
margin="dense" display: "flex",
label="Email" flexDirection: "column",
type="email" width: "100%",
fullWidth }}
variant="standard" >
error={!!errors.email} <Typography variant="body2" fontWeight={500}>
helperText={errors.email?.message} User Name
/> </Typography>
)} <Controller
/> name="name"
<Controller control={control}
name="password" rules={{
control={control} required: "User Name is required",
rules={{ minLength: {
required: "password is required", value: 3,
}} message:
render={({ field }) => ( "Minimum 3 characters required",
<TextField },
{...field} maxLength: {
required value: 30,
margin="dense" message:
label="Password" "Maximum 30 characters allowed",
type="password" },
fullWidth }}
variant="standard" render={({ field }) => (
error={!!errors.password} <CustomTextField
helperText={errors.password?.message} {...field}
/> required
)} placeholder="Enter User Name"
/> fullWidth
<Controller size="small"
name="phone" error={!!errors.name}
control={control} helperText={errors.name?.message}
rules={{ />
required: "Phone number is required", )}
pattern: { />
value: /^[0-9]*$/, </Box>
message: "Only numbers are allowed",
},
minLength: {
value: 6,
message: "Phone number must be exactly 6 digits",
},
maxLength: {
value: 14,
message: "Phone number must be exactly 14 digits",
},
}}
render={({ field }) => (
<TextField
{...field}
required
margin="dense"
label="Phone Number"
type="tel"
fullWidth
variant="standard"
error={!!errors.phone}
helperText={errors.phone?.message}
/>
)}
/>
</DialogContent>
<DialogActions> <Box
<Button onClick={handleClose}>Cancel</Button> sx={{
<Button type="submit">Create</Button> display: "flex",
</DialogActions> flexDirection: "column",
</Dialog> width: "100%",
}}
>
<Typography variant="body2" fontWeight={500}>
Email
</Typography>
<Controller
name="email"
control={control}
rules={{
required: "Email is required",
pattern: {
value: /\S+@\S+\.\S+/,
message:
"Please enter a valid email address.",
},
}}
render={({ field }) => (
<CustomTextField
{...field}
error={!!errors.email}
helperText={errors.email?.message}
id="email"
type="email"
placeholder="Email"
required
fullWidth
color={
errors.email
? "error"
: "primary"
}
/>
)}
/>
</Box>
</Box>
{/* Second Row - Two Inputs */}
<Box sx={{ display: "flex", gap: 2 }}>
<Box
sx={{
display: "flex",
flexDirection: "column",
width: "100%",
}}
>
<Typography variant="body2" fontWeight={500}>
Password
</Typography>
<Controller
name="password"
control={control}
rules={{
required: "Password is required",
minLength: {
value: 6,
message:
"Password must be at least 6 characters long.",
},
pattern: {
value: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{6,}$/,
message:
"Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character.",
},
}}
render={({ field }) => (
<CustomTextField
{...field}
required
placeholder="Enter Password"
type={
showPassword
? "text"
: "password"
}
id="password"
fullWidth
color={
errors.password
? "error"
: "primary"
}
size="small"
InputProps={{
endAdornment: (
<InputAdornment position="end">
<CustomIconButton
aria-label="toggle password visibility"
onClick={
togglePasswordVisibility
}
edge="end"
>
{showPassword ? (
<VisibilityOff />
) : (
<Visibility />
)}
</CustomIconButton>
</InputAdornment>
),
}}
error={!!errors.password}
helperText={
errors.password?.message
}
/>
)}
/>
</Box>
<Box
sx={{
display: "flex",
flexDirection: "column",
width: "100%",
}}
>
<Typography variant="body2" fontWeight={500}>
Phone Number
</Typography>
<Controller
name="phone"
control={control}
rules={{
required: "Phone number is required",
pattern: {
value: /^[0-9]*$/,
message: "Only numbers are allowed",
},
minLength: {
value: 6,
message:
"Phone number must be at least 6 digits",
},
maxLength: {
value: 14,
message:
"Phone number must be at most 14 digits",
},
}}
render={({ field }) => (
<CustomTextField
{...field}
required
placeholder="Enter Phone Number"
size="small"
error={!!errors.phone}
helperText={errors.phone?.message}
/>
)}
/>
</Box>
</Box>
</Box>
{/* Submit Button */}
<Box
sx={{
display: "flex",
justifyContent: "flex-end",
width: "100%",
mt: 3,
}}
>
<Button
type="submit"
sx={{
backgroundColor: "#52ACDF",
color: "white",
borderRadius: "8px",
width: "117px",
"&:hover": { backgroundColor: "#439BC1" },
}}
>
{editRow ? "Update User" : "Add User"}
</Button>
</Box>
</form>
</Box>
</Modal>
); );
}; };
export default AddUserModal; export default AddUserModal;
function handleUpdate(id: any, name: string, email: string, phone: string, password: string) { function setValue(arg0: string, name: any) {
throw new Error("Function not implemented."); throw new Error("Function not implemented.");
} }

View file

@ -0,0 +1,26 @@
import { styled } from "@mui/material/styles";
import { IconButton, TextField } from "@mui/material";
export const CustomIconButton = styled(IconButton)({
backgroundColor: "transparent",
"&:hover": {
backgroundColor: "#272727",
},
"*:where([data-mui-color-scheme='dark']) &": {
backgroundColor: "transparent",
border: "none",
},
});
// Custom TextField with different placeholder color
export const CustomTextField = styled(TextField)({
"& .MuiInputBase-input::placeholder": {
color: "#D9D8D8",
opacity: 1,
},
"& .MuiInputBase-root.Mui-focused .MuiInputBase-input::placeholder": {
color: "darkgray",
},
});

View file

@ -1,42 +1,28 @@
import { useState } from "react"; import { useForm } from "react-hook-form";
import { import {
Box, Box,
Button, Button,
Typography, Typography,
TextField,
Modal, Modal,
IconButton,
} from "@mui/material"; } from "@mui/material";
import CloseIcon from "@mui/icons-material/Close"; import CloseIcon from "@mui/icons-material/Close";
import { CustomIconButton, CustomTextField } from "../AddUserModel/styled.css.tsx";
export default function AddVehicleModal({ export default function AddVehicleModal({
open, open,
handleClose, handleClose,
handleAddVehicle, handleAddVehicle,
}) { }) {
// State for input fields const {
const [name, setName] = useState(""); register,
const [company, setCompany] = useState(""); handleSubmit,
const [modelName, setModelName] = useState(""); formState: { errors },
const [chargeType, setChargeType] = useState(""); reset,
const [imageUrl, setImageUrl] = useState(""); } = useForm();
const handleSubmit = () => { const onSubmit = (data: any) => {
if (!name || !company || !modelName || !chargeType || !imageUrl) { handleAddVehicle(data); // Add vehicle to table
alert("Please fill all fields");
return;
}
const newVehicle = {
name,
company,
modelName,
chargeType,
imageUrl,
};
handleAddVehicle(newVehicle); // Add vehicle to table
handleClose(); // Close modal after adding handleClose(); // Close modal after adding
reset();
}; };
return ( return (
@ -69,127 +55,197 @@ export default function AddVehicleModal({
<Typography variant="h6" fontWeight={600}> <Typography variant="h6" fontWeight={600}>
Add Vehicle Add Vehicle
</Typography> </Typography>
<IconButton onClick={handleClose}> <CustomIconButton onClick={handleClose}>
<CloseIcon /> <CloseIcon />
</IconButton> </CustomIconButton>
</Box> </Box>
{/* Horizontal Line */} {/* Horizontal Line */}
<Box sx={{ borderBottom: "1px solid #ddd", my: 2 }} /> <Box sx={{ borderBottom: "1px solid #ddd", my: 2 }} />
{/* Input Fields */} {/* Form */}
<Box sx={{ display: "flex", flexDirection: "column", gap: 2 }}> <form onSubmit={handleSubmit(onSubmit)}>
{/* First Row - Two Inputs */} {/* Input Fields */}
<Box sx={{ display: "flex", gap: 2 }}>
<Box
sx={{
display: "flex",
flexDirection: "column",
width: "100%",
}}
>
<Typography variant="body2" fontWeight={500}>
Vehicle Name
</Typography>
<TextField
fullWidth
placeholder="Enter Vehicle Name"
size="small"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</Box>
<Box
sx={{
display: "flex",
flexDirection: "column",
width: "100%",
}}
>
<Typography variant="body2" fontWeight={500}>
Company
</Typography>
<TextField
fullWidth
placeholder="Enter Company Name"
size="small"
value={company}
onChange={(e) => setCompany(e.target.value)}
/>
</Box>
</Box>
{/* Second Row - Two Inputs */}
<Box sx={{ display: "flex", gap: 2 }}>
<Box
sx={{
display: "flex",
flexDirection: "column",
width: "100%",
}}
>
<Typography variant="body2" fontWeight={500}>
Model Name
</Typography>
<TextField
fullWidth
placeholder="Enter Model Name"
size="small"
value={modelName}
onChange={(e) => setModelName(e.target.value)}
/>
</Box>
<Box
sx={{
display: "flex",
flexDirection: "column",
width: "100%",
}}
>
<Typography variant="body2" fontWeight={500}>
Charge Type
</Typography>
<TextField
fullWidth
placeholder="Enter Charge Type"
size="small"
value={chargeType}
onChange={(e) => setChargeType(e.target.value)}
/>
</Box>
</Box>
{/* Third Row - Image URL */}
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
width: "100%", gap: 2,
}} }}
> >
<Typography variant="body2" fontWeight={500}> {/* First Row - Two Inputs */}
Image URL <Box sx={{ display: "flex", gap: 2 }}>
</Typography> <Box
<TextField sx={{
fullWidth display: "flex",
placeholder="Enter Image URL" flexDirection: "column",
size="small" width: "100%",
value={imageUrl} }}
onChange={(e) => setImageUrl(e.target.value)} >
/> <Typography variant="body2" fontWeight={500}>
</Box> Vehicle Name
</Box> </Typography>
<CustomTextField
fullWidth
placeholder="Enter Vehicle Name"
size="small"
error={!!errors.name}
helperText={
errors.name ? errors.name.message : ""
}
{...register("name", {
required: "Vehicle Name is required",
minLength: {
value: 2,
message:
"Vehicle Name must be at least 2 characters long",
},
})}
/>
</Box>
{/* Submit Button */} <Box
<Box sx={{
sx={{ display: "flex", justifyContent: "flex-end", mt: 3 }} display: "flex",
> flexDirection: "column",
<Button variant="contained" onClick={handleSubmit}> width: "100%",
Add Vehicle }}
</Button> >
</Box> <Typography variant="body2" fontWeight={500}>
Company
</Typography>
<CustomTextField
fullWidth
placeholder="Enter Company Name"
size="small"
error={!!errors.company}
helperText={
errors.company
? errors.company.message
: ""
}
{...register("company", {
required: "Company is required",
minLength: {
value: 5,
message:
"Company must be at least 5 characters long",
},
})}
/>
</Box>
</Box>
{/* Second Row - Two Inputs */}
<Box sx={{ display: "flex", gap: 2 }}>
<Box
sx={{
display: "flex",
flexDirection: "column",
width: "100%",
}}
>
<Typography variant="body2" fontWeight={500}>
Model Name
</Typography>
<CustomTextField
fullWidth
placeholder="Enter Model Name"
size="small"
error={!!errors.modelName}
helperText={
errors.modelName
? errors.modelName.message
: ""
}
{...register("modelName", {
required: "Model Name is required",
})}
/>
</Box>
<Box
sx={{
display: "flex",
flexDirection: "column",
width: "100%",
}}
>
<Typography variant="body2" fontWeight={500}>
Charge Type
</Typography>
<CustomTextField
fullWidth
placeholder="Enter Charge Type"
size="small"
error={!!errors.chargeType}
helperText={
errors.chargeType
? errors.chargeType.message
: ""
}
{...register("chargeType", {
required: "Charge Type is required",
})}
/>
</Box>
</Box>
{/* Third Row - Image URL */}
<Box
sx={{
display: "flex",
flexDirection: "column",
width: "100%",
}}
>
<Typography variant="body2" fontWeight={500}>
Image URL
</Typography>
<CustomTextField
fullWidth
placeholder="Enter Image URL"
size="small"
error={!!errors.imageUrl}
helperText={
errors.imageUrl
? errors.imageUrl.message
: ""
}
{...register("imageUrl", {
required: "Image URL is required",
pattern: {
value: /^(https?:\/\/)?((([a-zA-Z\d]([a-zA-Z\d-]*[a-zA-Z\d])*)\.)+[a-zA-Z]{2,}|((\d{1,3}\.){3}\d{1,3}))(:\d+)?(\/[-a-zA-Z\d%_.~+]*)*(\?[;&a-zA-Z\d%_.~+=-]*)?(#[-a-zA-Z\d_]*)?$/,
message: "Please enter a valid URL",
},
})}
/>
</Box>
</Box>
{/* Submit Button */}
<Box
sx={{
display: "flex",
justifyContent: "flex-end",
mt: 3,
}}
>
<Button
type="submit"
sx={{
backgroundColor: "#52ACDF",
color: "white",
borderRadius: "8px",
width: "117px",
"&:hover": { backgroundColor: "#439BC1" },
}}
>
Add Vehicle
</Button>
</Box>
</form>
</Box> </Box>
</Modal> </Modal>
); );

View file

@ -15,9 +15,9 @@ import { useDispatch } from "react-redux";
import { import {
Box, Box,
Button, Button,
IconButton,
InputAdornment, InputAdornment,
Menu, Menu,
IconButton,
Pagination, Pagination,
TextField, TextField,
Typography, Typography,
@ -30,7 +30,9 @@ import VehicleViewModal from "../Modals/VehicleViewModal";
import SearchIcon from "@mui/icons-material/Search"; import SearchIcon from "@mui/icons-material/Search";
import TuneIcon from "@mui/icons-material/Tune"; import TuneIcon from "@mui/icons-material/Tune";
import {
CustomIconButton,
} from "../AddUserModel/styled.css.tsx";
// Styled components for customization // Styled components for customization
const StyledTableCell = styled(TableCell)(({ theme }) => ({ const StyledTableCell = styled(TableCell)(({ theme }) => ({
[`&.${tableCellClasses.head}`]: { [`&.${tableCellClasses.head}`]: {
@ -248,11 +250,15 @@ const filteredRows = rows.filter(
borderColor: "#52ACDF", borderColor: "#52ACDF",
}, },
}, },
"& .MuiInputBase-input::placeholder": {
color: "#D9D8D8",
opacity: 1,
},
}} }}
InputProps={{ InputProps={{
startAdornment: ( startAdornment: (
<InputAdornment position="start"> <InputAdornment position="start">
<SearchIcon sx={{ color: "#272727" }} /> <SearchIcon sx={{ color: "#52ACDF" }} />
</InputAdornment> </InputAdornment>
), ),
}} }}
@ -361,7 +367,7 @@ const filteredRows = rows.filter(
) : column.id !== "action" ? ( ) : column.id !== "action" ? (
row[column.id] row[column.id]
) : ( ) : (
<IconButton <CustomIconButton
onClick={(e) => { onClick={(e) => {
handleClick(e, row); handleClick(e, row);
setRowData(row); // Store the selected row setRowData(row); // Store the selected row
@ -371,20 +377,13 @@ const filteredRows = rows.filter(
minWidth: 0, minWidth: 0,
width: "auto", width: "auto",
height: "auto", height: "auto",
backgroundColor:
"transparent",
color: "#FFFFFF", color: "#FFFFFF",
border: "none",
"&:hover": {
backgroundColor:
"transparent",
},
}} }}
> >
<MoreHorizRoundedIcon <MoreHorizRoundedIcon
sx={{ fontSize: "24px" }} sx={{ fontSize: "24px" }}
/> />
</IconButton> </CustomIconButton>
)} )}
</StyledTableCell> </StyledTableCell>
))} ))}
@ -442,6 +441,9 @@ const filteredRows = rows.filter(
[`& .${paperClasses.root}`]: { [`& .${paperClasses.root}`]: {
padding: 0, padding: 0,
}, },
"& .MuiList-root": {
background: "#272727", // Remove any divider under menu items
},
}} }}
> >
<Box <Box
@ -531,7 +533,7 @@ const filteredRows = rows.filter(
justifyContent: "flex-start", justifyContent: "flex-start",
py: 0, py: 0,
fontWeight: "bold", fontWeight: "bold",
color: "red",
}} }}
> >
Delete Delete

View file

@ -3,14 +3,15 @@ import {
Box, Box,
Button, Button,
Typography, Typography,
TextField,
Modal, Modal,
IconButton,
} from "@mui/material"; } from "@mui/material";
import CloseIcon from "@mui/icons-material/Close"; import CloseIcon from "@mui/icons-material/Close";
import { useForm, Controller } from "react-hook-form"; import { useForm, Controller } from "react-hook-form";
import { updateVehicle } from "../../redux/slices/VehicleSlice"; import { updateVehicle } from "../../redux/slices/VehicleSlice";
import {
CustomIconButton,
CustomTextField,
} from "../AddUserModel/styled.css.tsx";
interface EditVehicleModalProps { interface EditVehicleModalProps {
open: boolean; open: boolean;
handleClose: () => void; handleClose: () => void;
@ -115,9 +116,9 @@ const EditVehicleModal: React.FC<EditVehicleModalProps> = ({
<Typography variant="h6" fontWeight={600}> <Typography variant="h6" fontWeight={600}>
Edit Vehicle Edit Vehicle
</Typography> </Typography>
<IconButton onClick={handleClose}> <CustomIconButton onClick={handleClose}>
<CloseIcon /> <CloseIcon />
</IconButton> </CustomIconButton>
</Box> </Box>
{/* Horizontal Line */} {/* Horizontal Line */}
@ -146,7 +147,7 @@ const EditVehicleModal: React.FC<EditVehicleModalProps> = ({
control={control} control={control}
rules={{ required: "Vehicle Name is required" }} rules={{ required: "Vehicle Name is required" }}
render={({ field }) => ( render={({ field }) => (
<TextField <CustomTextField
{...field} {...field}
fullWidth fullWidth
placeholder="Enter Vehicle Name" placeholder="Enter Vehicle Name"
@ -177,7 +178,7 @@ const EditVehicleModal: React.FC<EditVehicleModalProps> = ({
control={control} control={control}
rules={{ required: "Company is required" }} rules={{ required: "Company is required" }}
render={({ field }) => ( render={({ field }) => (
<TextField <CustomTextField
{...field} {...field}
fullWidth fullWidth
placeholder="Enter Company Name" placeholder="Enter Company Name"
@ -211,7 +212,7 @@ const EditVehicleModal: React.FC<EditVehicleModalProps> = ({
control={control} control={control}
rules={{ required: "Model Name is required" }} rules={{ required: "Model Name is required" }}
render={({ field }) => ( render={({ field }) => (
<TextField <CustomTextField
{...field} {...field}
fullWidth fullWidth
placeholder="Enter Model Name" placeholder="Enter Model Name"
@ -242,7 +243,7 @@ const EditVehicleModal: React.FC<EditVehicleModalProps> = ({
control={control} control={control}
rules={{ required: "Charge Type is required" }} rules={{ required: "Charge Type is required" }}
render={({ field }) => ( render={({ field }) => (
<TextField <CustomTextField
{...field} {...field}
fullWidth fullWidth
placeholder="Enter Charge Type" placeholder="Enter Charge Type"
@ -271,7 +272,7 @@ const EditVehicleModal: React.FC<EditVehicleModalProps> = ({
control={control} control={control}
rules={{ required: "Image URL is required" }} rules={{ required: "Image URL is required" }}
render={({ field }) => ( render={({ field }) => (
<TextField <CustomTextField
{...field} {...field}
fullWidth fullWidth
placeholder="Enter Image URL" placeholder="Enter Image URL"
@ -288,7 +289,16 @@ const EditVehicleModal: React.FC<EditVehicleModalProps> = ({
<Box <Box
sx={{ display: "flex", justifyContent: "flex-end", mt: 3 }} sx={{ display: "flex", justifyContent: "flex-end", mt: 3 }}
> >
<Button variant="contained" type="submit"> <Button
type="submit"
sx={{
backgroundColor: "#52ACDF",
color: "white",
borderRadius: "8px",
width: "117px",
"&:hover": { backgroundColor: "#439BC1" },
}}
>
Update Vehicle Update Vehicle
</Button> </Button>
</Box> </Box>

View file

@ -1,18 +1,15 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { Box, Modal, Typography, Divider } from "@mui/material"; import { Box, Modal, Typography, Divider, Grid } from "@mui/material";
import CloseIcon from "@mui/icons-material/Close"; import CloseIcon from "@mui/icons-material/Close";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { RootState } from "../../../redux/reducers"; import { RootState } from "../../../redux/reducers";
type Props = { type Props = {
open: boolean; open: boolean;
setViewModal: Function; setViewModal: Function;
handleView: (id: string | undefined) => void; handleView: (id: string | undefined) => void;
id?: number | undefined; id?: number | undefined;
}; };
;
const style = { const style = {
position: "absolute", position: "absolute",
@ -30,13 +27,10 @@ const style = {
gap: 2, gap: 2,
}; };
export default function VehicleViewModal({ export default function VehicleViewModal({ open, setViewModal, id }: Props) {
open, const { vehicles } = useSelector(
setViewModal, (state: RootState) => state.vehicleReducer
id, );
}: Props) {
const { vehicles } = useSelector((state: RootState) => state.vehicleReducer);
const [selectedVehicle, setSelectedVehicle] = useState<any>(null); const [selectedVehicle, setSelectedVehicle] = useState<any>(null);
useEffect(() => { useEffect(() => {
@ -86,37 +80,37 @@ const { vehicles } = useSelector((state: RootState) => state.vehicleReducer);
<Divider sx={{ width: "100%" }} /> <Divider sx={{ width: "100%" }} />
{selectedVehicle ? ( {selectedVehicle ? (
<Box <Grid container spacing={2} sx={{ width: "80%" }}>
sx={{ <Grid item xs={6}>
width: "80%", <Typography variant="body1">
textAlign: "left", <strong>Name:</strong> {selectedVehicle.name}
display: "flex", </Typography>
flexDirection: "column", </Grid>
gap: 1.5, <Grid item xs={6}>
whiteSpace: "pre-wrap", <Typography variant="body1">
wordBreak: "break-word", <strong>Company:</strong>{" "}
overflowWrap: "break-word", {selectedVehicle.company}
}} </Typography>
> </Grid>
<Typography variant="body1"> <Grid item xs={6}>
<strong>Name:</strong> {selectedVehicle.name} <Typography variant="body1">
</Typography> <strong>Model Name:</strong>{" "}
<Typography variant="body1"> {selectedVehicle.modelName}
<strong>Company:</strong> {selectedVehicle.company} </Typography>
</Typography> </Grid>
<Typography variant="body1"> <Grid item xs={6}>
<strong>Model Name:</strong>{" "} <Typography variant="body1">
{selectedVehicle.modelName} <strong>Charge Type:</strong>{" "}
</Typography> {selectedVehicle.chargeType}
<Typography variant="body1"> </Typography>
<strong>Charge Type:</strong>{" "} </Grid>
{selectedVehicle.chargeType} <Grid item xs={6}>
</Typography> <Typography variant="body1">
<Typography variant="body1"> <strong>Image URL:</strong>{" "}
<strong>Image URL:</strong>{" "} {selectedVehicle.imageUrl}
{selectedVehicle.imageUrl} </Typography>
</Typography> </Grid>
</Box> </Grid>
) : ( ) : (
<Typography align="center"> <Typography align="center">
No vehicle found with this ID No vehicle found with this ID

View file

@ -1,4 +1,4 @@
import { Box, Button, Modal, Typography, Divider } from "@mui/material"; import { Box, Button, Modal, Typography, Divider, Grid } from "@mui/material";
import { RootState } from "../../../redux/store/store"; import { RootState } from "../../../redux/store/store";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
@ -10,12 +10,14 @@ type Props = {
id?: string; id?: string;
}; };
const style = { const mainContainerStyle = {
position: "absolute", position: "absolute",
top: "50%", top: "50%",
left: "50%", left: "50%",
transform: "translate(-50%, -50%)", transform: "translate(-50%, -50%)",
width: 400, // width: "544px",
// height: "190px",
gap: "8px",
bgcolor: "background.paper", bgcolor: "background.paper",
borderRadius: 2, borderRadius: 2,
boxShadow: "0px 4px 20px rgba(0, 0, 0, 0.15)", boxShadow: "0px 4px 20px rgba(0, 0, 0, 0.15)",
@ -23,15 +25,16 @@ const style = {
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
alignItems: "center", alignItems: "center",
gap: 2,
}; };
const btnStyle = { const headerLayoutStyle = {
mt: 2, // width: 544,
px: 5, // height: 48,
py: 1.2, gap: "24px",
width: "100%", paddingBottom: "12px",
textTransform: "capitalize", display: "flex",
alignItems: "center",
justifyContent: "space-between",
}; };
export default function ViewModal({ open, setViewModal, id }: Props) { export default function ViewModal({ open, setViewModal, id }: Props) {
@ -51,75 +54,79 @@ export default function ViewModal({ open, setViewModal, id }: Props) {
aria-labelledby="modal-title" aria-labelledby="modal-title"
aria-describedby="modal-description" aria-describedby="modal-description"
> >
<Box sx={style}> <Box sx={mainContainerStyle}>
<Typography <Box sx={headerLayoutStyle}>
id="modal-title" <Typography
variant="h5" id="modal-title"
fontWeight="bold" variant="h5"
sx={{ width: "100%" }} fontWeight="bold"
> sx={{ flex: 1, textAlign: "center" }}
>
{selectedAdmin?.name}'s Details
</Typography>
<Box <Box
onClick={() => setViewModal(false)}
sx={{ sx={{
cursor: "pointer",
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
justifyContent: "space-between", marginLeft: "auto", // Ensures the button is at the right end
width: "100%", justifyContent:"flex-end"
}} }}
> >
<Box sx={{ flex: 1, textAlign: "center" }}> <CloseIcon />
{selectedAdmin?.name}'s Details
</Box>
<Box
onClick={() => setViewModal(false)}
sx={{
cursor: "pointer",
display: "flex",
alignItems: "center",
}}
>
<CloseIcon />
</Box>
</Box> </Box>
</Typography> </Box>
<Divider sx={{ width: "100%" }} /> <Divider sx={{ width: "100%" }} />
{selectedAdmin ? ( {selectedAdmin ? (
<Box <Box
sx={{ sx={{
width: "80%", width: "100%",
textAlign: "left", textAlign: "left",
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
gap: 1.5, gap: 1.5,
whiteSpace: "pre-wrap", // the text wraps properly whiteSpace: "pre-wrap",
wordBreak: "break-word", wordBreak: "break-word",
overflowWrap: "break-word", overflowWrap: "break-word",
}} }}
> >
<Typography variant="body1"> <Grid container spacing={2}>
<b>Name:</b> {selectedAdmin.name} <Grid item xs={6}>
</Typography> <Typography>
<Typography variant="body1"> <b>Name:</b>
<strong>Email:</strong> {selectedAdmin.email} </Typography>
</Typography> <Typography>{selectedAdmin.name}</Typography>
<Typography variant="body1"> </Grid>
<strong>Phone:</strong> {selectedAdmin.phone} <Grid item xs={6}>
</Typography> <Typography>
<Typography variant="body1"> <b>Phone:</b>
<strong>Address:</strong>{" "} </Typography>
{selectedAdmin.registeredAddress ?? "N/A"} <Typography>{selectedAdmin.phone}</Typography>
</Typography> </Grid>
<Grid item xs={6}>
<Typography>
<b>Email:</b>
</Typography>
<Typography>{selectedAdmin.email}</Typography>
</Grid>
<Grid item xs={6}>
<Typography>
<b>Address:</b>
</Typography>
<Typography>
{selectedAdmin.registeredAddress ?? "N/A"}
</Typography>
</Grid>
</Grid>
</Box> </Box>
) : ( ) : (
<Typography align="center"> <Typography align="center">
No admin found with this ID No admin found with this ID
</Typography> </Typography>
)} )}
{/* <Button variant="contained" color="error" sx={btnStyle} onClick={() => setViewModal(false)}>
Close
</Button> */}
</Box> </Box>
</Modal> </Modal>
); );

View file

@ -25,7 +25,7 @@ export default function OptionsMenu({ avatar }: { avatar?: boolean }) {
return ( return (
<React.Fragment> <React.Fragment>
<ExpandMoreIcon onClick={handleClick} sx={{cursor:"pointer"}}/> <ExpandMoreIcon onClick={handleClick} sx={{ cursor: "pointer" }} />
<Menu <Menu
anchorEl={anchorEl} anchorEl={anchorEl}
id="top-menu" id="top-menu"
@ -39,6 +39,10 @@ export default function OptionsMenu({ avatar }: { avatar?: boolean }) {
overflow: "visible", overflow: "visible",
filter: "drop-shadow(0px 2px 8px rgba(0,0,0,0.32))", filter: "drop-shadow(0px 2px 8px rgba(0,0,0,0.32))",
mt: 1.5, mt: 1.5,
"& .MuiList-root": {
background: "#272727", // Remove any divider under menu items
},
"& .MuiMenuItem-root": { "& .MuiMenuItem-root": {
borderBottom: "none", // Remove any divider under menu items borderBottom: "none", // Remove any divider under menu items
}, },

View file

@ -11,9 +11,8 @@ import {
Typography, Typography,
Box, Box,
Grid, Grid,
FormControlLabel,
Button, Button,
TextField, FormControlLabel,
Snackbar, Snackbar,
} from "@mui/material"; } from "@mui/material";
import { useNavigate } from "react-router-dom"; // Import useNavigate import { useNavigate } from "react-router-dom"; // Import useNavigate
@ -21,6 +20,9 @@ import { useDispatch, useSelector } from "react-redux";
import { createRole } from "../../redux/slices/roleSlice"; // Import the createRole action import { createRole } from "../../redux/slices/roleSlice"; // Import the createRole action
import { AppDispatch, RootState } from "../../redux/store/store"; // Assuming this is the path to your store file import { AppDispatch, RootState } from "../../redux/store/store"; // Assuming this is the path to your store file
import { toast } from "sonner"; import { toast } from "sonner";
import {
CustomTextField,
} from "../../components/AddUserModel/styled.css.tsx";
// Define the data structure for permission // Define the data structure for permission
interface Permission { interface Permission {
module: string; module: string;
@ -155,7 +157,7 @@ const AddEditRolePage: React.FC = () => {
{/* Role Name Input */} {/* Role Name Input */}
<Box sx={{ mb: 2 }}> <Box sx={{ mb: 2 }}>
<label>Role Name</label> <label>Role Name</label>
<TextField <CustomTextField
placeholder="Enter role name" placeholder="Enter role name"
value={roleName} value={roleName}
onChange={handleRoleNameChange} onChange={handleRoleNameChange}
@ -256,10 +258,15 @@ const AddEditRolePage: React.FC = () => {
{/* Submit Button */} {/* Submit Button */}
<Box sx={{ mt: 2, display: "flex", justifyContent: "flex-end" }}> <Box sx={{ mt: 2, display: "flex", justifyContent: "flex-end" }}>
<Button <Button
variant="contained"
color="primary"
onClick={handleSubmit} onClick={handleSubmit}
disabled={loading} disabled={loading}
sx={{
backgroundColor: "#52ACDF",
color: "white",
borderRadius: "8px",
width: "117px",
"&:hover": { backgroundColor: "#439BC1" },
}}
> >
{loading ? "Saving..." : "Save Role"} {loading ? "Saving..." : "Save Role"}
</Button> </Button>

View file

@ -14,6 +14,7 @@ export const dataDisplayCustomizations = {
padding: '8px', padding: '8px',
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
gap: 0, gap: 0,
}, },
}, },

View file

@ -385,7 +385,7 @@ export const inputsCustomizations = {
color: (theme.vars || theme).palette.text.primary, color: (theme.vars || theme).palette.text.primary,
borderRadius: (theme.vars || theme).shape.borderRadius, borderRadius: (theme.vars || theme).shape.borderRadius,
border: `1px solid ${(theme.vars || theme).palette.divider}`, border: `1px solid ${(theme.vars || theme).palette.divider}`,
backgroundColor: (theme.vars || theme).palette.background.default, backgroundColor: "#272727",
transition: 'border 120ms ease-in', transition: 'border 120ms ease-in',
'&:hover': { '&:hover': {
borderColor: gray[400], borderColor: gray[400],