middle of role page

This commit is contained in:
2025-07-29 09:33:55 +03:30
parent 8d3b5b6e1e
commit 74dddb1705
9 changed files with 319 additions and 2 deletions

View File

@@ -7,7 +7,7 @@ export const metadata = {
const Page = () => { const Page = () => {
return ( return (
<WithPermission permission_name={["manage_Roles"]}> <WithPermission permission_name={["manage_roles"]}>
<RolesPage /> <RolesPage />
</WithPermission> </WithPermission>
); );

View File

@@ -0,0 +1,91 @@
"use client";
import DataTableWithAuth from "@/core/components/DataTableWithAuth";
import { GET_ROLE_LIST } from "@/core/utils/routes";
import { Box, Stack, Typography } from "@mui/material";
import { useMemo } from "react";
// import RowActions from "./RowActions";
import Toolbar from "./Toolbar";
import moment from "jalali-moment";
import RowActions from "@/components/dashboard/Users/RowActions";
const DataTable = () => {
const columns = useMemo(
() => [
{
accessorKey: "id",
header: "کد یکتا",
id: "id",
enableColumnFilter: true,
datatype: "text",
filterMode: "equals",
sortDescFirst: false,
columnFilterModeOptions: ["equals", "contains"],
grow: false,
size: 100,
},
{
accessorKey: "name_fa",
header: "نام",
id: "name_fa",
enableColumnFilter: true,
datatype: "text",
filterMode: "equals",
sortDescFirst: false,
columnFilterModeOptions: ["equals", "contains"],
grow: false,
size: 100,
},
{
accessorKey: "created_at",
header: "تاریخ ساخت",
id: "created_at",
enableColumnFilter: false,
datatype: "date",
filterMode: "equals",
grow: false,
size: 100,
Cell: ({ renderedCellValue }) => (
<Typography variant="body2">
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("HH:mm | YYYY/MM/DD") : "-"}
</Typography>
),
},
{
accessorKey: "updated_at",
header: "تاریخ آخرین بروزرسانی",
id: "updated_at",
enableColumnFilter: false,
datatype: "date",
filterMode: "equals",
grow: false,
size: 100,
Cell: ({ renderedCellValue }) => (
<Typography variant="body2">
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("HH:mm | YYYY/MM/DD") : "-"}
</Typography>
),
},
],
[]
);
return (
<>
<Box sx={{ p: 1, border: 1, borderColor: "divider", borderRadius: 1 }}>
<DataTableWithAuth
need_filter={true}
columns={columns}
sorting={[{ id: "id", desc: true }]}
table_url={GET_ROLE_LIST}
page_name={"rolesPage"}
table_name={"rolesList"}
TableToolbar={Toolbar}
enableRowActions
positionActionsColumn={"last"}
RowActions={RowActions}
/>
</Box>
</>
);
};
export default DataTable;

View File

@@ -0,0 +1,150 @@
import LtrTextField from "@/core/components/LtrTextField";
import StyledForm from "@/core/components/StyledForm";
import { yupResolver } from "@hookform/resolvers/yup";
import { Button, Checkbox, Chip, DialogActions, DialogContent, Divider, Grid, Stack } from "@mui/material";
import { Controller, useForm } from "react-hook-form";
import { object, string } from "yup";
import useRequest from "@/lib/hooks/useRequest";
import { CREATE_ROLE } from "@/core/utils/routes";
import { useState } from "react";
import { usePermissionsList } from "@/lib/hooks/usePermissionsList";
const defaultValues = {
name: "",
name_fa: "",
};
const validationSchema = object().shape({
name: string().required("نام فارسی نقش را وارد کنید"),
name_fa: string().required("نام انگلیسی نقش را وارد کنید"),
});
const CreateRoleForm = ({ setOpen, mutate }) => {
const [permissionChecked, setPermissionChecked] = useState({});
const requestServer = useRequest({ notificationSuccess: true });
const { data } = usePermissionsList();
console.log("data", data);
const handleCheckboxChange = (index) => {
setPermissionChecked((prev) => ({
...prev,
[index]: !prev[index],
}));
};
const {
control,
handleSubmit,
formState: { isSubmitting, errors },
} = useForm({ defaultValues, resolver: yupResolver(validationSchema) });
const onSubmit = async (data) => {
const formData = new FormData();
Object.keys(data).forEach((key) => {
formData.append(key, data[key]);
});
try {
await requestServer(CREATE_ROLE, "post", {
data: formData,
});
setOpen(false);
mutate();
} catch (error) {}
};
return (
<>
<DialogContent dividers>
<Divider sx={{ mb: 3 }}>
<Chip color="primary" variant="outlined" label="نقش جدید" />
</Divider>
<StyledForm
id="createRleForm"
onSubmit={handleSubmit(onSubmit)}
style={{ width: "100%", height: "100%" }}
>
<Stack spacing={2}>
<Grid container spacing={2}>
<Grid size={{ xs: 12, md: 6 }}>
<Controller
control={control}
render={({ field, fieldState: { error } }) => {
return (
<LtrTextField
{...field}
label="نام انگلیسی نقش"
variant="outlined"
fullWidth
error={!!error}
helperText={!!error && error.message}
/>
);
}}
name={"name"}
/>
</Grid>
<Grid size={{ xs: 12, md: 6 }}>
<Controller
control={control}
render={({ field, fieldState: { error } }) => {
return (
<LtrTextField
{...field}
label="نام فارسی نقش"
variant="outlined"
fullWidth
error={!!error}
helperText={!!error && error.message}
/>
);
}}
name={"name_fa"}
/>
</Grid>
<Grid item xs={12} md={12}>
<Divider>
<Chip label="سطوح دسترسی" size="small" />
</Divider>
<Grid container spacing={1}>
{permissions.map((permission, index) => (
<Grid item key={index}>
<Checkbox
checked={!!permissionChecked[index]}
onChange={() => handleCheckboxChange(index)}
/>
{permission.label}
</Grid>
))}
</Grid>
</Grid>
</Grid>
</Stack>
</StyledForm>
</DialogContent>
<DialogActions>
<Button
disabled={isSubmitting}
variant="outlined"
color="secondary"
size="large"
onClick={() => setOpen(false)}
>
بستن
</Button>
<Button
type="submit"
disabled={isSubmitting}
form="createRoleForm"
size="large"
autoFocus
variant="contained"
>
{isSubmitting ? "در حال ثبت نقش جدید..." : "ثبت نقش جدید"}
</Button>
</DialogActions>
</>
);
};
export default CreateRoleForm;

View File

@@ -0,0 +1,39 @@
"use client";
import { AddCircle } from "@mui/icons-material";
import { Button, Dialog, IconButton, useMediaQuery, useTheme } from "@mui/material";
import CreateRoleForm from "./Form";
import { useState } from "react";
const CreateRole = ({ mutate }) => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
const [open, setOpen] = useState(false);
const handleOpen = () => {
setOpen(true);
};
return (
<>
{isMobile ? (
<IconButton aria-label="نقش جدید" color="primary" onClick={handleOpen}>
<AddCircle sx={{ fontSize: "25px" }} />
</IconButton>
) : (
<Button
size={"small"}
variant="contained"
color="primary"
startIcon={<AddCircle />}
onClick={handleOpen}
>
نقش جدید
</Button>
)}
<Dialog maxWidth="sm" fullWidth={true} open={open}>
<CreateRoleForm open={open} setOpen={setOpen} mutate={mutate} />
</Dialog>
</>
);
};
export default CreateRole;

View File

@@ -0,0 +1,10 @@
import CreateRole from "./Create";
const Toolbar = ({ mutate }) => {
return (
<>
<CreateRole mutate={mutate} />
</>
);
};
export default Toolbar;

View File

@@ -5,7 +5,7 @@ import DataTable from "./DataTable";
const RolesPage = () => { const RolesPage = () => {
return ( return (
<Stack spacing={1}> <Stack spacing={1}>
<PageTitle title={"کاربران"} /> <PageTitle title={"نقش ها"} />
<DataTable /> <DataTable />
</Stack> </Stack>
); );

View File

@@ -8,6 +8,7 @@ export const GET_PERMISSIONS_ROUTE = api + "/profile/permissions";
export const GET_SIDEBAR_BADGE_ROUTE = ""; export const GET_SIDEBAR_BADGE_ROUTE = "";
export const GET_PROVINCE_LISTS = api + "/provinces/list"; export const GET_PROVINCE_LISTS = api + "/provinces/list";
export const GET_ROLE_LISTS = api + "/roles/list"; export const GET_ROLE_LISTS = api + "/roles/list";
export const GET_PERMISSIONS_LIST = api + "/permissions/list";
export const GET_CATEGORY = api + "/categories/list"; export const GET_CATEGORY = api + "/categories/list";
export const GET_CALLER_HISTORY = api + "/calls/list"; export const GET_CALLER_HISTORY = api + "/calls/list";
@@ -17,3 +18,8 @@ export const GET_USER_LIST = api + "/users";
export const CREATE_USER = api + "/users"; export const CREATE_USER = api + "/users";
export const DELETE_USER = api + "/users"; export const DELETE_USER = api + "/users";
export const UPDATE_USER = api + "/users"; export const UPDATE_USER = api + "/users";
export const GET_ROLE_LIST = api + "/roles";
export const CREATE_ROLE = api + "/roles";
export const DELETE_ROLE = api + "/roles";
export const UPDATE_ROLE = api + "/roles";

View File

@@ -0,0 +1,21 @@
import { GET_PERMISSIONS_LIST } from "@/core/utils/routes";
import useSWR from "swr";
import useRequest from "./useRequest";
export const usePermissionsList = () => {
const request = useRequest();
const fetcher = async (url) => {
try {
const response = await request(url);
return response.data.data;
} catch (error) {
throw new Error();
}
};
return useSWR(GET_PERMISSIONS_LIST, fetcher, {
keepPreviousData: true,
dedupingInterval: 30000,
});
};