Feature/update profile sidebar

This commit is contained in:
AmirHossein Mahmoodi
2024-09-16 07:59:19 +00:00
parent 3e8abb7580
commit 9387f85cf7
19 changed files with 230 additions and 203 deletions

View File

@@ -221,7 +221,7 @@ const DataTable_TableBodyCell = ({ cell, numRows, rowRef, staticColumnIndex, sta
{tableCellProps.children ?? (
<>
{cell.getIsPlaceholder() ? (
columnDef.PlaceholderCell?.({ cell, column, row, table }) ?? null
(columnDef.PlaceholderCell?.({ cell, column, row, table }) ?? null)
) : showSkeletons !== false && (isLoading || showSkeletons) ? (
<Skeleton animation="wave" height={20} width={skeletonWidth} {...skeletonProps} />
) : columnDefType === "display" &&

View File

@@ -27,9 +27,10 @@ const DataTable_TableContainer = ({ table, ...rest }) => {
};
useIsomorphicLayoutEffect(() => {
const topToolbarHeight = typeof document !== "undefined" ? topToolbarRef.current?.offsetHeight ?? 0 : 0;
const topToolbarHeight = typeof document !== "undefined" ? (topToolbarRef.current?.offsetHeight ?? 0) : 0;
const bottomToolbarHeight = typeof document !== "undefined" ? bottomToolbarRef?.current?.offsetHeight ?? 0 : 0;
const bottomToolbarHeight =
typeof document !== "undefined" ? (bottomToolbarRef?.current?.offsetHeight ?? 0) : 0;
setTotalToolbarHeight(topToolbarHeight + bottomToolbarHeight);
});

View File

@@ -24,13 +24,11 @@ import VisibilityOff from "@mui/icons-material/VisibilityOff";
const validationSchema = object({
current_password: string().required("اجباری"),
new_password: string().required("اجباری"),
repeat_new_password: string().required("اجباری").test(
"password-match",
"رمز عبور جدید و تکرار آن باید یکسان باشند",
function(value) {
repeat_new_password: string()
.required("اجباری")
.test("password-match", "رمز عبور جدید و تکرار آن باید یکسان باشند", function (value) {
return this.parent.new_password === value;
},
),
}),
});
const Form = ({ handleCloseForm, setLoading }) => {
@@ -61,8 +59,7 @@ const Form = ({ handleCloseForm, setLoading }) => {
try {
await request(CHANGE_USER_PASSWORD, "post", { data: formData, signal: controller.signal });
handleCloseForm();
} catch (error) {
}
} catch (error) {}
};
return (
@@ -152,4 +149,4 @@ const Form = ({ handleCloseForm, setLoading }) => {
</>
);
};
export default Form;
export default Form;

View File

@@ -19,19 +19,29 @@ const ChangePass = ({ open, setOpen }) => {
<Form handleCloseForm={handleCloseForm} setLoading={setLoading} />
</DialogContent>
<DialogActions>
<LoadingButton loading={loading} variant="outlined" color="error" size="large"
onClick={handleCloseForm}>
<LoadingButton
loading={loading}
variant="outlined"
color="error"
size="large"
onClick={handleCloseForm}
>
بستن
</LoadingButton>
<LoadingButton type="submit" loading={loading} form="ChangePassword"
size="large" autoFocus
variant="contained"
loadingPosition="end"
endIcon={<SaveIcon />}>
<LoadingButton
type="submit"
loading={loading}
form="ChangePassword"
size="large"
autoFocus
variant="contained"
loadingPosition="end"
endIcon={<SaveIcon />}
>
ثبت
</LoadingButton>
</DialogActions>
</Dialog>
);
};
export default ChangePass;
export default ChangePass;

View File

@@ -35,9 +35,13 @@ const ProfileActions = () => {
</Tooltip>
<Divider orientation="vertical" variant="middle" flexItem sx={{ mx: 1 }} />
<Tooltip title="تغییر رمز عبور" arrow>
<IconButton aria-label="تغییر رمز عبور" color="primary" onClick={() => {
setOpenChangePass(true);
}}>
<IconButton
aria-label="تغییر رمز عبور"
color="primary"
onClick={() => {
setOpenChangePass(true);
}}
>
<VpnKeyIcon />
</IconButton>
</Tooltip>

View File

@@ -1,31 +1,35 @@
"use client";
import { useAuth } from "@/lib/contexts/auth";
import { Avatar, Box, Chip, Divider, Stack, Typography } from "@mui/material";
import moment from "jalali-moment";
const ProfileInfo = () => {
const { user } = useAuth();
return (
<>
<Box sx={{ display: "flex", alignItems: "center", my: 0.5 }}>
<Avatar
alt="User Image"
src=""
sx={{ width: 56, height: 56 }}
/>
<Avatar alt="User Image" src={user?.avatar} sx={{ width: 56, height: 56 }} />
<Stack sx={{ ml: 1 }}>
<Box sx={{ display: "flex", alignItems: "end", gap: 0.7 }}>
<Typography variant="h6">حسن محمد زاده عبدالله</Typography>
<Typography variant="h6">{`${user.first_name} ${user.last_name}`}</Typography>
</Box>
<Typography variant="caption">.: اداره کل ستاد :.</Typography>
<Typography variant="caption">.: {user.name} :.</Typography>
</Stack>
</Box>
<Box sx={{ display: "flex", alignItems: "center", my: 0.5 }}>
<Typography variant="button" color="#757575">آخرین ورود</Typography>
<Typography variant="button" color="#757575">
آخرین ورود
</Typography>
<Divider sx={{ mx: 2, flexGrow: 1 }} />
<Typography variant="subtitle2" color="#757575">1 ساعت پیش</Typography>
<Typography variant="subtitle2" color="#757575">
{moment(user.last_login).locale("fa").fromNow()}
</Typography>
</Box>
<Box sx={{ my: 0.5 }}>
<Divider>
<Chip size="small" label="userName" color="success" variant="outlined" />
<Chip size="small" label={user.username} color="success" variant="outlined" />
</Divider>
</Box>
</>

View File

@@ -53,11 +53,11 @@ const Form = ({ handleCloseForm, setLoading }) => {
const { user, getUser } = useAuth();
const [uploadBackDrop, setUploadBackDrop] = useState(false);
const defaultValues = {
first_name: user.data.first_name,
last_name: user.data.last_name,
major: user.data.major,
degree: user.data.degree,
mobile: user.data.mobile,
first_name: user.first_name,
last_name: user.last_name,
major: user.major,
degree: user.degree,
mobile: user.mobile,
avatar: null,
};
@@ -89,8 +89,7 @@ const Form = ({ handleCloseForm, setLoading }) => {
await request(UPDATE_USER_ROUTE, "post", { data: formData });
getUser();
handleCloseForm();
} catch (error) {
}
} catch (error) {}
};
return (
@@ -99,15 +98,17 @@ const Form = ({ handleCloseForm, setLoading }) => {
<Chip color="success" variant="outlined" label="ویرایش پروفایل" />
</Divider>
<StyledForm onSubmit={handleSubmit(onSubmit)} id={"UpdateProfile"}>
<Box sx={{
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
mb: 4,
position: "relative",
borderRadius: "50%",
}}>
<Box
sx={{
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
mb: 4,
position: "relative",
borderRadius: "50%",
}}
>
<Button
component="label"
sx={{
@@ -123,15 +124,16 @@ const Form = ({ handleCloseForm, setLoading }) => {
onMouseEnter={() => setUploadBackDrop(true)}
onMouseLeave={() => setUploadBackDrop(false)}
>
<Avatar
src={`${process.env.NEXT_PUBLIC_API_URL}/${user.data.avatar}`}
sx={{ width: 120, height: 120, border: "1px solid #e1e1e1" }}
/>
<Avatar src={user?.avatar} sx={{ width: 120, height: 120, border: "1px solid #e1e1e1" }} />
<Backdrop
sx={{
color: "#fff", zIndex: (theme) => theme.zIndex.drawer + 1,
position: "absolute", width: 120, height: 120,
marginLeft: "auto", marginRight: "auto",
color: "#fff",
zIndex: (theme) => theme.zIndex.drawer + 1,
position: "absolute",
width: 120,
height: 120,
marginLeft: "auto",
marginRight: "auto",
borderRadius: "50%",
}}
open={uploadBackDrop}
@@ -139,8 +141,11 @@ const Form = ({ handleCloseForm, setLoading }) => {
<CloudUploadIcon sx={{ fontSize: "2rem" }} color="inherit" />
</Backdrop>
</Box>
<VisuallyHiddenInput type="file" accept="image/*"
onChange={(event) => setValue("avatar", event.target.files[0])} />
<VisuallyHiddenInput
type="file"
accept="image/*"
onChange={(event) => setValue("avatar", event.target.files[0])}
/>
</Button>
</Box>
<Grid container columns={{ xs: 1, sm: 2 }} spacing={2}>
@@ -156,8 +161,9 @@ const Form = ({ handleCloseForm, setLoading }) => {
fullWidth
type="text"
/>
<FormHelperText
id="first_name">{errors.first_name ? errors.first_name.message : null}</FormHelperText>
<FormHelperText id="first_name">
{errors.first_name ? errors.first_name.message : null}
</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={1}>
@@ -172,8 +178,9 @@ const Form = ({ handleCloseForm, setLoading }) => {
fullWidth
type="text"
/>
<FormHelperText
id="last_name">{errors.last_name ? errors.last_name.message : null}</FormHelperText>
<FormHelperText id="last_name">
{errors.last_name ? errors.last_name.message : null}
</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={1}>
@@ -188,8 +195,7 @@ const Form = ({ handleCloseForm, setLoading }) => {
fullWidth
type="text"
/>
<FormHelperText
id="major">{errors.major ? errors.major.message : null}</FormHelperText>
<FormHelperText id="major">{errors.major ? errors.major.message : null}</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={1}>
@@ -217,9 +223,7 @@ const Form = ({ handleCloseForm, setLoading }) => {
/>
)}
/>
<FormHelperText>
{error ? error.message : null}
</FormHelperText>
<FormHelperText>{error ? error.message : null}</FormHelperText>
</FormControl>
)}
/>
@@ -236,8 +240,7 @@ const Form = ({ handleCloseForm, setLoading }) => {
fullWidth
type="text"
/>
<FormHelperText
id="mobile">{errors.mobile ? errors.mobile.message : null}</FormHelperText>
<FormHelperText id="mobile">{errors.mobile ? errors.mobile.message : null}</FormHelperText>
</FormControl>
</Grid>
</Grid>
@@ -245,4 +248,4 @@ const Form = ({ handleCloseForm, setLoading }) => {
</>
);
};
export default Form;
export default Form;

View File

@@ -25,14 +25,20 @@ const Update = ({ open, setOpen }) => {
<Button autoFocus variant="outlined" color="error" size="large" onClick={handleCloseForm}>
بستن
</Button>
<LoadingButton type="submit" loading={loading} form="UpdateProfile" size="large" autoFocus
variant="contained"
loadingPosition="end"
endIcon={<SaveIcon />}>
<LoadingButton
type="submit"
loading={loading}
form="UpdateProfile"
size="large"
autoFocus
variant="contained"
loadingPosition="end"
endIcon={<SaveIcon />}
>
ثبت
</LoadingButton>
</DialogActions>
</Dialog>
);
};
export default Update;
export default Update;

View File

@@ -6,12 +6,14 @@ import ProfileActions from "./ProfileActions";
const Profile = () => {
return (
<Stack sx={{
px: 2,
background: "#f7f7f7",
borderTop: "1px dashed #e1e1e1",
borderBottom: "1px dashed #e1e1e1",
}}>
<Stack
sx={{
px: 2,
background: "#f7f7f7",
borderTop: "1px dashed #e1e1e1",
borderBottom: "1px dashed #e1e1e1",
}}
>
<ProfileInfo />
<ProfileActions />
</Stack>

View File

@@ -11,4 +11,4 @@ export const getValueByPath = (obj, path) => {
}
return value;
}
};

View File

@@ -1,80 +1,80 @@
export const headerMenu = [
{
title: 'تصادفات',
title: "تصادفات",
subMenu: [
[
{
title: 'تصادفات روزانه',
href: 'https://rms.witel.ir/v2/daily_accidents/create'
}
]
]
title: "تصادفات روزانه",
href: "https://rms.witel.ir/v2/daily_accidents/create",
},
],
],
},
{
title: 'گزارش های جامع',
title: "گزارش های جامع",
subMenu: [
[
{
title: 'گزارش محوری',
href: 'https://rms.witel.ir/v2/axis_reports'
title: "گزارش محوری",
href: "https://rms.witel.ir/v2/axis_reports",
},
{
title: 'هوش تجاری (BI)',
href: 'https://rms.witel.ir/v2/axis_reports'
}
]
]
title: "هوش تجاری (BI)",
href: "https://rms.witel.ir/v2/axis_reports",
},
],
],
},
{
title: 'زیرساخت و ناوگان',
title: "زیرساخت و ناوگان",
subMenu: [
[
{
title: 'پراکندگی بر روی نقشه راهدارخانه ها',
href: 'https://rms.witel.ir/v2/map?type=rahdar'
title: "پراکندگی بر روی نقشه راهدارخانه ها",
href: "https://rms.witel.ir/v2/map?type=rahdar",
},
{
title: 'راهدارخانه ها',
href: 'https://rms.witel.ir/v2/rahdari_points'
}
title: "راهدارخانه ها",
href: "https://rms.witel.ir/v2/rahdari_points",
},
],
[
{
title: 'ممیزی ماشین آلات راهداری کشور',
href: 'https://rms.witel.ir/cmms-audit'
}
]
]
title: "ممیزی ماشین آلات راهداری کشور",
href: "https://rms.witel.ir/cmms-audit",
},
],
],
},
{
title: 'سامانه های راهداری',
title: "سامانه های راهداری",
subMenu: [
[
{
title: 'تحقیق و توسعه',
href: 'https://rms.witel.ir/RandD'
title: "تحقیق و توسعه",
href: "https://rms.witel.ir/RandD",
},
{
title: 'سامانه مدیریت یکپارچه زیرساخت های راه (PMS,BMS,SMS)',
href: 'http://roadams.rmto.ir'
title: "سامانه مدیریت یکپارچه زیرساخت های راه (PMS,BMS,SMS)",
href: "http://roadams.rmto.ir",
},
{
title: 'سامانه مدیریت ناوگان (FMS)',
href: 'http://fms.141.ir'
title: "سامانه مدیریت ناوگان (FMS)",
href: "http://fms.141.ir",
},
{
title: 'سامانه جامع مدیریت سوانح و حوادث جاده ای',
href: 'https://items.rmto.ir'
title: "سامانه جامع مدیریت سوانح و حوادث جاده ای",
href: "https://items.rmto.ir",
},
{
title: 'سامانه مدیریت نگهداری ماشین آلات (CMMS)',
href: 'https://cmms.rmto.ir/Login.aspx?ReturnUrl=%2f'
title: "سامانه مدیریت نگهداری ماشین آلات (CMMS)",
href: "https://cmms.rmto.ir/Login.aspx?ReturnUrl=%2f",
},
{
title: 'درگاه کاتالوگ داده',
href: 'https://roadams.rmto.ir:8080'
}
]
]
}
]
title: "درگاه کاتالوگ داده",
href: "https://roadams.rmto.ir:8080",
},
],
],
},
];

View File

@@ -91,7 +91,7 @@ export const pageMenu = [
type: "menu",
icon: <FactCheckIcon sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true,
badges: ['road_items.total'],
badges: ["road_items.total"],
Subitems: [
{
id: "roadItemManagmentSupervisor",
@@ -99,7 +99,7 @@ export const pageMenu = [
type: "menu",
icon: <SpeedIcon sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true,
badges: ['road_items.supervise_cnt'],
badges: ["road_items.supervise_cnt"],
Subitems: [
{
id: "roadItemManagmentSupervisorCartable",
@@ -119,7 +119,7 @@ export const pageMenu = [
type: "menu",
icon: <EngineeringIcon sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true,
badges: ['road_items.operation_cnt'],
badges: ["road_items.operation_cnt"],
Subitems: [
{
id: "roadItemManagmentOparationCreate",
@@ -169,7 +169,7 @@ export const pageMenu = [
type: "menu",
icon: <FireTruckIcon sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true,
badges: ['road_patrols.total'],
badges: ["road_patrols.total"],
Subitems: [
{
id: "roadPatrolManagmentSupervisor",
@@ -177,7 +177,7 @@ export const pageMenu = [
type: "menu",
icon: <SpeedIcon sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true,
badges: ['road_patrols.supervise_cnt'],
badges: ["road_patrols.supervise_cnt"],
Subitems: [
{
id: "roadPatrolManagmentSupervisorCartable",
@@ -197,7 +197,7 @@ export const pageMenu = [
type: "menu",
icon: <EngineeringIcon sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true,
badges: ['road_patrols.operation_cnt'],
badges: ["road_patrols.operation_cnt"],
Subitems: [
{
id: "roadPatrolManagmentOparationCreate",
@@ -277,7 +277,7 @@ export const pageMenu = [
type: "menu",
icon: <RouteIcon sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true,
badges: ['safety_and_privacy.step_one', 'safety_and_privacy.step_two'],
badges: ["safety_and_privacy.step_one", "safety_and_privacy.step_two"],
Subitems: [
{
id: "safetyAndPrivacyManagmentOparation",
@@ -340,7 +340,7 @@ export const pageMenu = [
type: "menu",
icon: <ElectricBoltIcon sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true,
badges: ['road_observations.total'],
badges: ["road_observations.total"],
Subitems: [
{
id: "roadObservationsManagmentSupervisor",
@@ -348,7 +348,7 @@ export const pageMenu = [
type: "menu",
icon: <SpeedIcon sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true,
badges: ['road_observations.supervise_cnt'],
badges: ["road_observations.supervise_cnt"],
Subitems: [
{
id: "roadObservationsManagmentSupervisorCartable",
@@ -373,7 +373,7 @@ export const pageMenu = [
type: "menu",
icon: <EngineeringIcon sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true,
badges: ['road_observations.operation_cnt'],
badges: ["road_observations.operation_cnt"],
Subitems: [
{
id: "roadObservationsManagmentOparationCartable",