diff --git a/src/app/(withAuth)/(dashboardLayout)/dashboard/roles/page.js b/src/app/(withAuth)/(dashboardLayout)/dashboard/roles/page.js index 631cd14..8e37670 100644 --- a/src/app/(withAuth)/(dashboardLayout)/dashboard/roles/page.js +++ b/src/app/(withAuth)/(dashboardLayout)/dashboard/roles/page.js @@ -7,7 +7,7 @@ export const metadata = { const Page = () => { return ( - + ); diff --git a/src/components/dashboard/Roles/DataTable.jsx b/src/components/dashboard/Roles/DataTable.jsx new file mode 100644 index 0000000..7dc50f6 --- /dev/null +++ b/src/components/dashboard/Roles/DataTable.jsx @@ -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 }) => ( + + {renderedCellValue ? moment(renderedCellValue).locale("fa").format("HH:mm | YYYY/MM/DD") : "-"} + + ), + }, + { + accessorKey: "updated_at", + header: "تاریخ آخرین بروزرسانی", + id: "updated_at", + enableColumnFilter: false, + datatype: "date", + filterMode: "equals", + grow: false, + size: 100, + Cell: ({ renderedCellValue }) => ( + + {renderedCellValue ? moment(renderedCellValue).locale("fa").format("HH:mm | YYYY/MM/DD") : "-"} + + ), + }, + ], + [] + ); + + return ( + <> + + + + + ); +}; +export default DataTable; diff --git a/src/components/dashboard/Roles/RowAcctions/index.jsx b/src/components/dashboard/Roles/RowAcctions/index.jsx new file mode 100644 index 0000000..e69de29 diff --git a/src/components/dashboard/Roles/Toolbar/Create/Form/index.jsx b/src/components/dashboard/Roles/Toolbar/Create/Form/index.jsx new file mode 100644 index 0000000..01fc9f0 --- /dev/null +++ b/src/components/dashboard/Roles/Toolbar/Create/Form/index.jsx @@ -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 ( + <> + + + + + + + + + { + return ( + + ); + }} + name={"name"} + /> + + + { + return ( + + ); + }} + name={"name_fa"} + /> + + + + + + + {permissions.map((permission, index) => ( + + handleCheckboxChange(index)} + /> + {permission.label} + + ))} + + + + + + + + + + + + ); +}; + +export default CreateRoleForm; diff --git a/src/components/dashboard/Roles/Toolbar/Create/index.jsx b/src/components/dashboard/Roles/Toolbar/Create/index.jsx new file mode 100644 index 0000000..db5df6f --- /dev/null +++ b/src/components/dashboard/Roles/Toolbar/Create/index.jsx @@ -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 ? ( + + + + ) : ( + + )} + + + + + ); +}; +export default CreateRole; diff --git a/src/components/dashboard/Roles/Toolbar/index.jsx b/src/components/dashboard/Roles/Toolbar/index.jsx new file mode 100644 index 0000000..413eefc --- /dev/null +++ b/src/components/dashboard/Roles/Toolbar/index.jsx @@ -0,0 +1,10 @@ +import CreateRole from "./Create"; + +const Toolbar = ({ mutate }) => { + return ( + <> + + + ); +}; +export default Toolbar; diff --git a/src/components/dashboard/Roles/index.jsx b/src/components/dashboard/Roles/index.jsx index dc33690..6f3cadd 100644 --- a/src/components/dashboard/Roles/index.jsx +++ b/src/components/dashboard/Roles/index.jsx @@ -5,7 +5,7 @@ import DataTable from "./DataTable"; const RolesPage = () => { return ( - + ); diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js index b803eff..bac15b9 100644 --- a/src/core/utils/routes.js +++ b/src/core/utils/routes.js @@ -8,6 +8,7 @@ export const GET_PERMISSIONS_ROUTE = api + "/profile/permissions"; export const GET_SIDEBAR_BADGE_ROUTE = ""; export const GET_PROVINCE_LISTS = api + "/provinces/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_CALLER_HISTORY = api + "/calls/list"; @@ -17,3 +18,8 @@ export const GET_USER_LIST = api + "/users"; export const CREATE_USER = api + "/users"; export const DELETE_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"; diff --git a/src/lib/hooks/usePermissionsList.js b/src/lib/hooks/usePermissionsList.js new file mode 100644 index 0000000..1ceff74 --- /dev/null +++ b/src/lib/hooks/usePermissionsList.js @@ -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, + }); +};