add functionality to search and password visibility and responsivess added in somepage

This commit is contained in:
jaanvi 2025-03-03 13:36:37 +05:30
parent 42300867a7
commit d21f4f5d27
8 changed files with 199 additions and 71 deletions

View file

@ -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}

View file

@ -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>

View file

@ -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]) ? (

View file

@ -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">

View file

@ -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>
); );

View file

@ -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"

View file

@ -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%" },
}} }}

View file

@ -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>