add functionality to search and password visibility and responsivess added in somepage
This commit is contained in:
parent
42300867a7
commit
d21f4f5d27
|
@ -6,10 +6,12 @@ import {
|
||||||
DialogActions,
|
DialogActions,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
|
IconButton,
|
||||||
TextField,
|
TextField,
|
||||||
} 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 { Visibility, VisibilityOff } from "@mui/icons-material";
|
||||||
|
|
||||||
//By Jaanvi : Edit Model :: 11-feb-25
|
//By Jaanvi : Edit Model :: 11-feb-25
|
||||||
interface AddEditCategoryModalProps {
|
interface AddEditCategoryModalProps {
|
||||||
|
@ -86,6 +88,8 @@ const AddEditCategoryModal: React.FC<AddEditCategoryModalProps> = ({
|
||||||
}
|
}
|
||||||
}, [editRow, setValue, reset]);
|
}, [editRow, setValue, reset]);
|
||||||
|
|
||||||
|
const [showPassword, setShowPassword] = React.useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
open={open}
|
open={open}
|
||||||
|
@ -172,26 +176,58 @@ const AddEditCategoryModal: React.FC<AddEditCategoryModalProps> = ({
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
{!editRow &&<Controller
|
{!editRow && (
|
||||||
name="password"
|
<Controller
|
||||||
control={control}
|
name="password"
|
||||||
rules={{
|
control={control}
|
||||||
required: "password is required",
|
rules={{
|
||||||
}}
|
required: "password is required",
|
||||||
render={({ field }) => (
|
}}
|
||||||
<TextField
|
render={({ field }) => (
|
||||||
{...field}
|
<>
|
||||||
required
|
<Box sx={{position:"relative" }}>
|
||||||
margin="dense"
|
<TextField
|
||||||
label="Password"
|
{...field}
|
||||||
type="password"
|
required
|
||||||
fullWidth
|
margin="dense"
|
||||||
variant="standard"
|
label="Password"
|
||||||
error={!!errors.password}
|
type={showPassword ? "text" : "password"}
|
||||||
helperText={errors.password?.message}
|
id="password"
|
||||||
/>
|
autoComplete="current-password"
|
||||||
)}
|
autoFocus
|
||||||
/>}
|
fullWidth
|
||||||
|
variant="standard"
|
||||||
|
error={!!errors.password}
|
||||||
|
helperText={errors.password?.message}
|
||||||
|
/>
|
||||||
|
<IconButton
|
||||||
|
sx={{
|
||||||
|
position: "absolute",
|
||||||
|
top: "60%",
|
||||||
|
right: "10px",
|
||||||
|
background: "none",
|
||||||
|
borderColor: "transparent",
|
||||||
|
transform: "translateY(-50%)",
|
||||||
|
"&:hover": {
|
||||||
|
backgroundColor: "transparent",
|
||||||
|
borderColor: "transparent",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
onClick={() =>
|
||||||
|
setShowPassword((prev) => !prev)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{showPassword ? (
|
||||||
|
<VisibilityOff />
|
||||||
|
) : (
|
||||||
|
<Visibility />
|
||||||
|
)}
|
||||||
|
</IconButton>
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<Controller
|
<Controller
|
||||||
name="phone"
|
name="phone"
|
||||||
control={control}
|
control={control}
|
||||||
|
|
|
@ -73,7 +73,7 @@ export default function AppNavbar() {
|
||||||
Dashboard
|
Dashboard
|
||||||
</Typography>
|
</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<ColorModeIconDropdown />
|
{/* <ColorModeIconDropdown /> */}
|
||||||
<MenuButton aria-label="menu" onClick={toggleDrawer(true)}>
|
<MenuButton aria-label="menu" onClick={toggleDrawer(true)}>
|
||||||
<MenuRoundedIcon />
|
<MenuRoundedIcon />
|
||||||
</MenuButton>
|
</MenuButton>
|
||||||
|
|
|
@ -127,7 +127,14 @@ const CustomTable: React.FC<CustomTableProps> = ({
|
||||||
return (
|
return (
|
||||||
<Box sx={{ overflowX: "auto", width: "100%" }}>
|
<Box sx={{ overflowX: "auto", width: "100%" }}>
|
||||||
<TableContainer component={Paper}>
|
<TableContainer component={Paper}>
|
||||||
<Table sx={{ minWidth: 700 }} aria-label="customized table">
|
<Table
|
||||||
|
sx={{
|
||||||
|
minWidth: 700,
|
||||||
|
width: "100%",
|
||||||
|
tableLayout: "auto",
|
||||||
|
}}
|
||||||
|
aria-label="customized table"
|
||||||
|
>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
{columns.map((column) => (
|
{columns.map((column) => (
|
||||||
|
@ -136,7 +143,13 @@ const CustomTable: React.FC<CustomTableProps> = ({
|
||||||
align={column.align || "left"}
|
align={column.align || "left"}
|
||||||
sx={{
|
sx={{
|
||||||
whiteSpace: "nowrap", // Prevent wrapping
|
whiteSpace: "nowrap", // Prevent wrapping
|
||||||
fontSize: { xs: "12px", sm: "14px" }, // Responsively adjust font size
|
// fontSize: { xs: "12px", sm: "14px" },
|
||||||
|
fontSize: {
|
||||||
|
xs: "10px",
|
||||||
|
sm: "12px",
|
||||||
|
md: "14px",
|
||||||
|
}, // Adjust font size responsively
|
||||||
|
padding: { xs: "8px", sm: "12px" },
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{column.label}
|
{column.label}
|
||||||
|
@ -154,9 +167,11 @@ const CustomTable: React.FC<CustomTableProps> = ({
|
||||||
sx={{
|
sx={{
|
||||||
whiteSpace: "nowrap", // Prevent wrapping
|
whiteSpace: "nowrap", // Prevent wrapping
|
||||||
fontSize: {
|
fontSize: {
|
||||||
xs: "12px",
|
xs: "10px",
|
||||||
sm: "14px",
|
sm: "12px",
|
||||||
}, // Responsively adjust font size
|
md: "14px",
|
||||||
|
}, // Adjust font size responsively
|
||||||
|
padding: { xs: "8px", sm: "12px" },
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{isImage(row[column.id]) ? (
|
{isImage(row[column.id]) ? (
|
||||||
|
|
|
@ -12,10 +12,10 @@ import ColorModeIconDropdown from "../../shared-theme/ColorModeIconDropdown";
|
||||||
import NotificationsRoundedIcon from "@mui/icons-material/NotificationsRounded";
|
import NotificationsRoundedIcon from "@mui/icons-material/NotificationsRounded";
|
||||||
|
|
||||||
export default function Header() {
|
export default function Header() {
|
||||||
const [showNotifications, setShowNotifications] = React.useState(false);
|
const [showNotifications, setShowNotifications] = React.useState(false);
|
||||||
const toggleNotifications = () => {
|
const toggleNotifications = () => {
|
||||||
setShowNotifications((prev) => !prev);
|
setShowNotifications((prev) => !prev);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
|
@ -27,6 +27,7 @@ export default function Header() {
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
|
flexDirection: { xs: "column", sm: "row" },
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box sx={{ flexGrow: 1 }} />
|
<Box sx={{ flexGrow: 1 }} />
|
||||||
|
@ -35,11 +36,16 @@ export default function Header() {
|
||||||
spacing={3}
|
spacing={3}
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
justifyContent="flex-end"
|
justifyContent="flex-end"
|
||||||
|
sx={{
|
||||||
|
width: "100%",
|
||||||
|
justifyContent: { xs: "center", sm: "flex-end" },
|
||||||
|
marginTop: { xs: 2, sm: 0 },
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{/* Search Bar */}
|
{/* Search Bar */}
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
width: "360px",
|
width: { xs: "100%", sm: "360px" },
|
||||||
height: "44px",
|
height: "44px",
|
||||||
backgroundColor: "#FFFFFF",
|
backgroundColor: "#FFFFFF",
|
||||||
borderRadius: "8px",
|
borderRadius: "8px",
|
||||||
|
@ -51,12 +57,24 @@ export default function Header() {
|
||||||
>
|
>
|
||||||
<SearchIcon sx={{ color: "#202020" }} />
|
<SearchIcon sx={{ color: "#202020" }} />
|
||||||
<InputBase
|
<InputBase
|
||||||
sx={{ marginLeft: 1, flex: 1, color: "#202020" }}
|
sx={{
|
||||||
|
marginLeft: 1,
|
||||||
|
flex: 1,
|
||||||
|
color: "#202020",
|
||||||
|
fontSize: { xs: "12px", sm: "14px" },
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Notification and Profile Section */}
|
{/* Notification and Profile Section */}
|
||||||
<Stack direction="row" spacing={2} alignItems="center">
|
<Stack
|
||||||
|
direction="row"
|
||||||
|
spacing={2}
|
||||||
|
alignItems="center"
|
||||||
|
sx={{
|
||||||
|
display: { xs: "none", sm: "flex" }, // Hide on mobile, show on larger screens
|
||||||
|
}}
|
||||||
|
>
|
||||||
{/* Custom Bell Icon */}
|
{/* Custom Bell Icon */}
|
||||||
<MenuButton
|
<MenuButton
|
||||||
showBadge
|
showBadge
|
||||||
|
@ -89,12 +107,13 @@ export default function Header() {
|
||||||
p: 2,
|
p: 2,
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
top: "55px",
|
top: "55px",
|
||||||
right: "280px",
|
right: { xs: "10px", sm: "280px" },
|
||||||
bgcolor: "#FFFFFF",
|
bgcolor: "#FFFFFF",
|
||||||
boxShadow: 1,
|
boxShadow: 1,
|
||||||
borderRadius: 1,
|
borderRadius: 1,
|
||||||
zIndex: 1300,
|
zIndex: 1300,
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
|
width: "250px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* <Typography variant="h6" color="text.primary">
|
{/* <Typography variant="h6" color="text.primary">
|
||||||
|
|
|
@ -157,14 +157,17 @@ const AddEditRolePage: React.FC = () => {
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Role Name Input */}
|
{/* Role Name Input */}
|
||||||
<Box sx={{ mb: 2 }}>
|
<Box sx={{ mb: 2}}>
|
||||||
|
<label >Role Name</label>
|
||||||
<TextField
|
<TextField
|
||||||
label="Role Name"
|
placeholder="Enter role name"
|
||||||
value={roleName}
|
value={roleName}
|
||||||
onChange={handleRoleNameChange}
|
onChange={handleRoleNameChange}
|
||||||
fullWidth
|
fullWidth
|
||||||
|
required
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
sx={{ mb: 2 }}
|
|
||||||
|
sx={{ mb: 2 ,mt:2}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
@ -270,7 +273,6 @@ const AddEditRolePage: React.FC = () => {
|
||||||
autoHideDuration={3000}
|
autoHideDuration={3000}
|
||||||
onClose={() => setOpenSnackbar(false)}
|
onClose={() => setOpenSnackbar(false)}
|
||||||
message="Role added successfully!"
|
message="Role added successfully!"
|
||||||
|
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { Box, Button, Typography } from "@mui/material";
|
import { Box, Button, TextField, Typography } from "@mui/material";
|
||||||
import AddEditCategoryModal from "../../components/AddEditCategoryModal";
|
import AddEditCategoryModal from "../../components/AddEditCategoryModal";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import CustomTable, { Column } from "../../components/CustomTable";
|
import CustomTable, { Column } from "../../components/CustomTable";
|
||||||
|
@ -10,6 +10,7 @@ import {
|
||||||
createAdmin,
|
createAdmin,
|
||||||
} from "../../redux/slices/adminSlice";
|
} from "../../redux/slices/adminSlice";
|
||||||
import { AppDispatch, RootState } from "../../redux/store/store";
|
import { AppDispatch, RootState } from "../../redux/store/store";
|
||||||
|
import SearchIcon from "@mui/icons-material/Search";
|
||||||
|
|
||||||
export default function AdminList() {
|
export default function AdminList() {
|
||||||
const [modalOpen, setModalOpen] = useState(false);
|
const [modalOpen, setModalOpen] = useState(false);
|
||||||
|
@ -22,7 +23,7 @@ export default function AdminList() {
|
||||||
const dispatch = useDispatch<AppDispatch>();
|
const dispatch = useDispatch<AppDispatch>();
|
||||||
|
|
||||||
const admins = useSelector((state: RootState) => state.adminReducer.admins);
|
const admins = useSelector((state: RootState) => state.adminReducer.admins);
|
||||||
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch(adminList());
|
dispatch(adminList());
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
@ -84,9 +85,18 @@ export default function AdminList() {
|
||||||
{ id: "registeredAddress", label: "Address" },
|
{ id: "registeredAddress", label: "Address" },
|
||||||
{ id: "action", label: "Action", align: "center" },
|
{ id: "action", label: "Action", align: "center" },
|
||||||
];
|
];
|
||||||
|
const filteredAdmins = admins?.filter(
|
||||||
|
(admin) =>
|
||||||
|
admin.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
|
admin.email.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
|
admin.phone.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
|
admin.registeredAddress
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(searchTerm.toLowerCase())
|
||||||
|
);
|
||||||
|
|
||||||
const categoryRows = admins?.length
|
const categoryRows = filteredAdmins?.length
|
||||||
? admins?.map(
|
? filteredAdmins?.map(
|
||||||
(
|
(
|
||||||
admin: {
|
admin: {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -109,6 +119,19 @@ export default function AdminList() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<Typography
|
||||||
|
component="h2"
|
||||||
|
variant="h6"
|
||||||
|
sx={{
|
||||||
|
fontWeight: 600,
|
||||||
|
mb: { xs: 2, sm: 0 },
|
||||||
|
width: "100%",
|
||||||
|
display: "flex",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Admins
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
|
@ -119,13 +142,25 @@ export default function AdminList() {
|
||||||
mb: 2, // Add margin bottom for spacing
|
mb: 2, // Add margin bottom for spacing
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography
|
<TextField
|
||||||
component="h2"
|
variant="outlined"
|
||||||
variant="h6"
|
size="small"
|
||||||
sx={{ fontWeight: 600, mb: { xs: 2, sm: 0 } }}
|
placeholder="Search..."
|
||||||
>
|
value={searchTerm}
|
||||||
Admins
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
</Typography>
|
sx={{
|
||||||
|
width: { xs: "100%", sm: "30%" },
|
||||||
|
marginBottom: { xs: 2, sm: 0 },
|
||||||
|
}}
|
||||||
|
InputProps={{
|
||||||
|
startAdornment: (
|
||||||
|
<SearchIcon
|
||||||
|
sx={{ color: "#202020", marginRight: 1 }}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
size="medium"
|
size="medium"
|
||||||
|
|
|
@ -109,7 +109,6 @@ export default function Login(props: { disableCustomTheme?: boolean }) {
|
||||||
<Card
|
<Card
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
sx={{
|
sx={{
|
||||||
|
|
||||||
maxWidth: "400px",
|
maxWidth: "400px",
|
||||||
width: { xs: "80%", sm: "80%", md: "100%" },
|
width: { xs: "80%", sm: "80%", md: "100%" },
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import {
|
||||||
import { AppDispatch, RootState } from "../../redux/store/store";
|
import { AppDispatch, RootState } from "../../redux/store/store";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import AddEditRolePage from "../AddEditRolePage";
|
import AddEditRolePage from "../AddEditRolePage";
|
||||||
|
import SearchIcon from "@mui/icons-material/Search";
|
||||||
|
|
||||||
export default function RoleList() {
|
export default function RoleList() {
|
||||||
const [modalOpen, setModalOpen] = useState(false);
|
const [modalOpen, setModalOpen] = useState(false);
|
||||||
|
@ -71,25 +72,31 @@ export default function RoleList() {
|
||||||
{ id: "action", label: "Action", align: "center" },
|
{ id: "action", label: "Action", align: "center" },
|
||||||
];
|
];
|
||||||
|
|
||||||
const categoryRows = roles?.map((role: Role, index: number) => ({
|
const filterRoles = roles?.filter((role) =>
|
||||||
id: role.id,
|
role.name.toLocaleLowerCase().includes(searchTerm.toLowerCase())
|
||||||
srno: index + 1,
|
);
|
||||||
name: role.name,
|
|
||||||
status: (
|
const categoryRows = filterRoles?.length
|
||||||
<Chip
|
? filterRoles?.map((role: Role, index: number) => ({
|
||||||
label={role.status === 1 ? "Active" : "Inactive"}
|
id: role.id,
|
||||||
color={role.status === 1 ? "primary" : "default"}
|
srno: index + 1,
|
||||||
variant="outlined"
|
name: role.name,
|
||||||
sx={{
|
status: (
|
||||||
fontWeight: 600,
|
<Chip
|
||||||
width: "80px",
|
label={role.status === 1 ? "Active" : "Inactive"}
|
||||||
textAlign: "center",
|
color={role.status === 1 ? "primary" : "default"}
|
||||||
borderRadius: "4px",
|
variant="outlined"
|
||||||
}}
|
sx={{
|
||||||
/>
|
fontWeight: 600,
|
||||||
),
|
width: "80px",
|
||||||
statusValue: role.status,
|
textAlign: "center",
|
||||||
}));
|
borderRadius: "4px",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
statusValue: role.status,
|
||||||
|
}))
|
||||||
|
: [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -97,9 +104,10 @@ export default function RoleList() {
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
|
flexDirection: { xs: "column", sm: "row" },
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
mb: 2,
|
mb: 2,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TextField
|
<TextField
|
||||||
|
@ -108,12 +116,26 @@ export default function RoleList() {
|
||||||
placeholder="Search..."
|
placeholder="Search..."
|
||||||
value={searchTerm}
|
value={searchTerm}
|
||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
sx={{ width: "30%" }}
|
sx={{
|
||||||
|
width: { xs: "100%", sm: "30%" },
|
||||||
|
marginBottom: { xs: 2, sm: 0 },
|
||||||
|
}}
|
||||||
|
InputProps={{
|
||||||
|
startAdornment: (
|
||||||
|
<SearchIcon
|
||||||
|
sx={{ color: "#202020", marginRight: 1 }}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
size="small"
|
size="small"
|
||||||
onClick={handleClickOpen}
|
onClick={handleClickOpen}
|
||||||
|
sx={{
|
||||||
|
textAlign: "center",
|
||||||
|
width: { xs: "100%", sm: "auto" },
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Add Role
|
Add Role
|
||||||
</Button>
|
</Button>
|
||||||
|
|
Loading…
Reference in a new issue