add prettier for formatting to project
This commit is contained in:
@@ -7,205 +7,182 @@ import { LinearProgress } from "@mui/material";
|
||||
|
||||
export const DataTableContext = createContext();
|
||||
|
||||
const DataTableProvider = ({
|
||||
children,
|
||||
user_id,
|
||||
page_name,
|
||||
table_name,
|
||||
columns,
|
||||
initialSort = [],
|
||||
}) => {
|
||||
const { settingStore } = useTableSetting();
|
||||
const [isInitStates, setInitStates] = useState(false);
|
||||
const flatColumns = flattenArrayOfObjects(columns, "columns");
|
||||
const [initFilter, setInitFilter] = useState({});
|
||||
const [filterData, setFilterData] = useState({});
|
||||
const [initSort, setInitSort] = useState(initialSort || []);
|
||||
const [sortData, setSortData] = useState(initialSort || []);
|
||||
const [initHide, setInitHide] = useState({});
|
||||
const [hideData, setHideData] = useState({});
|
||||
const [isDirty, setIsDirty] = useState(false);
|
||||
const [isAnyDirty, setIsAnyDirty] = useState(false);
|
||||
const DataTableProvider = ({ children, user_id, page_name, table_name, columns, initialSort = [] }) => {
|
||||
const { settingStore } = useTableSetting();
|
||||
const [isInitStates, setInitStates] = useState(false);
|
||||
const flatColumns = flattenArrayOfObjects(columns, "columns");
|
||||
const [initFilter, setInitFilter] = useState({});
|
||||
const [filterData, setFilterData] = useState({});
|
||||
const [initSort, setInitSort] = useState(initialSort || []);
|
||||
const [sortData, setSortData] = useState(initialSort || []);
|
||||
const [initHide, setInitHide] = useState({});
|
||||
const [hideData, setHideData] = useState({});
|
||||
const [isDirty, setIsDirty] = useState(false);
|
||||
const [isAnyDirty, setIsAnyDirty] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
let hasAnyConflict = false;
|
||||
const hasConflict =
|
||||
JSON.stringify(hideData) !== JSON.stringify(initHide) ||
|
||||
JSON.stringify(sortData) !== JSON.stringify(initSort) ||
|
||||
JSON.stringify(filterData) !== JSON.stringify(initFilter);
|
||||
useEffect(() => {
|
||||
let hasAnyConflict = false;
|
||||
const hasConflict =
|
||||
JSON.stringify(hideData) !== JSON.stringify(initHide) ||
|
||||
JSON.stringify(sortData) !== JSON.stringify(initSort) ||
|
||||
JSON.stringify(filterData) !== JSON.stringify(initFilter);
|
||||
|
||||
const CheckFilterValues = Object.values(filterData).every((innerObject) => {
|
||||
if (
|
||||
innerObject.datatype === "date" &&
|
||||
innerObject.filterMode === "between"
|
||||
) {
|
||||
return (
|
||||
Array.isArray(innerObject.value) &&
|
||||
innerObject.value.length === 2 &&
|
||||
innerObject.value.every((v) => v === "")
|
||||
);
|
||||
} else {
|
||||
return innerObject.value === "";
|
||||
}
|
||||
});
|
||||
const flattenObject = (obj) => {
|
||||
let result = {};
|
||||
for (const key in obj) {
|
||||
if (typeof obj[key] === "object" && obj[key] !== null) {
|
||||
Object.assign(result, flattenObject(obj[key])); // باز کردن اشیای تودرتو
|
||||
} else {
|
||||
result[key] = obj[key];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// تبدیل آبجکت به آبجکت فلت شده
|
||||
const flatHideData = flattenObject(hideData);
|
||||
|
||||
const CheckHideValues = Object.values(flatHideData).every(
|
||||
(value) => value === true,
|
||||
);
|
||||
hasAnyConflict =
|
||||
!CheckHideValues ||
|
||||
JSON.stringify(sortData) !== JSON.stringify(initialSort) ||
|
||||
!CheckFilterValues;
|
||||
|
||||
setIsDirty(hasConflict);
|
||||
setIsAnyDirty(hasAnyConflict);
|
||||
}, [hideData, sortData, filterData, initHide, initSort, initFilter]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!settingStore) return;
|
||||
const filterValues = flatColumns.reduce((acc, column) => {
|
||||
if (!column.enableColumnFilter) return acc;
|
||||
const storeFilter = settingStore?.[user_id]?.[page_name]?.[table_name]?.[
|
||||
"filters"
|
||||
]?.find((filter) => filter.id === column.id);
|
||||
if (column.datatype === "array") {
|
||||
acc[column.id] = {
|
||||
id: column.id,
|
||||
value: storeFilter?.value || [],
|
||||
filterMode: storeFilter?.filterMode || column.filterMode,
|
||||
datatype: column.datatype,
|
||||
};
|
||||
} else if (column.filterMode === "between") {
|
||||
acc[column.id] = {
|
||||
id: column.id,
|
||||
value: storeFilter?.value || ["", ""],
|
||||
filterMode: storeFilter?.filterMode || column.filterMode,
|
||||
datatype: column.datatype,
|
||||
};
|
||||
} else {
|
||||
acc[column.id] = {
|
||||
id: column.id,
|
||||
value: storeFilter?.value || "",
|
||||
filterMode: storeFilter?.filterMode || column.filterMode,
|
||||
datatype: column.datatype,
|
||||
};
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const getHideValues = (columns) => {
|
||||
return columns.reduce((acc, column) => {
|
||||
const columnId = column.id;
|
||||
const storeHide =
|
||||
settingStore?.[user_id]?.[page_name]?.[table_name]?.["hides"]?.[
|
||||
columnId
|
||||
];
|
||||
if (column.columns && column.columns.length > 0) {
|
||||
acc[columnId] = getHideValues(column.columns);
|
||||
} else {
|
||||
acc[columnId] = storeHide !== undefined ? storeHide : true;
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
|
||||
const hideValues = getHideValues(columns);
|
||||
setHideData(hideValues);
|
||||
setInitHide(hideValues);
|
||||
setFilterData(filterValues);
|
||||
setInitFilter(filterValues);
|
||||
setSortData(
|
||||
settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] ||
|
||||
initialSort,
|
||||
);
|
||||
setInitSort(
|
||||
settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] ||
|
||||
initialSort,
|
||||
);
|
||||
setInitStates(true);
|
||||
}, [settingStore]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
JSON.stringify(initFilter) !== JSON.stringify(filterData) ||
|
||||
JSON.stringify(initSort) !== JSON.stringify(sortData) ||
|
||||
JSON.stringify(initHide) !== JSON.stringify(hideData)
|
||||
) {
|
||||
if (!toast.isActive("keep_data", "filtering")) {
|
||||
toast(
|
||||
<AskForKeepData
|
||||
filterData={filterData}
|
||||
sortData={sortData}
|
||||
hideData={hideData}
|
||||
user_id={user_id}
|
||||
page_name={page_name}
|
||||
table_name={table_name}
|
||||
columns={flatColumns}
|
||||
/>,
|
||||
{
|
||||
containerId: "filtering",
|
||||
toastId: "keep_data",
|
||||
className: "filter-toast",
|
||||
position: "bottom-left",
|
||||
draggable: true,
|
||||
autoClose: false,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
toast.update("keep_data", {
|
||||
containerId: "filtering",
|
||||
toastId: "keep_data",
|
||||
render: (
|
||||
<AskForKeepData
|
||||
filterData={filterData}
|
||||
sortData={sortData}
|
||||
hideData={hideData}
|
||||
user_id={user_id}
|
||||
page_name={page_name}
|
||||
table_name={table_name}
|
||||
columns={flatColumns}
|
||||
/>
|
||||
),
|
||||
const CheckFilterValues = Object.values(filterData).every((innerObject) => {
|
||||
if (innerObject.datatype === "date" && innerObject.filterMode === "between") {
|
||||
return (
|
||||
Array.isArray(innerObject.value) &&
|
||||
innerObject.value.length === 2 &&
|
||||
innerObject.value.every((v) => v === "")
|
||||
);
|
||||
} else {
|
||||
return innerObject.value === "";
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
toast.dismiss({ containerId: "datatable" });
|
||||
}
|
||||
}, [filterData, sortData, hideData]);
|
||||
const flattenObject = (obj) => {
|
||||
let result = {};
|
||||
for (const key in obj) {
|
||||
if (typeof obj[key] === "object" && obj[key] !== null) {
|
||||
Object.assign(result, flattenObject(obj[key])); // باز کردن اشیای تودرتو
|
||||
} else {
|
||||
result[key] = obj[key];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
if (!isInitStates) return <LinearProgress sx={{ borderRadius: 2 }} />;
|
||||
// تبدیل آبجکت به آبجکت فلت شده
|
||||
const flatHideData = flattenObject(hideData);
|
||||
|
||||
return (
|
||||
<DataTableContext.Provider
|
||||
value={{
|
||||
filterData,
|
||||
setFilterData,
|
||||
sortData,
|
||||
setSortData,
|
||||
hideData,
|
||||
setHideData,
|
||||
isDirty,
|
||||
isAnyDirty,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</DataTableContext.Provider>
|
||||
);
|
||||
const CheckHideValues = Object.values(flatHideData).every((value) => value === true);
|
||||
hasAnyConflict =
|
||||
!CheckHideValues || JSON.stringify(sortData) !== JSON.stringify(initialSort) || !CheckFilterValues;
|
||||
|
||||
setIsDirty(hasConflict);
|
||||
setIsAnyDirty(hasAnyConflict);
|
||||
}, [hideData, sortData, filterData, initHide, initSort, initFilter]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!settingStore) return;
|
||||
const filterValues = flatColumns.reduce((acc, column) => {
|
||||
if (!column.enableColumnFilter) return acc;
|
||||
const storeFilter = settingStore?.[user_id]?.[page_name]?.[table_name]?.["filters"]?.find(
|
||||
(filter) => filter.id === column.id
|
||||
);
|
||||
if (column.datatype === "array") {
|
||||
acc[column.id] = {
|
||||
id: column.id,
|
||||
value: storeFilter?.value || [],
|
||||
filterMode: storeFilter?.filterMode || column.filterMode,
|
||||
datatype: column.datatype,
|
||||
};
|
||||
} else if (column.filterMode === "between") {
|
||||
acc[column.id] = {
|
||||
id: column.id,
|
||||
value: storeFilter?.value || ["", ""],
|
||||
filterMode: storeFilter?.filterMode || column.filterMode,
|
||||
datatype: column.datatype,
|
||||
};
|
||||
} else {
|
||||
acc[column.id] = {
|
||||
id: column.id,
|
||||
value: storeFilter?.value || "",
|
||||
filterMode: storeFilter?.filterMode || column.filterMode,
|
||||
datatype: column.datatype,
|
||||
};
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const getHideValues = (columns) => {
|
||||
return columns.reduce((acc, column) => {
|
||||
const columnId = column.id;
|
||||
const storeHide = settingStore?.[user_id]?.[page_name]?.[table_name]?.["hides"]?.[columnId];
|
||||
if (column.columns && column.columns.length > 0) {
|
||||
acc[columnId] = getHideValues(column.columns);
|
||||
} else {
|
||||
acc[columnId] = storeHide !== undefined ? storeHide : true;
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
|
||||
const hideValues = getHideValues(columns);
|
||||
setHideData(hideValues);
|
||||
setInitHide(hideValues);
|
||||
setFilterData(filterValues);
|
||||
setInitFilter(filterValues);
|
||||
setSortData(settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] || initialSort);
|
||||
setInitSort(settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] || initialSort);
|
||||
setInitStates(true);
|
||||
}, [settingStore]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
JSON.stringify(initFilter) !== JSON.stringify(filterData) ||
|
||||
JSON.stringify(initSort) !== JSON.stringify(sortData) ||
|
||||
JSON.stringify(initHide) !== JSON.stringify(hideData)
|
||||
) {
|
||||
if (!toast.isActive("keep_data", "filtering")) {
|
||||
toast(
|
||||
<AskForKeepData
|
||||
filterData={filterData}
|
||||
sortData={sortData}
|
||||
hideData={hideData}
|
||||
user_id={user_id}
|
||||
page_name={page_name}
|
||||
table_name={table_name}
|
||||
columns={flatColumns}
|
||||
/>,
|
||||
{
|
||||
containerId: "filtering",
|
||||
toastId: "keep_data",
|
||||
className: "filter-toast",
|
||||
position: "bottom-left",
|
||||
draggable: true,
|
||||
autoClose: false,
|
||||
}
|
||||
);
|
||||
} else {
|
||||
toast.update("keep_data", {
|
||||
containerId: "filtering",
|
||||
toastId: "keep_data",
|
||||
render: (
|
||||
<AskForKeepData
|
||||
filterData={filterData}
|
||||
sortData={sortData}
|
||||
hideData={hideData}
|
||||
user_id={user_id}
|
||||
page_name={page_name}
|
||||
table_name={table_name}
|
||||
columns={flatColumns}
|
||||
/>
|
||||
),
|
||||
});
|
||||
}
|
||||
} else {
|
||||
toast.dismiss({ containerId: "datatable" });
|
||||
}
|
||||
}, [filterData, sortData, hideData]);
|
||||
|
||||
if (!isInitStates) return <LinearProgress sx={{ borderRadius: 2 }} />;
|
||||
|
||||
return (
|
||||
<DataTableContext.Provider
|
||||
value={{
|
||||
filterData,
|
||||
setFilterData,
|
||||
sortData,
|
||||
setSortData,
|
||||
hideData,
|
||||
setHideData,
|
||||
isDirty,
|
||||
isAnyDirty,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</DataTableContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export default DataTableProvider;
|
||||
|
||||
@@ -1,109 +1,99 @@
|
||||
"use client";
|
||||
import { GET_USER_ROUTE } from "@/core/utils/routes";
|
||||
import axios from "axios";
|
||||
import {
|
||||
createContext,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useReducer,
|
||||
useState,
|
||||
} from "react";
|
||||
import { createContext, useCallback, useContext, useEffect, useReducer, useState } from "react";
|
||||
|
||||
const initAuth = {
|
||||
initAuthState: false,
|
||||
isAuth: false,
|
||||
user: {},
|
||||
initAuthState: false,
|
||||
isAuth: false,
|
||||
user: {},
|
||||
};
|
||||
|
||||
const authReducer = (state, action) => {
|
||||
switch (action.type) {
|
||||
case "CLEAR_USER":
|
||||
return { ...state, user: {} };
|
||||
case "CHANGE_USER":
|
||||
return { ...state, user: action.user };
|
||||
case "CHANGE_AUTH_STATE":
|
||||
return { ...state, isAuth: action.isAuth };
|
||||
case "CHANGE_INIT_AUTH":
|
||||
return { ...state, initAuthState: action.initAuthState };
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
switch (action.type) {
|
||||
case "CLEAR_USER":
|
||||
return { ...state, user: {} };
|
||||
case "CHANGE_USER":
|
||||
return { ...state, user: action.user };
|
||||
case "CHANGE_AUTH_STATE":
|
||||
return { ...state, isAuth: action.isAuth };
|
||||
case "CHANGE_INIT_AUTH":
|
||||
return { ...state, initAuthState: action.initAuthState };
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
const AuthContext = createContext();
|
||||
|
||||
export const AuthProvider = ({ children }) => {
|
||||
const [errorState, setErrorState] = useState({ status: null, message: "" });
|
||||
const [state, dispatch] = useReducer(authReducer, initAuth);
|
||||
const [errorState, setErrorState] = useState({ status: null, message: "" });
|
||||
const [state, dispatch] = useReducer(authReducer, initAuth);
|
||||
|
||||
const clearUser = useCallback(() => {
|
||||
dispatch({ type: "CLEAR_USER" });
|
||||
}, []);
|
||||
const clearUser = useCallback(() => {
|
||||
dispatch({ type: "CLEAR_USER" });
|
||||
}, []);
|
||||
|
||||
const changeUser = useCallback((user) => {
|
||||
dispatch({ type: "CHANGE_USER", user });
|
||||
}, []);
|
||||
const changeUser = useCallback((user) => {
|
||||
dispatch({ type: "CHANGE_USER", user });
|
||||
}, []);
|
||||
|
||||
const changeAuthState = useCallback((isAuth) => {
|
||||
dispatch({ type: "CHANGE_AUTH_STATE", isAuth });
|
||||
}, []);
|
||||
const changeAuthState = useCallback((isAuth) => {
|
||||
dispatch({ type: "CHANGE_AUTH_STATE", isAuth });
|
||||
}, []);
|
||||
|
||||
const changeInitAuth = useCallback((initAuthState) => {
|
||||
dispatch({ type: "CHANGE_INIT_AUTH", initAuthState });
|
||||
}, []);
|
||||
const changeInitAuth = useCallback((initAuthState) => {
|
||||
dispatch({ type: "CHANGE_INIT_AUTH", initAuthState });
|
||||
}, []);
|
||||
|
||||
const logout = () => {
|
||||
clearUser();
|
||||
changeAuthState(false);
|
||||
changeInitAuth(true);
|
||||
};
|
||||
|
||||
const getUser = useCallback(async () => {
|
||||
try {
|
||||
const { data } = await axios.get(GET_USER_ROUTE, {
|
||||
withCredentials: true,
|
||||
});
|
||||
changeUser(data.data);
|
||||
changeAuthState(true);
|
||||
changeInitAuth(true);
|
||||
setErrorState(false);
|
||||
} catch (error) {
|
||||
if (error.response && error.response.status === 401) {
|
||||
const logout = () => {
|
||||
clearUser();
|
||||
changeAuthState(false);
|
||||
changeInitAuth(true);
|
||||
return;
|
||||
}
|
||||
let status =
|
||||
error.response && error.response.status
|
||||
? error.response.status
|
||||
: "نامشخص";
|
||||
setErrorState({
|
||||
status,
|
||||
message: " مشکلی در احراز هویت رخ داده است . دقایقی بعد امتحان کنید!!!",
|
||||
});
|
||||
}
|
||||
}, [clearUser, changeUser, changeAuthState, changeInitAuth]);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getUser();
|
||||
}, []);
|
||||
const getUser = useCallback(async () => {
|
||||
try {
|
||||
const { data } = await axios.get(GET_USER_ROUTE, {
|
||||
withCredentials: true,
|
||||
});
|
||||
changeUser(data.data);
|
||||
changeAuthState(true);
|
||||
changeInitAuth(true);
|
||||
setErrorState(false);
|
||||
} catch (error) {
|
||||
if (error.response && error.response.status === 401) {
|
||||
clearUser();
|
||||
changeAuthState(false);
|
||||
changeInitAuth(true);
|
||||
return;
|
||||
}
|
||||
let status = error.response && error.response.status ? error.response.status : "نامشخص";
|
||||
setErrorState({
|
||||
status,
|
||||
message: " مشکلی در احراز هویت رخ داده است . دقایقی بعد امتحان کنید!!!",
|
||||
});
|
||||
}
|
||||
}, [clearUser, changeUser, changeAuthState, changeInitAuth]);
|
||||
|
||||
return (
|
||||
<AuthContext.Provider
|
||||
value={{
|
||||
user: state.user,
|
||||
isAuth: state.isAuth,
|
||||
initAuthState: state.initAuthState,
|
||||
getUser,
|
||||
logout,
|
||||
errorState,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
);
|
||||
useEffect(() => {
|
||||
getUser();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<AuthContext.Provider
|
||||
value={{
|
||||
user: state.user,
|
||||
isAuth: state.isAuth,
|
||||
initAuthState: state.initAuthState,
|
||||
getUser,
|
||||
logout,
|
||||
errorState,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useAuth = () => useContext(AuthContext);
|
||||
|
||||
@@ -1,106 +1,95 @@
|
||||
"use client";
|
||||
import {
|
||||
createContext,
|
||||
useReducer,
|
||||
useState,
|
||||
useCallback,
|
||||
useMemo,
|
||||
useContext,
|
||||
} from "react";
|
||||
import { createContext, useReducer, useState, useCallback, useMemo, useContext } from "react";
|
||||
|
||||
const reducer = (state, action) => {
|
||||
switch (action.type) {
|
||||
case "CHANGE_ACTIVE_TAB":
|
||||
return state.map((call, index) => ({
|
||||
...call,
|
||||
active: index === action.index_call,
|
||||
}));
|
||||
case "CHANGE_LIST":
|
||||
return [...action.new_list];
|
||||
case "CHANGE_ACTIVE_CATEGORY_ID":
|
||||
return state.map((call) =>
|
||||
call.id === action.tab_id
|
||||
? { ...call, active_category_id: action.category_id }
|
||||
: call,
|
||||
);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
switch (action.type) {
|
||||
case "CHANGE_ACTIVE_TAB":
|
||||
return state.map((call, index) => ({
|
||||
...call,
|
||||
active: index === action.index_call,
|
||||
}));
|
||||
case "CHANGE_LIST":
|
||||
return [...action.new_list];
|
||||
case "CHANGE_ACTIVE_CATEGORY_ID":
|
||||
return state.map((call) =>
|
||||
call.id === action.tab_id ? { ...call, active_category_id: action.category_id } : call
|
||||
);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export const CallContext = createContext(null);
|
||||
|
||||
export const CallProvider = ({ children }) => {
|
||||
const [openCallDialog, setOpenCallDialog] = useState(false);
|
||||
const [activeCall, setActiveCall] = useState(0);
|
||||
const [calls, dispatch] = useReducer(reducer, []);
|
||||
const [openCallDialog, setOpenCallDialog] = useState(false);
|
||||
const [activeCall, setActiveCall] = useState(0);
|
||||
const [calls, dispatch] = useReducer(reducer, []);
|
||||
|
||||
const changeActiveTab = useCallback((index_call) => {
|
||||
dispatch({ type: "CHANGE_ACTIVE_TAB", index_call });
|
||||
}, []);
|
||||
const changeActiveTab = useCallback((index_call) => {
|
||||
dispatch({ type: "CHANGE_ACTIVE_TAB", index_call });
|
||||
}, []);
|
||||
|
||||
const changeList = useCallback((new_list) => {
|
||||
dispatch({ type: "CHANGE_LIST", new_list });
|
||||
}, []);
|
||||
const changeList = useCallback((new_list) => {
|
||||
dispatch({ type: "CHANGE_LIST", new_list });
|
||||
}, []);
|
||||
|
||||
const changeActiveCategoryId = useCallback((tab_id, category_id) => {
|
||||
dispatch({ type: "CHANGE_ACTIVE_CATEGORY_ID", tab_id, category_id });
|
||||
}, []);
|
||||
const changeActiveCategoryId = useCallback((tab_id, category_id) => {
|
||||
dispatch({ type: "CHANGE_ACTIVE_CATEGORY_ID", tab_id, category_id });
|
||||
}, []);
|
||||
|
||||
const changeActiveTabCall = (newValue) => {
|
||||
changeActiveTab(newValue);
|
||||
setActiveCall(newValue);
|
||||
};
|
||||
const changeActiveTabCall = (newValue) => {
|
||||
changeActiveTab(newValue);
|
||||
setActiveCall(newValue);
|
||||
};
|
||||
|
||||
const newCall = useCallback(
|
||||
(data) => {
|
||||
const newCall = {
|
||||
id: data.id,
|
||||
phone_number: data.phone_number,
|
||||
date: new Date(),
|
||||
active: true,
|
||||
active_category_id: null,
|
||||
};
|
||||
const newList = [...calls, newCall];
|
||||
changeList(newList);
|
||||
changeActiveTabCall(newList.length - 1);
|
||||
},
|
||||
[calls],
|
||||
);
|
||||
const newCall = useCallback(
|
||||
(data) => {
|
||||
const newCall = {
|
||||
id: data.id,
|
||||
phone_number: data.phone_number,
|
||||
date: new Date(),
|
||||
active: true,
|
||||
active_category_id: null,
|
||||
};
|
||||
const newList = [...calls, newCall];
|
||||
changeList(newList);
|
||||
changeActiveTabCall(newList.length - 1);
|
||||
},
|
||||
[calls]
|
||||
);
|
||||
|
||||
const closeCall = useCallback(
|
||||
(id) => {
|
||||
const index = calls.findIndex((answer) => answer.id === id);
|
||||
const newIndex = index === 0 ? 0 : index - 1;
|
||||
const newList = [...calls];
|
||||
newList.splice(index, 1);
|
||||
if (newList.length !== 0) {
|
||||
newList[newIndex].active = true;
|
||||
changeActiveTabCall(newIndex);
|
||||
}
|
||||
changeList(newList);
|
||||
},
|
||||
[calls],
|
||||
);
|
||||
const closeCall = useCallback(
|
||||
(id) => {
|
||||
const index = calls.findIndex((answer) => answer.id === id);
|
||||
const newIndex = index === 0 ? 0 : index - 1;
|
||||
const newList = [...calls];
|
||||
newList.splice(index, 1);
|
||||
if (newList.length !== 0) {
|
||||
newList[newIndex].active = true;
|
||||
changeActiveTabCall(newIndex);
|
||||
}
|
||||
changeList(newList);
|
||||
},
|
||||
[calls]
|
||||
);
|
||||
|
||||
const contextValue = useMemo(
|
||||
() => ({
|
||||
openCallDialog,
|
||||
setOpenCallDialog,
|
||||
calls,
|
||||
newCall,
|
||||
closeCall,
|
||||
activeCall,
|
||||
setActiveCall,
|
||||
changeActiveCategoryId,
|
||||
changeActiveTabCall,
|
||||
}),
|
||||
[openCallDialog, calls, activeCall],
|
||||
);
|
||||
const contextValue = useMemo(
|
||||
() => ({
|
||||
openCallDialog,
|
||||
setOpenCallDialog,
|
||||
calls,
|
||||
newCall,
|
||||
closeCall,
|
||||
activeCall,
|
||||
setActiveCall,
|
||||
changeActiveCategoryId,
|
||||
changeActiveTabCall,
|
||||
}),
|
||||
[openCallDialog, calls, activeCall]
|
||||
);
|
||||
|
||||
return (
|
||||
<CallContext.Provider value={contextValue}>{children}</CallContext.Provider>
|
||||
);
|
||||
return <CallContext.Provider value={contextValue}>{children}</CallContext.Provider>;
|
||||
};
|
||||
|
||||
export const useCall = () => useContext(CallContext);
|
||||
|
||||
@@ -1,72 +1,57 @@
|
||||
import { GET_CATEGORY } from "@/core/utils/routes";
|
||||
import {
|
||||
createContext,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useReducer,
|
||||
} from "react";
|
||||
import { createContext, useCallback, useContext, useEffect, useMemo, useReducer } from "react";
|
||||
import useRequest from "../hooks/useRequest";
|
||||
|
||||
const initialState = {
|
||||
categoryLists: [],
|
||||
subCategoryLists: [],
|
||||
active_category_id: null,
|
||||
categoryLists: [],
|
||||
subCategoryLists: [],
|
||||
active_category_id: null,
|
||||
};
|
||||
|
||||
const reducer = (state, action) => {
|
||||
switch (action.type) {
|
||||
case "SET_CATEGORIES":
|
||||
return { ...state, categoryLists: action.payload };
|
||||
case "SET_SUBCATEGORIES":
|
||||
return { ...state, subCategoryLists: action.payload };
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
switch (action.type) {
|
||||
case "SET_CATEGORIES":
|
||||
return { ...state, categoryLists: action.payload };
|
||||
case "SET_SUBCATEGORIES":
|
||||
return { ...state, subCategoryLists: action.payload };
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export const CategoriesContext = createContext(null);
|
||||
|
||||
export const CategoriesProvider = ({ children }) => {
|
||||
const requestServer = useRequest({ notificationShow: false });
|
||||
const requestServer = useRequest({ notificationShow: false });
|
||||
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchCategories = async () => {
|
||||
try {
|
||||
const { data } = await requestServer(GET_CATEGORY, "get");
|
||||
const subCategories = data.data;
|
||||
useEffect(() => {
|
||||
const fetchCategories = async () => {
|
||||
try {
|
||||
const { data } = await requestServer(GET_CATEGORY, "get");
|
||||
const subCategories = data.data;
|
||||
|
||||
const categories = Array.from(
|
||||
new Map(
|
||||
subCategories.map((item) => [item.category_id, item]),
|
||||
).values(),
|
||||
);
|
||||
const categories = Array.from(new Map(subCategories.map((item) => [item.category_id, item])).values());
|
||||
|
||||
dispatch({ type: "SET_CATEGORIES", payload: categories });
|
||||
dispatch({ type: "SET_SUBCATEGORIES", payload: subCategories });
|
||||
} catch (error) {}
|
||||
};
|
||||
dispatch({ type: "SET_CATEGORIES", payload: categories });
|
||||
dispatch({ type: "SET_SUBCATEGORIES", payload: subCategories });
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
fetchCategories();
|
||||
}, []);
|
||||
fetchCategories();
|
||||
}, []);
|
||||
|
||||
const contextValue = useMemo(
|
||||
() => ({
|
||||
categoryLists: state.categoryLists,
|
||||
subCategoryLists: state.subCategoryLists,
|
||||
active_category_id: state.active_category_id,
|
||||
}),
|
||||
[state],
|
||||
);
|
||||
const contextValue = useMemo(
|
||||
() => ({
|
||||
categoryLists: state.categoryLists,
|
||||
subCategoryLists: state.subCategoryLists,
|
||||
active_category_id: state.active_category_id,
|
||||
}),
|
||||
[state]
|
||||
);
|
||||
|
||||
return (
|
||||
<CategoriesContext.Provider value={contextValue}>
|
||||
{children}
|
||||
</CategoriesContext.Provider>
|
||||
);
|
||||
return <CategoriesContext.Provider value={contextValue}>{children}</CategoriesContext.Provider>;
|
||||
};
|
||||
|
||||
export const useCategory = () => useContext(CategoriesContext);
|
||||
|
||||
@@ -1,129 +1,111 @@
|
||||
"use client";
|
||||
import { Power, PowerOff } from "@mui/icons-material";
|
||||
import {
|
||||
createContext,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
useCallback,
|
||||
} from "react";
|
||||
import { createContext, useContext, useEffect, useMemo, useRef, useState, useCallback } from "react";
|
||||
import { toast } from "react-toastify";
|
||||
import { io } from "socket.io-client";
|
||||
import { useAuth } from "./auth";
|
||||
|
||||
const SocketContext = createContext({
|
||||
socket: null,
|
||||
status: "",
|
||||
socket: null,
|
||||
status: "",
|
||||
});
|
||||
|
||||
export const useSocket = () => useContext(SocketContext);
|
||||
|
||||
export const SocketProvider = ({ children }) => {
|
||||
const { user } = useAuth();
|
||||
const socketToastId = useRef(null);
|
||||
const [status, setStatus] = useState("");
|
||||
const [clientsOnline, setClientsOnline] = useState([]);
|
||||
const { user } = useAuth();
|
||||
const socketToastId = useRef(null);
|
||||
const [status, setStatus] = useState("");
|
||||
const [clientsOnline, setClientsOnline] = useState([]);
|
||||
|
||||
const socket = useMemo(() => {
|
||||
return io(`${process.env.NEXT_PUBLIC_SERVER_SOCKET_URL}`, {
|
||||
path: "/notification/socket.io",
|
||||
autoConnect: false,
|
||||
auth: { token: null },
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (user?.telephone_id) {
|
||||
socket.auth.token = { telephone_id: user.telephone_id, user_id: user.id };
|
||||
}
|
||||
}, [user, socket]);
|
||||
|
||||
const handleConnect = useCallback(() => setStatus("connected"), []);
|
||||
const handleDisconnect = useCallback(() => setStatus("disconnected"), []);
|
||||
const handleConnectError = useCallback(() => setStatus("error"), []);
|
||||
|
||||
useEffect(() => {
|
||||
socket.on("connect", handleConnect);
|
||||
socket.on("disconnect", handleDisconnect);
|
||||
socket.on("connect_error", handleConnectError);
|
||||
|
||||
return () => {
|
||||
socket.off("connect", handleConnect);
|
||||
socket.off("disconnect", handleDisconnect);
|
||||
socket.off("connect_error", handleConnectError);
|
||||
};
|
||||
}, [socket, handleConnect, handleDisconnect, handleConnectError]);
|
||||
|
||||
useEffect(() => {
|
||||
if (status === "connected") {
|
||||
toast.update(socketToastId.current, {
|
||||
containerId: "socket_connection",
|
||||
type: "success",
|
||||
render: "ارتباط با سرور برقرار شد",
|
||||
autoClose: 2000,
|
||||
closeButton: true,
|
||||
closeOnClick: true,
|
||||
icon: ({ theme, type }) => <Power />,
|
||||
});
|
||||
} else if (status === "error" || status === "disconnected") {
|
||||
if (socketToastId.current) {
|
||||
toast.update(socketToastId.current, {
|
||||
containerId: "socket_connection",
|
||||
type: "warning",
|
||||
render: "ارتباط با سرور قطع شد. در حال تلاش برای بازیابی…",
|
||||
autoClose: false,
|
||||
closeButton: false,
|
||||
draggable: false,
|
||||
icon: ({ theme, type }) => <PowerOff />,
|
||||
const socket = useMemo(() => {
|
||||
return io(`${process.env.NEXT_PUBLIC_SERVER_SOCKET_URL}`, {
|
||||
path: "/notification/socket.io",
|
||||
autoConnect: false,
|
||||
auth: { token: null },
|
||||
});
|
||||
} else {
|
||||
socketToastId.current = toast.warn(
|
||||
"ارتباط با سرور قطع شد. در حال تلاش برای بازیابی…",
|
||||
{
|
||||
containerId: "socket_connection",
|
||||
autoClose: false,
|
||||
closeButton: false,
|
||||
draggable: false,
|
||||
icon: ({ theme, type }) => <PowerOff />,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}, [status]);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (status == "connected") return;
|
||||
useEffect(() => {
|
||||
if (user?.telephone_id) {
|
||||
socket.auth.token = { telephone_id: user.telephone_id, user_id: user.id };
|
||||
}
|
||||
}, [user, socket]);
|
||||
|
||||
socket.connect();
|
||||
const handleConnect = useCallback(() => setStatus("connected"), []);
|
||||
const handleDisconnect = useCallback(() => setStatus("disconnected"), []);
|
||||
const handleConnectError = useCallback(() => setStatus("error"), []);
|
||||
|
||||
return () => {
|
||||
socket.disconnect();
|
||||
};
|
||||
}, [socket]);
|
||||
useEffect(() => {
|
||||
socket.on("connect", handleConnect);
|
||||
socket.on("disconnect", handleDisconnect);
|
||||
socket.on("connect_error", handleConnectError);
|
||||
|
||||
useEffect(() => {
|
||||
const handleNotification = (data) => {
|
||||
setClientsOnline(data.clients);
|
||||
};
|
||||
socket.on("onlineClientsUpdated", handleNotification);
|
||||
return () => {
|
||||
socket.off("connect", handleConnect);
|
||||
socket.off("disconnect", handleDisconnect);
|
||||
socket.off("connect_error", handleConnectError);
|
||||
};
|
||||
}, [socket, handleConnect, handleDisconnect, handleConnectError]);
|
||||
|
||||
return () => {
|
||||
socket.off("onlineClientsUpdated", handleNotification);
|
||||
};
|
||||
}, [socket]);
|
||||
useEffect(() => {
|
||||
if (status === "connected") {
|
||||
toast.update(socketToastId.current, {
|
||||
containerId: "socket_connection",
|
||||
type: "success",
|
||||
render: "ارتباط با سرور برقرار شد",
|
||||
autoClose: 2000,
|
||||
closeButton: true,
|
||||
closeOnClick: true,
|
||||
icon: ({ theme, type }) => <Power />,
|
||||
});
|
||||
} else if (status === "error" || status === "disconnected") {
|
||||
if (socketToastId.current) {
|
||||
toast.update(socketToastId.current, {
|
||||
containerId: "socket_connection",
|
||||
type: "warning",
|
||||
render: "ارتباط با سرور قطع شد. در حال تلاش برای بازیابی…",
|
||||
autoClose: false,
|
||||
closeButton: false,
|
||||
draggable: false,
|
||||
icon: ({ theme, type }) => <PowerOff />,
|
||||
});
|
||||
} else {
|
||||
socketToastId.current = toast.warn("ارتباط با سرور قطع شد. در حال تلاش برای بازیابی…", {
|
||||
containerId: "socket_connection",
|
||||
autoClose: false,
|
||||
closeButton: false,
|
||||
draggable: false,
|
||||
icon: ({ theme, type }) => <PowerOff />,
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [status]);
|
||||
|
||||
const contextValue = useMemo(
|
||||
() => ({ socket, status, clientsOnline }),
|
||||
[socket, status, clientsOnline],
|
||||
);
|
||||
useEffect(() => {
|
||||
if (status == "connected") return;
|
||||
|
||||
return (
|
||||
<SocketContext.Provider value={contextValue}>
|
||||
{children}
|
||||
</SocketContext.Provider>
|
||||
);
|
||||
socket.connect();
|
||||
|
||||
return () => {
|
||||
socket.disconnect();
|
||||
};
|
||||
}, [socket]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleNotification = (data) => {
|
||||
setClientsOnline(data.clients);
|
||||
};
|
||||
socket.on("onlineClientsUpdated", handleNotification);
|
||||
|
||||
return () => {
|
||||
socket.off("onlineClientsUpdated", handleNotification);
|
||||
};
|
||||
}, [socket]);
|
||||
|
||||
const contextValue = useMemo(() => ({ socket, status, clientsOnline }), [socket, status, clientsOnline]);
|
||||
|
||||
return <SocketContext.Provider value={contextValue}>{children}</SocketContext.Provider>;
|
||||
};
|
||||
|
||||
export default SocketContext;
|
||||
|
||||
@@ -6,184 +6,137 @@ import LZString from "lz-string";
|
||||
export const TableSettingContext = createContext();
|
||||
|
||||
const decompressData = (compressedData) => {
|
||||
try {
|
||||
const decompressed = LZString.decompressFromUTF16(compressedData);
|
||||
if (decompressed === null) {
|
||||
localStorage.removeItem("_setting-app");
|
||||
return null;
|
||||
} else {
|
||||
return JSON.parse(decompressed);
|
||||
try {
|
||||
const decompressed = LZString.decompressFromUTF16(compressedData);
|
||||
if (decompressed === null) {
|
||||
localStorage.removeItem("_setting-app");
|
||||
return null;
|
||||
} else {
|
||||
return JSON.parse(decompressed);
|
||||
}
|
||||
} catch (error) {
|
||||
localStorage.removeItem("_setting-app");
|
||||
return null;
|
||||
}
|
||||
} catch (error) {
|
||||
localStorage.removeItem("_setting-app");
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export const TableSettingProvider = ({ children }) => {
|
||||
const [settingStore, setSettingStore] = useState({});
|
||||
const [settingStore, setSettingStore] = useState({});
|
||||
|
||||
useEffect(() => {
|
||||
const compressedData = localStorage.getItem("_setting-app");
|
||||
useEffect(() => {
|
||||
const compressedData = localStorage.getItem("_setting-app");
|
||||
|
||||
const data = compressedData ? decompressData(compressedData) : null;
|
||||
if (data) {
|
||||
setSettingStore(data);
|
||||
}
|
||||
}, []);
|
||||
const data = compressedData ? decompressData(compressedData) : null;
|
||||
if (data) {
|
||||
setSettingStore(data);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const hideAction = useCallback(
|
||||
(user_id, page_name, table_name, settingValue) => {
|
||||
clearAction(user_id, page_name, table_name, "hides");
|
||||
updateSettingStorage(
|
||||
user_id,
|
||||
page_name,
|
||||
table_name,
|
||||
"hides",
|
||||
settingValue,
|
||||
);
|
||||
},
|
||||
[],
|
||||
);
|
||||
const hideAction = useCallback((user_id, page_name, table_name, settingValue) => {
|
||||
clearAction(user_id, page_name, table_name, "hides");
|
||||
updateSettingStorage(user_id, page_name, table_name, "hides", settingValue);
|
||||
}, []);
|
||||
|
||||
const sortAction = useCallback(
|
||||
(user_id, page_name, table_name, settingValue) => {
|
||||
updateSettingStorage(
|
||||
user_id,
|
||||
page_name,
|
||||
table_name,
|
||||
"sorts",
|
||||
settingValue,
|
||||
);
|
||||
},
|
||||
[],
|
||||
);
|
||||
const sortAction = useCallback((user_id, page_name, table_name, settingValue) => {
|
||||
updateSettingStorage(user_id, page_name, table_name, "sorts", settingValue);
|
||||
}, []);
|
||||
|
||||
const filterAction = (user_id, page_name, table_name, settingValue) => {
|
||||
updateSettingStorage(
|
||||
user_id,
|
||||
page_name,
|
||||
table_name,
|
||||
"filters",
|
||||
settingValue,
|
||||
);
|
||||
};
|
||||
|
||||
const resetAction = (user_id, page_name, table_name) => {
|
||||
const compressedData = localStorage.getItem("_setting-app");
|
||||
const prevLocalStorage = compressedData
|
||||
? decompressData(compressedData)
|
||||
: {};
|
||||
|
||||
const userSettings = prevLocalStorage[user_id] || {};
|
||||
const pageSettings = userSettings[page_name] || {};
|
||||
delete pageSettings[table_name];
|
||||
|
||||
const resetData = {
|
||||
...prevLocalStorage,
|
||||
[user_id]: {
|
||||
...userSettings,
|
||||
[page_name]: {
|
||||
...pageSettings,
|
||||
},
|
||||
},
|
||||
const filterAction = (user_id, page_name, table_name, settingValue) => {
|
||||
updateSettingStorage(user_id, page_name, table_name, "filters", settingValue);
|
||||
};
|
||||
|
||||
localStorage.setItem(
|
||||
"_setting-app",
|
||||
LZString.compressToUTF16(JSON.stringify(resetData)),
|
||||
);
|
||||
setSettingStore(resetData);
|
||||
};
|
||||
const resetAction = (user_id, page_name, table_name) => {
|
||||
const compressedData = localStorage.getItem("_setting-app");
|
||||
const prevLocalStorage = compressedData ? decompressData(compressedData) : {};
|
||||
|
||||
const updateSettingStorage = (
|
||||
user_id,
|
||||
page_name,
|
||||
table_name,
|
||||
settingType,
|
||||
settingValue,
|
||||
) => {
|
||||
const compressedData = localStorage.getItem("_setting-app");
|
||||
const prevLocalStorage = compressedData
|
||||
? decompressData(compressedData)
|
||||
: {};
|
||||
const userSettings = prevLocalStorage[user_id] || {};
|
||||
const pageSettings = userSettings[page_name] || {};
|
||||
delete pageSettings[table_name];
|
||||
|
||||
const userSettings = prevLocalStorage[user_id] || {};
|
||||
const pageSettings = userSettings[page_name] || {};
|
||||
const tableSettings = pageSettings[table_name] || {};
|
||||
const resetData = {
|
||||
...prevLocalStorage,
|
||||
[user_id]: {
|
||||
...userSettings,
|
||||
[page_name]: {
|
||||
...pageSettings,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
let newSettings;
|
||||
if (settingType === "sorts" || settingType === "filters") {
|
||||
newSettings = [...settingValue];
|
||||
} else {
|
||||
newSettings = { ...(tableSettings[settingType] || {}), ...settingValue };
|
||||
}
|
||||
|
||||
const updatedLocalStorage = {
|
||||
...prevLocalStorage,
|
||||
[user_id]: {
|
||||
...userSettings,
|
||||
[page_name]: {
|
||||
...pageSettings,
|
||||
[table_name]: {
|
||||
...tableSettings,
|
||||
[settingType]: Array.isArray(settingValue)
|
||||
? [...newSettings]
|
||||
: { ...newSettings },
|
||||
},
|
||||
},
|
||||
},
|
||||
localStorage.setItem("_setting-app", LZString.compressToUTF16(JSON.stringify(resetData)));
|
||||
setSettingStore(resetData);
|
||||
};
|
||||
|
||||
localStorage.setItem(
|
||||
"_setting-app",
|
||||
LZString.compressToUTF16(JSON.stringify(updatedLocalStorage)),
|
||||
);
|
||||
setSettingStore(updatedLocalStorage);
|
||||
};
|
||||
const updateSettingStorage = (user_id, page_name, table_name, settingType, settingValue) => {
|
||||
const compressedData = localStorage.getItem("_setting-app");
|
||||
const prevLocalStorage = compressedData ? decompressData(compressedData) : {};
|
||||
|
||||
const clearAction = (user_id, page_name, table_name, key) => {
|
||||
const compressedData = localStorage.getItem("_setting-app");
|
||||
const prevLocalStorage = compressedData
|
||||
? decompressData(compressedData)
|
||||
: {};
|
||||
const userSettings = prevLocalStorage[user_id] || {};
|
||||
const pageSettings = userSettings[page_name] || {};
|
||||
const tableSettings = pageSettings[table_name] || {};
|
||||
|
||||
const userSettings = prevLocalStorage[user_id] || {};
|
||||
const pageSettings = userSettings[page_name] || {};
|
||||
const tableSettings = pageSettings[table_name] || {};
|
||||
let newSettings;
|
||||
if (settingType === "sorts" || settingType === "filters") {
|
||||
newSettings = [...settingValue];
|
||||
} else {
|
||||
newSettings = { ...(tableSettings[settingType] || {}), ...settingValue };
|
||||
}
|
||||
|
||||
const updatedSettings = {
|
||||
...prevLocalStorage,
|
||||
[user_id]: {
|
||||
...userSettings,
|
||||
[page_name]: {
|
||||
...pageSettings,
|
||||
[table_name]: {
|
||||
...tableSettings,
|
||||
[key]: Array.isArray(tableSettings[key]) ? [] : {},
|
||||
},
|
||||
},
|
||||
},
|
||||
const updatedLocalStorage = {
|
||||
...prevLocalStorage,
|
||||
[user_id]: {
|
||||
...userSettings,
|
||||
[page_name]: {
|
||||
...pageSettings,
|
||||
[table_name]: {
|
||||
...tableSettings,
|
||||
[settingType]: Array.isArray(settingValue) ? [...newSettings] : { ...newSettings },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
localStorage.setItem("_setting-app", LZString.compressToUTF16(JSON.stringify(updatedLocalStorage)));
|
||||
setSettingStore(updatedLocalStorage);
|
||||
};
|
||||
|
||||
localStorage.setItem(
|
||||
"_setting-app",
|
||||
LZString.compressToUTF16(JSON.stringify(updatedSettings)),
|
||||
);
|
||||
setSettingStore(updatedSettings);
|
||||
};
|
||||
const clearAction = (user_id, page_name, table_name, key) => {
|
||||
const compressedData = localStorage.getItem("_setting-app");
|
||||
const prevLocalStorage = compressedData ? decompressData(compressedData) : {};
|
||||
|
||||
return (
|
||||
<TableSettingContext.Provider
|
||||
value={{
|
||||
settingStore,
|
||||
hideAction,
|
||||
sortAction,
|
||||
filterAction,
|
||||
resetAction,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</TableSettingContext.Provider>
|
||||
);
|
||||
const userSettings = prevLocalStorage[user_id] || {};
|
||||
const pageSettings = userSettings[page_name] || {};
|
||||
const tableSettings = pageSettings[table_name] || {};
|
||||
|
||||
const updatedSettings = {
|
||||
...prevLocalStorage,
|
||||
[user_id]: {
|
||||
...userSettings,
|
||||
[page_name]: {
|
||||
...pageSettings,
|
||||
[table_name]: {
|
||||
...tableSettings,
|
||||
[key]: Array.isArray(tableSettings[key]) ? [] : {},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
localStorage.setItem("_setting-app", LZString.compressToUTF16(JSON.stringify(updatedSettings)));
|
||||
setSettingStore(updatedSettings);
|
||||
};
|
||||
|
||||
return (
|
||||
<TableSettingContext.Provider
|
||||
value={{
|
||||
settingStore,
|
||||
hideAction,
|
||||
sortAction,
|
||||
filterAction,
|
||||
resetAction,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</TableSettingContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -3,47 +3,45 @@ import useRequest from "./useRequest";
|
||||
import { GET_CALLER_HISTORY } from "@/core/utils/routes";
|
||||
|
||||
const useCallerHistory = (callId, phoneNumber, maxSize) => {
|
||||
const requestServer = useRequest();
|
||||
const requestServer = useRequest();
|
||||
|
||||
const [historyData, setHistoryData] = useState([]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [hasError, setHasError] = useState(false);
|
||||
const [historyData, setHistoryData] = useState([]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [hasError, setHasError] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchHistory = async () => {
|
||||
if (!phoneNumber || !maxSize) return;
|
||||
useEffect(() => {
|
||||
const fetchHistory = async () => {
|
||||
if (!phoneNumber || !maxSize) return;
|
||||
|
||||
setIsLoading(true);
|
||||
setHasError(false);
|
||||
setIsLoading(true);
|
||||
setHasError(false);
|
||||
|
||||
try {
|
||||
const url = `${GET_CALLER_HISTORY}?phone_number=${phoneNumber}&size=${maxSize}`;
|
||||
const { data } = await requestServer(url, "get");
|
||||
const items = data?.data || [];
|
||||
try {
|
||||
const url = `${GET_CALLER_HISTORY}?phone_number=${phoneNumber}&size=${maxSize}`;
|
||||
const { data } = await requestServer(url, "get");
|
||||
const items = data?.data || [];
|
||||
|
||||
const filtered = items.filter((item) => item.id !== callId);
|
||||
const unique = Array.from(
|
||||
new Map(filtered.map((item) => [item.id, item])).values(),
|
||||
);
|
||||
const filtered = items.filter((item) => item.id !== callId);
|
||||
const unique = Array.from(new Map(filtered.map((item) => [item.id, item])).values());
|
||||
|
||||
setHistoryData(unique);
|
||||
} catch (error) {
|
||||
setHasError(true);
|
||||
setHistoryData([]);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
setHistoryData(unique);
|
||||
} catch (error) {
|
||||
setHasError(true);
|
||||
setHistoryData([]);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchHistory();
|
||||
}, [callId, phoneNumber, maxSize]);
|
||||
|
||||
return {
|
||||
firstItemOfHistory: historyData[0] || false,
|
||||
historyList: historyData.length > 1 ? historyData.slice(1) : false,
|
||||
isLoadingHistoryList: isLoading,
|
||||
errorHistoryList: hasError,
|
||||
};
|
||||
|
||||
fetchHistory();
|
||||
}, [callId, phoneNumber, maxSize]);
|
||||
|
||||
return {
|
||||
firstItemOfHistory: historyData[0] || false,
|
||||
historyList: historyData.length > 1 ? historyData.slice(1) : false,
|
||||
isLoadingHistoryList: isLoading,
|
||||
errorHistoryList: hasError,
|
||||
};
|
||||
};
|
||||
|
||||
export default useCallerHistory;
|
||||
|
||||
@@ -2,26 +2,18 @@ import { useContext } from "react";
|
||||
import { DataTableContext } from "@/lib/contexts/DataTable";
|
||||
|
||||
const useTableSetting = () => {
|
||||
const {
|
||||
filterData,
|
||||
setFilterData,
|
||||
sortData,
|
||||
setSortData,
|
||||
hideData,
|
||||
setHideData,
|
||||
isDirty,
|
||||
isAnyDirty,
|
||||
} = useContext(DataTableContext);
|
||||
return {
|
||||
filterData,
|
||||
setFilterData,
|
||||
sortData,
|
||||
setSortData,
|
||||
hideData,
|
||||
setHideData,
|
||||
isDirty,
|
||||
isAnyDirty,
|
||||
};
|
||||
const { filterData, setFilterData, sortData, setSortData, hideData, setHideData, isDirty, isAnyDirty } =
|
||||
useContext(DataTableContext);
|
||||
return {
|
||||
filterData,
|
||||
setFilterData,
|
||||
sortData,
|
||||
setSortData,
|
||||
hideData,
|
||||
setHideData,
|
||||
isDirty,
|
||||
isAnyDirty,
|
||||
};
|
||||
};
|
||||
|
||||
export default useTableSetting;
|
||||
|
||||
@@ -3,19 +3,19 @@ import useSWR from "swr";
|
||||
import useRequest from "./useRequest";
|
||||
|
||||
export const usePermissions = () => {
|
||||
const request = useRequest();
|
||||
const request = useRequest();
|
||||
|
||||
const fetcher = async (url) => {
|
||||
try {
|
||||
const response = await request(url);
|
||||
return response.data.data;
|
||||
} catch (error) {
|
||||
throw new Error();
|
||||
}
|
||||
};
|
||||
const fetcher = async (url) => {
|
||||
try {
|
||||
const response = await request(url);
|
||||
return response.data.data;
|
||||
} catch (error) {
|
||||
throw new Error();
|
||||
}
|
||||
};
|
||||
|
||||
return useSWR(GET_PERMISSIONS_ROUTE, fetcher, {
|
||||
keepPreviousData: true,
|
||||
dedupingInterval: 30000,
|
||||
});
|
||||
return useSWR(GET_PERMISSIONS_ROUTE, fetcher, {
|
||||
keepPreviousData: true,
|
||||
dedupingInterval: 30000,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -3,27 +3,27 @@ import { GET_PROVINCE_LISTS } from "@/core/utils/routes";
|
||||
import useRequest from "@/lib/hooks/useRequest";
|
||||
|
||||
const useProvinces = () => {
|
||||
const requestServer = useRequest();
|
||||
const [provinces, setProvinces] = useState([]);
|
||||
const [loadingProvinces, setLoadingProvinces] = useState(true);
|
||||
const [errorProvinces, setErrorProvinces] = useState(null);
|
||||
const requestServer = useRequest();
|
||||
const [provinces, setProvinces] = useState([]);
|
||||
const [loadingProvinces, setLoadingProvinces] = useState(true);
|
||||
const [errorProvinces, setErrorProvinces] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchProvinces = async () => {
|
||||
try {
|
||||
const response = await requestServer(`${GET_PROVINCE_LISTS}`);
|
||||
setProvinces(response.data.data);
|
||||
setLoadingProvinces(false);
|
||||
} catch (e) {
|
||||
setErrorProvinces(e);
|
||||
setLoadingProvinces(false);
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
const fetchProvinces = async () => {
|
||||
try {
|
||||
const response = await requestServer(`${GET_PROVINCE_LISTS}`);
|
||||
setProvinces(response.data.data);
|
||||
setLoadingProvinces(false);
|
||||
} catch (e) {
|
||||
setErrorProvinces(e);
|
||||
setLoadingProvinces(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchProvinces();
|
||||
}, []);
|
||||
fetchProvinces();
|
||||
}, []);
|
||||
|
||||
return { provinces, loadingProvinces, errorProvinces };
|
||||
return { provinces, loadingProvinces, errorProvinces };
|
||||
};
|
||||
|
||||
export default useProvinces;
|
||||
|
||||
@@ -5,62 +5,58 @@ import { useAuth } from "../contexts/auth";
|
||||
import { useSidebarBadge } from "./useSidebarBadge";
|
||||
|
||||
const defaultOptions = {
|
||||
data: {},
|
||||
requestOptions: {
|
||||
headers: {},
|
||||
},
|
||||
notificationShow: true,
|
||||
notificationSuccess: false,
|
||||
notificationFailed: true,
|
||||
hasSidebarUpdate: false,
|
||||
data: {},
|
||||
requestOptions: {
|
||||
headers: {},
|
||||
},
|
||||
notificationShow: true,
|
||||
notificationSuccess: false,
|
||||
notificationFailed: true,
|
||||
hasSidebarUpdate: false,
|
||||
};
|
||||
|
||||
const useRequest = (initOptions) => {
|
||||
const _options = Object.assign({}, defaultOptions, initOptions);
|
||||
const _options = Object.assign({}, defaultOptions, initOptions);
|
||||
|
||||
const { mutate: sidebarUpdate } = useSidebarBadge({
|
||||
enable: _options.hasSidebarUpdate,
|
||||
});
|
||||
const { logout } = useAuth();
|
||||
const { mutate: sidebarUpdate } = useSidebarBadge({
|
||||
enable: _options.hasSidebarUpdate,
|
||||
});
|
||||
const { logout } = useAuth();
|
||||
|
||||
/**
|
||||
* Performs an HTTP request.
|
||||
* @param {string} url - The URL to send the request to.
|
||||
* @param {'get' | 'post' | 'put' | 'delete'} [method='get'] - HTTP method.
|
||||
* @param {object} [options] - Additional request options.
|
||||
* @returns {Promise<AxiosResponse>} - Axios response.
|
||||
*/
|
||||
return async (url = "", method = "get", options) => {
|
||||
const mergedOptions = Object.assign({}, _options, options);
|
||||
try {
|
||||
const response = await axios({
|
||||
url,
|
||||
method,
|
||||
data: method === "get" ? null : mergedOptions.data,
|
||||
withCredentials: true,
|
||||
...mergedOptions.requestOptions,
|
||||
});
|
||||
if (mergedOptions.hasSidebarUpdate) {
|
||||
if (method === "post" || method === "put" || method === "delete")
|
||||
sidebarUpdate();
|
||||
}
|
||||
successRequest(
|
||||
mergedOptions.notificationShow && mergedOptions.notificationSuccess,
|
||||
"request_data",
|
||||
);
|
||||
return response;
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
errorResponse(
|
||||
error.response,
|
||||
mergedOptions.notificationShow && mergedOptions.notificationFailed,
|
||||
"request_data",
|
||||
logout,
|
||||
);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Performs an HTTP request.
|
||||
* @param {string} url - The URL to send the request to.
|
||||
* @param {'get' | 'post' | 'put' | 'delete'} [method='get'] - HTTP method.
|
||||
* @param {object} [options] - Additional request options.
|
||||
* @returns {Promise<AxiosResponse>} - Axios response.
|
||||
*/
|
||||
return async (url = "", method = "get", options) => {
|
||||
const mergedOptions = Object.assign({}, _options, options);
|
||||
try {
|
||||
const response = await axios({
|
||||
url,
|
||||
method,
|
||||
data: method === "get" ? null : mergedOptions.data,
|
||||
withCredentials: true,
|
||||
...mergedOptions.requestOptions,
|
||||
});
|
||||
if (mergedOptions.hasSidebarUpdate) {
|
||||
if (method === "post" || method === "put" || method === "delete") sidebarUpdate();
|
||||
}
|
||||
successRequest(mergedOptions.notificationShow && mergedOptions.notificationSuccess, "request_data");
|
||||
return response;
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
errorResponse(
|
||||
error.response,
|
||||
mergedOptions.notificationShow && mergedOptions.notificationFailed,
|
||||
"request_data",
|
||||
logout
|
||||
);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export default useRequest;
|
||||
|
||||
@@ -3,27 +3,27 @@ import { GET_ROLE_LISTS } from "@/core/utils/routes";
|
||||
import useRequest from "@/lib/hooks/useRequest";
|
||||
|
||||
const useRoles = () => {
|
||||
const requestServer = useRequest();
|
||||
const [roles, setRoles] = useState([]);
|
||||
const [loadingRoles, setLoadingRoles] = useState(true);
|
||||
const [errorRoles, setErrorRoles] = useState(null);
|
||||
const requestServer = useRequest();
|
||||
const [roles, setRoles] = useState([]);
|
||||
const [loadingRoles, setLoadingRoles] = useState(true);
|
||||
const [errorRoles, setErrorRoles] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchRoles = async () => {
|
||||
try {
|
||||
const response = await requestServer(`${GET_ROLE_LISTS}`);
|
||||
setRoles(response.data.data);
|
||||
setLoadingRoles(false);
|
||||
} catch (e) {
|
||||
setErrorRoles(e);
|
||||
setLoadingRoles(false);
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
const fetchRoles = async () => {
|
||||
try {
|
||||
const response = await requestServer(`${GET_ROLE_LISTS}`);
|
||||
setRoles(response.data.data);
|
||||
setLoadingRoles(false);
|
||||
} catch (e) {
|
||||
setErrorRoles(e);
|
||||
setLoadingRoles(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchRoles();
|
||||
}, []);
|
||||
fetchRoles();
|
||||
}, []);
|
||||
|
||||
return { roles, loadingRoles, errorRoles };
|
||||
return { roles, loadingRoles, errorRoles };
|
||||
};
|
||||
|
||||
export default useRoles;
|
||||
|
||||
@@ -3,21 +3,21 @@ import axios from "axios";
|
||||
import useSWR from "swr";
|
||||
|
||||
export const useSidebarBadge = ({ enable = true }) => {
|
||||
const fetcher = async (url) => {
|
||||
try {
|
||||
const response = await axios({
|
||||
url,
|
||||
method: "get",
|
||||
withCredentials: true,
|
||||
});
|
||||
return response.data.data;
|
||||
} catch (error) {
|
||||
throw new Error();
|
||||
}
|
||||
};
|
||||
const fetcher = async (url) => {
|
||||
try {
|
||||
const response = await axios({
|
||||
url,
|
||||
method: "get",
|
||||
withCredentials: true,
|
||||
});
|
||||
return response.data.data;
|
||||
} catch (error) {
|
||||
throw new Error();
|
||||
}
|
||||
};
|
||||
|
||||
return useSWR(enable ? GET_SIDEBAR_BADGE_ROUTE : "", fetcher, {
|
||||
keepPreviousData: true,
|
||||
dedupingInterval: 30000,
|
||||
});
|
||||
return useSWR(enable ? GET_SIDEBAR_BADGE_ROUTE : "", fetcher, {
|
||||
keepPreviousData: true,
|
||||
dedupingInterval: 30000,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -2,9 +2,8 @@ import { useContext } from "react";
|
||||
import { TableSettingContext } from "../contexts/tableSetting";
|
||||
|
||||
const useTableSetting = () => {
|
||||
const { settingStore, hideAction, sortAction, filterAction, resetAction } =
|
||||
useContext(TableSettingContext);
|
||||
return { settingStore, hideAction, sortAction, filterAction, resetAction };
|
||||
const { settingStore, hideAction, sortAction, filterAction, resetAction } = useContext(TableSettingContext);
|
||||
return { settingStore, hideAction, sortAction, filterAction, resetAction };
|
||||
};
|
||||
|
||||
export default useTableSetting;
|
||||
|
||||
Reference in New Issue
Block a user