diff --git a/.gitignore b/.gitignore
index e72b4d6..f6e1a1c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,3 +39,4 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts
+/.idea
diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index 13566b8..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Editor-based HTTP Client requests
-/httpRequests/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
deleted file mode 100644
index 1113612..0000000
--- a/.idea/codeStyles/Project.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
deleted file mode 100644
index 79ee123..0000000
--- a/.idea/codeStyles/codeStyleConfig.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/crm-app.iml b/.idea/crm-app.iml
deleted file mode 100644
index 24643cc..0000000
--- a/.idea/crm-app.iml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
deleted file mode 100644
index c63ea15..0000000
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index f13d54d..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/prettier.xml b/.idea/prettier.xml
deleted file mode 100644
index b0c1c68..0000000
--- a/.idea/prettier.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 35eb1dd..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/app/(withoutAuth)/teleport/page.js b/src/app/(withoutAuth)/teleport/page.js
new file mode 100644
index 0000000..eef64f3
--- /dev/null
+++ b/src/app/(withoutAuth)/teleport/page.js
@@ -0,0 +1,10 @@
+import TeleportPage from "@/components/Teleport";
+
+export const metadata = {
+ title: "درحال انتقال به استان مورد نظر",
+};
+
+const Page = () => {
+ return ;
+};
+export default Page;
diff --git a/src/components/Login/Form/index.jsx b/src/components/Login/Form/index.jsx
index e3ae06b..41444fb 100644
--- a/src/components/Login/Form/index.jsx
+++ b/src/components/Login/Form/index.jsx
@@ -46,7 +46,7 @@ const LoginForm = () => {
data: formData,
});
setToken(response.data.data.token);
- } catch (error) {}
+ } catch (error) { }
};
return (
diff --git a/src/components/Teleport/index.jsx b/src/components/Teleport/index.jsx
new file mode 100644
index 0000000..cc7b9b7
--- /dev/null
+++ b/src/components/Teleport/index.jsx
@@ -0,0 +1,51 @@
+'use client'
+import LoadingHardPage from "@/core/components/LoadingHardPage";
+import { TELEPORT_USER_ROUTE } from "@/core/utils/routes";
+import { useAuth } from "@/lib/contexts/auth";
+import useRequest from "@/lib/hooks/useRequest";
+import { Stack, Typography } from "@mui/material";
+import { useSearchParams } from "next/navigation";
+import { useEffect, useState } from "react";
+
+const TelePortPage = () => {
+ const { setToken } = useAuth()
+ const searchParams = useSearchParams();
+ const token = searchParams.get("token");
+ const user_id = searchParams.get("user_id");
+
+ const [error, setError] = useState(false)
+ const requestServer = useRequest({ notificationShow: false });
+
+ useEffect(() => {
+ const login = async () => {
+ try {
+ const response = await requestServer(TELEPORT_USER_ROUTE, "post", {
+ data: {
+ token: decodeURIComponent(token),
+ user_id: decodeURIComponent(user_id)
+ }
+ });
+ setToken(response.data.data.token);
+ } catch (error) { setError(true) }
+ }
+
+ login()
+ }, [])
+
+ return (
+
+ مشکلی در انتقال پیش آمده است!
+
+ ) : (
+ درحال انتقال به مرکز مورد نظر...
+ )
+ }
+ loading={true}
+ />
+ )
+}
+export default TelePortPage
\ No newline at end of file
diff --git a/src/components/dashboard/Roles/DataTable.jsx b/src/components/dashboard/Roles/DataTable.jsx
index 3b6cab7..8acce6a 100644
--- a/src/components/dashboard/Roles/DataTable.jsx
+++ b/src/components/dashboard/Roles/DataTable.jsx
@@ -34,6 +34,18 @@ const DataTable = () => {
grow: false,
size: 100,
},
+ {
+ accessorKey: "name",
+ header: "نام انگلیسی",
+ id: "name",
+ enableColumnFilter: true,
+ datatype: "text",
+ filterMode: "equals",
+ sortDescFirst: false,
+ columnFilterModeOptions: ["equals", "contains"],
+ grow: false,
+ size: 100,
+ },
{
accessorKey: "created_at",
header: "تاریخ ساخت",
diff --git a/src/components/dashboard/Users/DataTable.jsx b/src/components/dashboard/Users/DataTable.jsx
index 31d2a6b..7988782 100644
--- a/src/components/dashboard/Users/DataTable.jsx
+++ b/src/components/dashboard/Users/DataTable.jsx
@@ -39,6 +39,7 @@ const DataTable = () => {
size: 100,
},
{
+ accessorKey: "telephone_id",
header: "شماره تماس داخلی",
id: "telephone_id",
enableColumnFilter: true,
@@ -48,7 +49,6 @@ const DataTable = () => {
columnFilterModeOptions: ["equals", "contains"],
grow: false,
size: 100,
- Cell: ({ row }) => ,
},
{
accessorKey: "is_online",
diff --git a/src/components/dashboard/dashboard/index.jsx b/src/components/dashboard/dashboard/index.jsx
index 29faec3..eb996a7 100644
--- a/src/components/dashboard/dashboard/index.jsx
+++ b/src/components/dashboard/dashboard/index.jsx
@@ -5,7 +5,7 @@ import OnlineUsersReport from "./OnlineUsersReport";
const DashboardPage = () => {
return (
-
+ {/* */}
);
};
diff --git a/src/components/layouts/dashboard/headerWithSidebar/Sidebar/SidebarMenu.jsx b/src/components/layouts/dashboard/headerWithSidebar/Sidebar/SidebarMenu.jsx
index 1bfb012..defa771 100644
--- a/src/components/layouts/dashboard/headerWithSidebar/Sidebar/SidebarMenu.jsx
+++ b/src/components/layouts/dashboard/headerWithSidebar/Sidebar/SidebarMenu.jsx
@@ -1,12 +1,12 @@
"use client";
+import Profile from "@/core/components/Profile";
+import { filterMenuItems } from "@/core/utils/filterMenuItems";
+import { pageMenu } from "@/core/utils/pageMenu";
import { usePermissions } from "@/lib/hooks/usePermissions";
import { List } from "@mui/material";
import { usePathname } from "next/navigation";
import { useEffect, useReducer, useState } from "react";
-import { filterMenuItems } from "@/core/utils/filterMenuItems";
-import { pageMenu } from "@/core/utils/pageMenu";
import SidebarListItems from "./SidebarListItems";
-import Profile from "@/core/components/Profile";
function selectPage(item, route) {
if (item.type === "page") {
@@ -53,16 +53,16 @@ function reducer(state, action) {
return state.map((item) =>
item.hasSubitems
? {
- ...item,
- Subitems: item.Subitems.map((subitem) =>
- subitem.hasSubitems
- ? {
- ...subitem,
- Subitems: toggleSubitems(subitem.Subitems, action.id),
- }
- : subitem
- ),
- }
+ ...item,
+ Subitems: item.Subitems.map((subitem) =>
+ subitem.hasSubitems
+ ? {
+ ...subitem,
+ Subitems: toggleSubitems(subitem.Subitems, action.id),
+ }
+ : subitem
+ ),
+ }
: item
);
diff --git a/src/components/layouts/dashboard/headerWithSidebar/index.jsx b/src/components/layouts/dashboard/headerWithSidebar/index.jsx
index 4b58b78..bb6c33e 100644
--- a/src/components/layouts/dashboard/headerWithSidebar/index.jsx
+++ b/src/components/layouts/dashboard/headerWithSidebar/index.jsx
@@ -8,8 +8,11 @@ import HeaderMenu from "./HeaderMenu";
import moment from "jalali-moment";
import { headerMenu } from "@/core/utils/headerMenu";
import SidebarMenu from "./Sidebar/SidebarMenu";
+import Teleporting from "@/core/components/Teleporting";
+import { usePermissions } from "@/lib/hooks/usePermissions";
+import WithWidgetMiddleware from "@/core/middlewares/withWidget";
-const drawerWidth = 300;
+const drawerWidth = 270;
const Main = styled(Stack, { shouldForwardProp: (prop) => prop !== "open" })(({ theme, open }) => ({
flexGrow: 1,
@@ -50,11 +53,13 @@ const DrawerHeader = styled("div")(({ theme }) => ({
alignItems: "center",
padding: theme.spacing(0, 1),
...theme.mixins.toolbar,
- minHeight: "40px !important",
+ minHeight: "43px !important",
justifyContent: "flex-end",
}));
const HeaderWithSidebar = ({ children }) => {
+ const { data: permissions } = usePermissions();
+ const isTeleportToProvince = permissions?.some((permission) => permission === "teleport_to_province");
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("md")); // Detect mobile/tablet screen
const [open, setOpen] = useState(!isMobile); // Initial state based on screen size
@@ -103,9 +108,16 @@ const HeaderWithSidebar = ({ children }) => {
},
}}
>
- {headerMenu.map((menu) => (
-
- ))}
+
+
+ {headerMenu.map((menu) => (
+
+ ))}
+
+
+
+
+
diff --git a/src/core/components/Teleporting/index.jsx b/src/core/components/Teleporting/index.jsx
new file mode 100644
index 0000000..2713547
--- /dev/null
+++ b/src/core/components/Teleporting/index.jsx
@@ -0,0 +1,102 @@
+import { GET_TOKEN_TELEPORT_USER_ROUTE } from "@/core/utils/routes";
+import { useAuth } from "@/lib/contexts/auth";
+import useProvinces from "@/lib/hooks/useProvince";
+import useRequest from "@/lib/hooks/useRequest";
+import { Apartment } from "@mui/icons-material";
+import { Box, CircularProgress, FormControl, InputLabel, MenuItem, Select, Stack, Typography, Zoom } from "@mui/material";
+import { useMemo, useState } from "react";
+
+const Teleporting = () => {
+ const { user } = useAuth()
+ const { provinces, errorProvinces, loadingProvinces } = useProvinces()
+ const getColumnSelectOptions = useMemo(() => {
+ if (loadingProvinces) {
+ return [{ value: "loading", label: "در حال بارگذاری..." }];
+ }
+ if (errorProvinces) {
+ return [{ value: "error", label: "خطا در بارگذاری" }];
+ }
+ return [
+ ...provinces.map((province) => ({
+ value: province.id,
+ label: province.name,
+ })),
+ ];
+ }, [provinces, errorProvinces, loadingProvinces]);
+ const requestServer = useRequest();
+ const [loading, setLoading] = useState(false);
+ const [province, setProvince] = useState(user.server_province_id);
+
+ const handleChange = async ({ target: { value } }) => {
+ setLoading(true);
+ setProvince(value)
+ try {
+ const { data } = await requestServer(GET_TOKEN_TELEPORT_USER_ROUTE, "post", {
+ data: {
+ province_id: value
+ },
+ });
+
+ const url = `http://${data.data.ip}/teleport`
+ const params = `?token=${encodeURIComponent(data.data.token)}&user_id=${encodeURIComponent(data.data.user_id)}`;
+ window.location.href = url + params
+ } catch (error) {
+ setLoading(false);
+ setProvince(user.server_province_id)
+ }
+ };
+
+ if (loading) {
+ return (
+
+
+
+ در حال انتقال به {provinces.find(p => p.id == province).name}
+
+
+ );
+ }
+
+ return (
+
+
+ مرکز
+
+
+
+ );
+};
+
+export default Teleporting;
\ No newline at end of file
diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js
index ba43bad..c92a570 100644
--- a/src/core/utils/routes.js
+++ b/src/core/utils/routes.js
@@ -1,5 +1,8 @@
const api = process.env.NEXT_PUBLIC_API_URL;
+export const TELEPORT_USER_ROUTE = api + "/verify_authentication";
+export const GET_TOKEN_TELEPORT_USER_ROUTE = api + "/login_to_province";
+
export const GET_USER_ROUTE = api + "/profile/info";
export const CHANGE_USER_PASSWORD = api + "/profile/change_password";
export const GET_USER_LOGIN_ROUTE = api + "/auth/login";
diff --git a/src/lib/contexts/auth.js b/src/lib/contexts/auth.js
index 90e97e3..eae28e0 100644
--- a/src/lib/contexts/auth.js
+++ b/src/lib/contexts/auth.js
@@ -36,6 +36,7 @@ const AuthContext = createContext();
export const AuthProvider = ({ children }) => {
const [errorState, setErrorState] = useState({ status: null, message: "" });
const [state, dispatch] = useReducer(authReducer, initAuth);
+ const [tokenChecked, setTokenChecked] = useState(false);
const clearUser = useCallback(() => {
dispatch({ type: "CLEAR_USER" });
@@ -95,9 +96,12 @@ export const AuthProvider = ({ children }) => {
useEffect(() => {
const localToken = localStorage.getItem("_token");
if (localToken) dispatch({ type: "SET_TOKEN", token: localToken });
+ setTokenChecked(true);
}, []);
useEffect(() => {
+ if (!tokenChecked) return;
+
if (!state.token) {
clearUser();
changeAuthState(false);
@@ -105,7 +109,7 @@ export const AuthProvider = ({ children }) => {
return;
}
getUser();
- }, [state.token]);
+ }, [tokenChecked, state.token]);
return (