hello vit/tailwind standard architect

shayestan
negin 2 months ago
commit 09070ffda8
  1. 22
      .eslintrc.cjs
  2. 24
      .gitignore
  3. 8
      README.md
  4. 14
      index.html
  5. 9
      jsconfig.json
  6. 7877
      package-lock.json
  7. 51
      package.json
  8. 6
      postcss.config.js
  9. BIN
      public/font/1.ttf
  10. BIN
      public/font/2.ttf
  11. BIN
      public/font/3.ttf
  12. BIN
      public/font/4.ttf
  13. BIN
      public/font/5.ttf
  14. BIN
      public/font/6.ttf
  15. BIN
      public/font/7.ttf
  16. BIN
      public/font/8.ttf
  17. BIN
      public/font/9.ttf
  18. 2796
      public/font/icons.js
  19. BIN
      public/font/iconsax.eot
  20. 5763
      public/font/iconsax.svg
  21. BIN
      public/font/iconsax.woff
  22. BIN
      public/font/iconsax2.ttf
  23. BIN
      public/font/iconsax2.woff
  24. BIN
      public/font/iconsax2_.ttf
  25. BIN
      public/images/logo.png
  26. 29074
      public/style.css
  27. 63
      public/tailwind.js
  28. 1
      public/vite.svg
  29. 229
      src/App.jsx
  30. 55
      src/App.scss
  31. 27
      src/components/BottomSheet.jsx
  32. 247
      src/components/Button.jsx
  33. 166
      src/components/Dialog.jsx
  34. 80
      src/components/ErrorBoundary.jsx
  35. 11
      src/components/Footer.jsx
  36. 30
      src/components/Icon.jsx
  37. 9
      src/components/Input.jsx
  38. 36
      src/components/Loading.jsx
  39. 65
      src/components/Theme.jsx
  40. 23
      src/components/Toast.jsx
  41. 20
      src/config.js
  42. 3793
      src/icons.js
  43. 29095
      src/iconsax.css
  44. 66
      src/index.css
  45. 111
      src/main.jsx
  46. 21
      src/pages/landing.jsx
  47. 77
      src/redux/actions/admin.js
  48. 21
      src/redux/actions/audit.js
  49. 73
      src/redux/actions/auto.js
  50. 37
      src/redux/actions/book.js
  51. 43
      src/redux/actions/certificate.js
  52. 35
      src/redux/actions/comment.js
  53. 30
      src/redux/actions/config.js
  54. 17
      src/redux/actions/content.js
  55. 17
      src/redux/actions/craft.js
  56. 9
      src/redux/actions/documents.js
  57. 19
      src/redux/actions/edu.js
  58. 19
      src/redux/actions/faq.js
  59. 122
      src/redux/actions/file.js
  60. 89
      src/redux/actions/healthCard.js
  61. 38
      src/redux/actions/index.js
  62. 49
      src/redux/actions/inspection.js
  63. 13
      src/redux/actions/map.js
  64. 45
      src/redux/actions/menu.js
  65. 42
      src/redux/actions/network copy.js
  66. 47
      src/redux/actions/network.js
  67. 9
      src/redux/actions/offCode.js
  68. 8
      src/redux/actions/otp.js
  69. 35
      src/redux/actions/process.js
  70. 51
      src/redux/actions/product.js
  71. 59
      src/redux/actions/publicApi.js
  72. 48
      src/redux/actions/report.js
  73. 6
      src/redux/actions/role.js
  74. 40
      src/redux/actions/roleFunction.js
  75. 118
      src/redux/actions/task.js
  76. 17
      src/redux/actions/transport.js
  77. 66
      src/redux/actions/unit.js
  78. 155
      src/redux/actions/user.js
  79. 34
      src/redux/actions/userAddress.js
  80. 82
      src/redux/actions/userFactor.js
  81. 27
      src/redux/actions/userFavorite.js
  82. 59
      src/redux/actions/userProduct.js
  83. 42
      src/redux/actions/waterSupply.js
  84. 13
      src/redux/actions/workFlow.js
  85. 7
      src/redux/index.js
  86. 241
      src/redux/proxy.js
  87. 146
      src/redux/reducers/admin.js
  88. 40
      src/redux/reducers/audit.js
  89. 186
      src/redux/reducers/auto.js
  90. 127
      src/redux/reducers/book.js
  91. 37
      src/redux/reducers/catalog.js
  92. 51
      src/redux/reducers/certificate.js
  93. 37
      src/redux/reducers/comment.js
  94. 188
      src/redux/reducers/config.js
  95. 31
      src/redux/reducers/content.js
  96. 23
      src/redux/reducers/craft.js
  97. 17
      src/redux/reducers/documents.js
  98. 57
      src/redux/reducers/faq.js
  99. 87
      src/redux/reducers/file.js
  100. 19
      src/redux/reducers/guide.js
  101. Some files were not shown because too many files have changed in this diff Show More

@ -0,0 +1,22 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:react/jsx-runtime',
'plugin:react-hooks/recommended',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
settings: { react: { version: '18.2' } },
plugins: ['react-refresh'],
rules: {
'react/jsx-no-target-blank': 'off',
"react/prop-types": "off",
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
}

24
.gitignore vendored

@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

@ -0,0 +1,8 @@
# React + Vite
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh

@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
<script type="module" src="/tailwind.js"></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>

@ -0,0 +1,9 @@
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"~/*": ["src/*"],
"@/*": ["public/*"]
}
}
}

7877
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,51 @@
{
"name": "porseline",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"@vitejs/plugin-react-refresh": "^1.3.6",
"axios": "^1.7.2",
"bcryptjs": "^2.4.3",
"framer-motion": "^11.3.8",
"leaflet": "^1.9.4",
"react": "^18.3.1",
"react-contenteditable": "^3.3.7",
"react-dom": "^18.3.1",
"react-iconly": "^2.2.10",
"react-loading": "^2.0.3",
"react-modern-drawer": "^1.3.1",
"react-redux": "^9.1.2",
"react-router-dom": "^6.25.1",
"react-spring-bottom-sheet": "^3.4.1",
"react-toastify": "^10.0.5",
"react-topbar-progress-indicator": "^4.1.1",
"redux": "^5.0.1",
"redux-devtools-extension": "^2.13.9",
"redux-thunk": "^3.1.0",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-monaco-editor": "^1.1.0",
"vite-plugin-pages": "^0.32.3",
"vite-plugin-pwa": "^0.20.0"
},
"devDependencies": {
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-react": "^4.3.1",
"autoprefixer": "^10.4.19",
"eslint": "^8.57.0",
"eslint-plugin-react": "^7.34.3",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-refresh": "^0.4.7",
"postcss": "^8.4.39",
"sass": "^1.77.8",
"tailwindcss": "^3.4.6",
"vite": "^5.3.4"
}
}

@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 4.2 MiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -0,0 +1,229 @@
// import "./App.css";
// import Input from "./component/Input/Input";
// import Landing from "./component/Landing/Landing";
// function App() {
// return (
// <div className="flex flex-col w-full items-center justify-around h-screen p-4 mx-auto bg-gradient-to-r from-purple-600 to-blue-600">
// <Landing/>
// {/* <Input
// type="text"
// placeholder=" نام خود را وارد کنید ..."
// className="w-[25rem] h-10 p-2 text-gray-600 outline-none rounded-lg"
// />
// <button
// type="submit"
// className="cursor-pointer w-16 p-4 bg-green-500 outline-none rounded-lg text-yellow-100"
// >
// بعدی
// </button> */}
// </div>
// );
// }
// export default App;
////////////////////////////////default
import { Suspense, useEffect, useMemo } from "react";
import { config, menu, user } from "~/redux/actions";
import { useLocation, useNavigate, useRoutes } from "react-router-dom";
import Dialog from "~/components/Dialog";
import ErrorBoundary from "~/components/ErrorBoundary";
// import Footer from "~/components/Footer";
// import Header from "~/components/Header";
import Loading from "~/components/Loading";
// import Menu from "~/components/Menu";
import Theme from "~/components/Theme";
import Toast from "~/components/Toast";
import appconfig from "./config";
import { connect } from "react-redux";
import { motion } from "framer-motion";
import routes from "~react-pages";
// import ChangesLog from "./ChangesLog";
//router
// import { BrowserRouter as Router } from "react-router-dom";
if (appconfig.base)
routes.forEach((e) => {
e.path = (appconfig.base + "/" + e.path).replace("//", "/");
});
const pageVariants = {
initial: { opacity: 0 },
in: { opacity: 1 },
out: { opacity: 0 },
};
const pageTransition = {
type: "slide",
ease: "linear",
duration: 0.5,
};
const Root = ({
user,
dialog,
menuList,
setDialog,
getMenuList,
themeName,
device,
setDevice,
ActiveRoleId,
setActiveRole,
setBottomSheet,
switchRole,
userRoleId,
hasMenu,
hasHeader,
setMenu,
setTheme,
themeColors,
login,
logout,
}) => {
const queryParams = Object.fromEntries(
new URLSearchParams(window.location.search)
);
const navigate = useNavigate();
const location = useLocation();
// FIXME
useMemo(async () => {
setMenu(true);
if (user) getMenuList();
}, [user, ActiveRoleId]);
useEffect(() => {
if (!location.pathname.includes("wiki") && user && menuList.length < 2)
getMenuList();
}, [location.pathname]);
let multyRole = user?.userRoles?.length > 1;
// console.log({ Location, user, ActiveRoleId, multyRole });
if (user && user.passwordHealth?.message) {
let Location = location.pathname.split("/")[appconfig.base ? 2 : 1];
if (!Location.includes("renewPassword"))
navigate(appconfig.base + "/renewPassword", { replace: true });
}
let Location = location.pathname.split("/")[appconfig.base ? 2 : 1];
const publics = ["landing"];
const publicsOnly = ["login", "guilds", "clients", "help"];
const isPublicOnly = publicsOnly.includes(Location);
const isPublic = publics.includes(Location);
useEffect(() => {
if (!queryParams.code && !user && ActiveRoleId != undefined) {
login();
} else {
// else if (!user && !ActiveRoleId) await logout();
if (!user && !isPublic && !isPublicOnly) {
if (!location.pathname.includes("logout"))
if (typeof location.search === "string")
window.sessionStorage.setItem(
"next",
location.pathname + (location.search || "")
);
navigate(appconfig.base + "/login", {
replace: false,
});
} else if (
Location != "logout" &&
user &&
ActiveRoleId == undefined &&
multyRole
) {
navigate(appconfig.base + "/switchRole", { replace: true });
} else if (user && isPublicOnly) {
let next = window.sessionStorage.getItem("next") || "/";
window.sessionStorage.removeItem("next");
navigate(appconfig.base + next);
}
}
}, [Location, user]);
return (
<Theme
themeColors={themeColors}
themeName={themeName}
device={device}
setDevice={setDevice}
>
<div className="flex flex-row w-full max-w-screen h-full bg-background">
{/* {hasMenu && (
<Menu
device={device}
user={user}
setDialog={setDialog}
menuList={menuList}
setActiveRole={setActiveRole}
switchRole={switchRole}
userRoleId={userRoleId}
/>
)} */}
<div className="flex flex-col flex-1 prettyScroll overflow-y-auto">
{/* {hasHeader && (
<Header
themeColors={themeColors}
setTheme={setTheme}
themeName={themeName}
user={user}
location={location}
setBottomSheet={setBottomSheet}
/>
)} */}
<section className="flex flex-col flex-1 bg-background">
<Suspense fallback={<Loading />}>
<motion.div
key={location.pathname}
initial="initial"
animate="in"
variants={pageVariants}
transition={pageTransition}
className="w-full h-screen flex-1 flex"
>
<ErrorBoundary>{useRoutes(routes)}</ErrorBoundary>
</motion.div>
</Suspense>
</section>
{/* <Footer user={user} location={location} /> */}
</div>
</div>
{/* <ChangesLog setDialog={setDialog} user={user} /> */}
<Dialog setDialog={setDialog} dialog={dialog} />
<Toast />
</Theme>
);
};
export default connect(
(state) => ({
user: state.user.status,
dialog: state.config.dialog,
bottomSheet: state.config.bottomSheet,
menuList: state.menu.list,
themeName: state.config.themeName,
device: state.config.device,
hasMenu: state.config.menu,
hasHeader: state.config.header,
ActiveRoleId: state.user.ActiveRoleId,
userRoleId: state.user.userRoleId,
themeColors: state.config.themeColors,
}),
{
setDialog: config.setDialog,
setBottomSheet: config.setBottomSheet,
getMenuList: menu.list,
setDevice: config.setDevice,
setActiveRole: user.setActiveRoleId,
switchRole: user.switchRole,
setMenu: config.setMenu,
setTheme: config.setTheme,
getProfile: user.getProfile,
login: user.login,
logout: user.logout,
}
)(Root);

@ -0,0 +1,55 @@
@import "./iconsax.css";
#root {
/* max-width: 1280px; */
margin: 0 auto;
direction: rtl;
}
@font-face {
font-family: iransans;
src: url("/font/3.ttf");
}
@font-face {
font-family: font-1;
src: url("/font/1.ttf");
}
@font-face {
font-family: font-2;
src: url("/font/2.ttf");
}
@font-face {
font-family: font-3;
src: url("/font/3.ttf");
}
@font-face {
font-family: font-4;
src: url("/font/4.ttf");
}
@font-face {
font-family: font-5;
src: url("/font/5.ttf");
}
@font-face {
font-family: font-6;
src: url("/font/6.ttf");
}
@font-face {
font-family: font-7;
src: url("/font/7.ttf");
}
@font-face {
font-family: font-8;
src: url("/font/8.ttf");
}
@font-face {
font-family: font-9;
src: url("/font/9.ttf");
}

@ -0,0 +1,27 @@
import { BottomSheet } from "react-spring-bottom-sheet";
const customBottomSheet = ({
className,
cancel,
hidden,
children,
height, //= window.innerHeight / 2,
}) => {
return (
<BottomSheet
className={className}
open={!hidden}
defaultSnap={height}
// blocking
onDismiss={cancel}
snapPoints={() => [
window.innerHeight / 6,
window.innerHeight / 2,
window.innerHeight * 0.95,
]}
>
{children}
</BottomSheet>
);
};
export default customBottomSheet;

@ -0,0 +1,247 @@
import React, { useEffect, useState, useRef } from "react";
import { useNavigate } from "react-router-dom";
import ContentEditable from "react-contenteditable";
//components
import Icon from "~/components/Icon";
import Loading from "~/components/Loading";
import appConfig from "~/config";
const { redirects } = appConfig;
const downloadUrl = (file_path) => {
var a = window.document.createElement("A");
a.href = file_path;
a.target = "_blank";
a.download = file_path.substr(file_path.lastIndexOf("/") + 1);
window.document.body.appendChild(a);
a.click();
window.document.body.removeChild(a);
};
const Button = ({
id,
badge,
tabIndex,
draggable,
onDragStart,
style,
text,
link,
icon,
iconColor,
iconSize,
iconSet,
iconClassName,
disabled,
scale,
surface,
title,
primary,
outline,
action,
loading: loading_,
className,
children,
textClassName,
progress,
dropdown,
hoverDropdown,
refAction = () => {},
ref,
editable,
onChange,
inputRef,
target,
badgeCalssName,
dropdownClassName,
dpClassName,
}) => {
const dropdownRef = useRef();
if (editable) {
link = undefined;
action = undefined;
}
if (ref && !refAction) refAction = ref;
const navigate = useNavigate();
const [menu, setMenu] = useState(false);
const [loading, setLoading] = useState(loading_);
const outsideClick = (event) => {
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
event.preventDefault();
setMenu(false);
}
};
useEffect(() => {
if (menu) document.addEventListener("mousedown", outsideClick);
else document.removeEventListener("mousedown", outsideClick);
}, [menu]);
useEffect(() => {
setLoading(loading_);
}, [loading_]);
className = className || "";
if (outline)
className += " border border-primary text-primary hover:bg-surface";
if (primary) {
if (!className.includes("bg-"))
className += " font-6 bg-primary hover:brightness-90";
className += ` text-primaryText `;
// primaryColor = "text-primaryText";
}
if (surface) className += ` bg-surface text-surfaceText `;
if (disabled) className += ` grayscale opacity-80`;
if (scale) className += ` hover:scale-105`;
if (!className.includes("justify")) className += ` justify-center`;
if (!className.includes("rounded")) className += ` rounded-md`;
const doAction = async (e) => {
setLoading(true);
if (!menu && action) await action(e);
if (dropdown) setMenu(true);
setLoading(false);
};
let timer;
let Container = !dropdown ? React.Fragment : DropdownContainer;
return (
<Container>
<button
id={id || null}
tabIndex={tabIndex}
draggable={draggable}
onDragStart={onDragStart}
style={style || {}}
ref={inputRef}
title={title || text}
className={`${className} flex text-sm my-2 py-2 gap-2 transition-all items-center `}
onMouseEnter={
hoverDropdown
? () =>
(timer = setTimeout(() => {
setMenu(true);
}, 100))
: null
}
onMouseLeave={
hoverDropdown
? () =>
(timer = setTimeout(() => {
setMenu(false);
}, 100))
: null
}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
if (!disabled && !loading) {
if (dropdown || action) doAction(e);
if (redirects[link]) link = redirects[link];
if (typeof link == "string")
if (target == "download") downloadUrl(link);
else if (link.includes("http") && target == "_self")
window.location.href = link;
else if (link.includes("http") || link.slice(0, 4) == "data") {
let w = window.open(link, target || "_blank", true);
if (link.slice(0, 4) == "data") {
let image = new Image();
image.src = link;
setTimeout(function () {
w.document.write(image.outerHTML);
}, 0);
}
} else if (link.includes("#"))
window.document.querySelector(link).scrollIntoView({
behavior: "smooth",
block: "start",
inline: "nearest",
});
else {
if (window.event.ctrlKey || (target && target != "_self"))
window.open(
!appConfig.base ? link : "/" + appConfig.base + link,
target || "_blank"
);
else
navigate(
!appConfig.base ? link : "/" + appConfig.base + link
);
}
else if (link) navigate(link);
}
}}
>
{loading && progress > 0 && (
<div className={`${textClassName}`}>{progress}%</div>
)}
{loading ? (
<Loading
text=""
textClassName={"text-[white]"}
color={primary ? "white" : ""}
size={10}
/>
) : null}
{icon && (
<Icon
name={icon}
color={
iconColor || (primary && "var(--primaryText)") || "var(--primary)"
}
size={iconSize}
variant={iconSet}
className={
(editable ? "" : text ? "" : "flex-1 ") + (iconClassName || "")
}
/>
)}
{editable ? (
<ContentEditable
html={text}
onChange={(e) => onChange(e.target.value)}
className={!text ? " w-1 rounded " : "min-w-10 "}
/>
) : (
text &&
text != " " && <div className={`${textClassName}`}>{text}</div>
)}
{badge ? (
<div className="relative ltr -left-1">
<span
className={
badgeCalssName +
` bg-error text-primaryText text-[12px] px-2 absolute rtl bottom-2 rounded-lg`
}
>
{badge}
</span>
</div>
) : null}
{!dropdown ? children : null}
</button>
{dropdown ? (
<div
ref={dropdownRef}
className={
dpClassName + " absolute ltr:left-0 rtl:right-0 translate-x-0 "
}
>
<div
id="dropdown"
className={`${
menu ? "" : "hidden"
} min-w-fit px-2 absolute text-xs list-none rounded-lg divide-gray-100 shadow-xl bg-background my-0 py-0 ${dropdownClassName}`}
onMouseLeave={() => setMenu(false)}
onMouseEnter={() => clearTimeout(timer)}
>
{children}
</div>
</div>
) : null}
</Container>
);
};
const DropdownContainer = ({ children }) => {
return <div className="">{children}</div>;
};
export default Button;

@ -0,0 +1,166 @@
import React,{useState} from "react";
//components
import Button from "~/components/Button";
import Icon from "~/components/Icon";
import BottomSheet from "~/components/BottomSheet";
export const Dialog = ({ dialog, setDialog }) => {
const [boxAnimation, setBoxAnimation] = useState(false);
if (!dialog.open) return null;
let {
text,
type = "confirm",
accept,
children,
className,
action,
cancel,
loading,
progress,
footer,
icon,
iconColor,
} = dialog;
accept = accept || action;
React.useEffect(() => {
setTimeout(() => {
setBoxAnimation(true);
}, 200);
return () => {
setBoxAnimation(false);
};
}, []);
const exit = React.useCallback(
(e) => {
cancel && cancel();
setDialog({ ...dialog, open: !dialog.open });
e.stopPropagation();
},
[dialog, setDialog]
);
const acceptFunc = React.useCallback(() => {
accept();
setDialog({ ...dialog, open: !dialog.open });
// e.stopPropagation();
}, [dialog, setDialog, accept]);
return (
<>
<div
className=" hidden md:flex w-screen h-full fixed top-0 right-0 bg-surfaceDark bg-opacity-10 backdrop-filter backdrop-blur-lg justify-center items-center"
style={{ zIndex: 70 }}
onClick={(e) => exit(e)}
>
<div
className={`flex flex-col items-center bg-surfaceLight bg-opacity-100 text-surfaceText md:min-w-[500px] p-3 gap-2 rounded-md transition-all transform shadow ${
boxAnimation ? "scale-100" : "scale-0"
}`}
style={{ minWidth: 300 }}
onClick={(e) => e.stopPropagation()}
>
<div
className={`${className} text-tiny p-${
text ? 4 : 2
} text-gray-22 bg-surface rounded-md w-full leading-7`}
>
<div className="flex items-center w-full gap-2 justify-center">
{icon && <Icon name={icon} size={32} />} <span>{text}</span>
</div>
{children}
</div>
<div className="modal-footer w-full flex md:flex-row flex-col gap-1 justify-between ">
{footer && <div className="flex-1">{footer}</div>}
{type === "confirm" && (
<div className="flex gap-4 w-full">
<Button
text="تایید"
primary
action={acceptFunc}
className="flex-1 !my-0"
loading={loading}
progress={progress}
/>
<Button
text="انصراف"
outline
className="flex-1 !my-0"
action={exit}
/>
</div>
)}
{type === "alert" && (
<div className="flex gap-4 w-full">
<Button
text="تایید"
loading={loading}
progress={progress}
primary
className="flex-1 !my-0"
action={acceptFunc}
/>
</div>
)}
</div>
</div>
</div>
<BottomSheet
className={"md:hidden block h-fit"}
cancel={exit}
hidden={!dialog.open}
height={text ? 300 : (window.innerHeight * 2) / 3}
>
<div className="p-2 rtl">
<div className="flex items-center w-full gap-2 justify-center">
{icon && <Icon name={icon} size={32} color={iconColor} />}{" "}
<span>{text}</span>
</div>
{children}
</div>
<div className="flex gap-2 bg-opacity-100 ">
<div className="modal-footer absolute left-0 bottom-2 px-2 pt-2 gap-1 rtl w-full flex justify-between px-2 flex-col bg-background ">
{footer && <div>{footer}</div>}
<div className="modal-footer w-full flex md:flex-row flex-col gap-1 justify-between ">
{footer && <div className="flex-1">{footer}</div>}
{type === "confirm" && (
<div className="flex gap-4 w-full">
<Button
text="تایید"
primary
action={acceptFunc}
className="flex-1 !my-0"
loading={loading}
progress={progress}
/>
<Button
text="انصراف"
outline
className="flex-1 !my-0"
action={exit}
/>
</div>
)}
{type === "alert" && (
<div className="flex gap-4 w-full">
<Button
text="تایید"
loading={loading}
progress={progress}
primary
className="flex-1 !my-0"
action={acceptFunc}
/>
</div>
)}
</div>
</div>
</div>
</BottomSheet>
</>
);
};
export default Dialog;

@ -0,0 +1,80 @@
import React from "react";
import Button from "~/components/Button";
import { connect } from "react-redux";
import { publicApi } from "~/redux/actions";
import appConfig from "~/config";
const { version } = appConfig;
const agent = window.navigator.userAgent;
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { error: false };
}
static getDerivedStateFromError(error) {
return { error };
}
render() {
if (this.state.error) {
let errors = this.state.error.stack.split("\n");
if (errors[0].includes("dynamically imported")) {
window.location.reload(true);
return null;
} // .filter((e) => !e.includes("node_module"));
return (
<div className="w-full h-full">
<div className="border-error bg-surface text-error rounded-lg border flex-1 min-h-10 flex flex-col gap-2 p-3 m-3">
<div className="font-6"> خطای نمایشی</div>
<div className="ltr font-6">
متاسفانه برای نمایش اطلاعات این صفحه خطایی وجود دارد
{/* {errors[0].replace("ReferenceError:", "")} */}
</div>
{/* <hr />
{errors.slice(1).map((e, i) => (
<div key={i} className={"ltr text-xs"}>
{e}
</div>
))} */}
<hr />
<div className="flex flex-col md:flex-row-reverse gap-2 justify-start">
<Button
action={() =>
this.props.report({
error: this.state.error.stack,
version,
method: "UI",
path: window.location.pathname,
data: Object.fromEntries(
new URLSearchParams(window.location.search)
),
statusCode: 600,
agent,
duration: 0,
})
}
text="گزارش خطا"
primary
className="bg-error !my-0 px-2"
loading={this.props.loading}
/>
<Button
// outline
text="صفحه اصلی"
link={"/"}
className={"border border-error text-error !my-0 px-2"}
/>
</div>
</div>
</div>
);
}
return this.props.children;
}
}
export default connect(
(state) => ({
loading: state.publicApi.loading,
}),
{ report: publicApi.report }
)(ErrorBoundary);

@ -0,0 +1,11 @@
import React from "react";
import CopyRight from "~/components/CopyRight";
const Footer = ({ user, location }) => {
return (
<footer className={`${user ? "hidden" : ""} lg:flex flex-col w-full`}>
{/* <div className="flex bg-surface text-surfaceText">بخش فوتر</div> */}
<CopyRight image />
</footer>
);
};
export default Footer;

@ -0,0 +1,30 @@
import { Iconly } from "react-iconly";
import icons, { iconlyList } from "~/icons";
const Icon = ({ name, size = 24, variant, color, className, title }) => {
let primaryColor = "var(--primary)";
let iconSaxSet = new Set(icons);
if (iconlyList[name])
return (
<Iconly
size={size}
primaryColor={color || primaryColor}
name={name}
filled={variant == "bold" ? true : false}
stroke={variant || null}
className={className}
/>
);
if (iconSaxSet.has(name)) {
return (
<span
title={title}
className={`${className} ltr isax isax-${name}`}
style={{ fontSize: size, color: color, fontWeight: variant }}
/>
);
}
// console.log(name);
return <img src={name} alt={name} className={className} />;
};
export default Icon;

@ -0,0 +1,9 @@
function Input({ type, placeholder ,className}) {
return (
<div className="flex items-center justify-between ">
<input type={type} placeholder={placeholder} className={className} />
</div>
);
}
export default Input;

@ -0,0 +1,36 @@
import React from "react";
import TopBarProgress from "react-topbar-progress-indicator";
import Loading from "react-loading";
TopBarProgress.config({
barColors: {
0: "#3C58EA",
0.5: "#0dbe94",
1: "#3C58EA",
},
shadowBlur: 1,
});
const myLoading = ({ text, color, size, className, textClassName }) => {
size = size || 20;
color = color || "var(--primary)";
return (
<div
className={
"flex text-xs text-center text-surfaceText gap-3 justify-center my-5 " +
className
}
>
<Loading
color={color}
type="spin"
width={size + "px"}
height={size + "px"}
/>
<span className={`text-surfaceText ${textClassName} pt-1`}>
{typeof text == "string" ? text : "در حال پردازش و دریافت اطلاعات ..."}
</span>
<TopBarProgress />
</div>
);
};
export default myLoading;

@ -0,0 +1,65 @@
import _ from "lodash";
import { useMemo } from "react";
import { IconlyProvider } from "react-iconly";
import { useEffect } from "react";
const root = document.querySelector(":root");
function hexToRgb(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result
? [
parseInt(result[1], 16),
parseInt(result[2], 16),
parseInt(result[3], 16),
]
: [];
}
const Theme = ({ themeColors, children, themeName, device, setDevice }) => {
useEffect(() => {
const activeTheme = themeColors[themeName];
for (let k in activeTheme) root.style.setProperty(k, activeTheme[k]);
for (let k in activeTheme)
root.style.setProperty(
k + "RGB",
`${hexToRgb(activeTheme[k]).join(",")}`
);
window.localStorage.setItem("themeName", themeName);
}, [themeName]);
const checkSize = () => {
const width = window.innerWidth;
if (width <= 640) {
if (device !== "mobile") setDevice("mobile");
} else if (width <= 1024) {
if (device !== "tablet") setDevice("tablet");
} else {
if (device !== "desktop") setDevice("desktop");
}
document.documentElement.style.setProperty(
"--vh",
window.innerHeight * 0.01 + "px"
);
};
window.addEventListener("resize", _.debounce(checkSize, 300));
useMemo(checkSize, []);
return (
<div>
<IconlyProvider
set="outline"
primaryColor="#3C58EA"
secondaryColor="#ffffff"
size="medium "
>
<div
className={`w-screen real-height real-max-height flex flex-col lg:flex-row rtl overflow-hidden lg:py-0
}`}
>
{children}
</div>
</IconlyProvider>
</div>
);
};
export default Theme;

@ -0,0 +1,23 @@
import React from "react";
import { ToastContainer, Slide } from "react-toastify";
const Toast = () => {
return (
<React.Fragment>
<ToastContainer
position="bottom-left"
theme="colored"
autoClose={3000}
// hideProgressBar={true}
newestOnTop={true}
closeOnClick
rtl={true}
pauseOnFocusLoss
draggable
pauseOnHover
Progress="0.1"
transition={Slide}
/>
</React.Fragment>
);
};
export default Toast;

@ -0,0 +1,20 @@
const config = {
apiKey: "AIzaSyBBksq-Asxq2M4Ot-75X19IyrEYJqNBPcg",
authDomain: ["sameh.behdasht.gov.ir", "localhost:8000"],
testUrl: "https://sameh.behdasht.gov.ir/beta/api/v2/",
baseUrl: "https://sameh.behdasht.gov.ir/api/v2/",
title: "سامانه جامع سلامت الکترونیک محیط و حرفهای",
subtitle: "",
base: "",
TTL: 360,
redirects: {
"/task/inbox": "/task",
"/task/draft": "/task",
"/task/sender": "/task",
"/task/expired": "/task",
"/log/nationalId": "/healthcard/nationalId",
"/user/log": "/log/user",
"/healthCard/university_stats": "/healthcard/report",
},
};
export default config;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,66 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
background-image: linear-gradient(to right, var(--tw-gradient-stops)); color:white
}
/* a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body {
margin: 0;
display: flex;
align-items: center;
justify-content: space-around;
min-width: 320px;
min-height: 100vh;
} */
/*
h1 {
font-size: 3.2em;
line-height: 1.1;
}
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
} */
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}

@ -0,0 +1,111 @@
import React, { StrictMode } from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
//router
import { BrowserRouter as Router } from "react-router-dom";
//redux
import store from "~/redux/store";
import { Provider } from "react-redux";
//external css
import "./App.scss";
// import "./tailwind.js";
import "react-toastify/dist/ReactToastify.css";
import "react-modern-drawer/dist/index.css";
import "react-spring-bottom-sheet/dist/style.css";
import "leaflet/dist/leaflet.css";
// import "leaflet-draw/dist/leaflet.draw.css";
// import "react-orgchart/index.css";
// import "react-quill/dist/quill.core.css";
// import "react-quill/dist/quill.snow.css";
// import "./leaflet.min.css"
// import "./leaflet.min.css"
// if (tailwind == undefined) window.location.reload(true);
window.t = (i) => i;
setTimeout(() => {
tailwind.config = {
theme: {
colors: {
primary: "rgba(var(--primaryRGB) , var(--tw-bg-opacity,1))",
primaryLight: "rgba(var(--primaryLightRGB) , var(--tw-bg-opacity,1))",
primaryDark: "rgba(var(--primaryDarkRGB) , var(--tw-bg-opacity,1))",
secondary: "rgba(var(--secondaryRGB) , var(--tw-bg-opacity,1))",
secondaryDark: "rgba(var(--secondaryDarkRGB) , var(--tw-bg-opacity,1))",
secondaryLight:
"rgba(var(--secondaryLightRGB) , var(--tw-bg-opacity,1))",
surface: "rgba(var(--surfaceRGB) , var(--tw-bg-opacity,1))",
surfaceLight: "rgba(var(--surfaceLightRGB) , var(--tw-bg-opacity,1))",
surfaceDark: "rgba(var(--surfaceDarkRGB) , var(--tw-bg-opacity,1))",
success: "rgba(var(--successRGB) , var(--tw-bg-opacity,1))",
successText: "rgba(var(--successTextRGB) , var(--tw-bg-opacity,1))",
warning: "rgba(var(--warningRGB) , var(--tw-bg-opacity,1))",
warningText: "rgba(var(--warningTextRGB) , var(--tw-bg-opacity,1))",
error: "rgba(var(--errorRGB) , var(--tw-bg-opacity,1))",
primaryText: "var(--primaryText)",
secondaryText: "var(--secondaryText)",
background: "var(--background)",
backgroundText: "var(--backgroundText)",
surfaceText: "var(--surfaceText)",
surfaceBorder: "var(--surfaceBorder)",
info: "var(--info)",
infoText: "var(--infoText)",
errorText: "var(--errorText)",
borderColor: "var(--borderColor)",
backgroundBorder: "var(--backgroundBorder)",
},
fontFamily: {
1: ["font-1"],
2: ["font-2"],
3: ["font-3"],
4: ["font-4"],
5: ["font-5"],
6: ["font-6"],
7: ["font-7"],
8: ["font-8"],
9: ["font-9"],
},
},
};
}, 100);
const root = ReactDOM.createRoot(document.getElementById("root"));
// if (window.location.hostname == "localhost") {
if (!window.initialized) {
var onBeforeUnLoadEvent = false;
let counter = +window.localStorage.getItem("activeTabs") || 0;
window.localStorage.setItem("activeTabs", counter + 1);
window.initialized = true;
}
window.onunload = window.onbeforeunload = function (event) {
event.stopImmediatePropagation();
if (!onBeforeUnLoadEvent) {
onBeforeUnLoadEvent = true;
let counter = +window.localStorage.getItem("activeTabs");
if (counter > 0) window.localStorage.setItem("activeTabs", counter - 1);
if (counter == 1) {
window.localStorage.removeItem("activeTabs");
if (window.location.hostname == "sameh.barnamenegar.com") {
window.localStorage.removeItem("activeRoleId");
window.sessionStorage.removeItem("userData");
window.sessionStorage.removeItem("sessionId");
window.Axios.post("/user/logout", { timeout: true });
}
// return "نشست شما خاتمه پیدا کرد";
}
}
return null;
};
// }
root.render(
// <StrictMode>
<Router>
<Provider store={store}>
<App />
</Provider>
</Router>
// </StrictMode>
);

@ -0,0 +1,21 @@
import Button from "~/components/Button"
function Landing() {
return (
<div className='flex flex-col items-center w-full '>
<div className="flex items-center justify-center mb-6">
<img src="/images/logo.png" alt="flower" className="w-[250px] "/>
</div>
<div className="flex items-center justify-center">
<p className="font-4 rtl w-[500px] h-[150px] text-md text-gray-400">سلام و عرض ارادت !
این پرسشنامه شامل فرم مشخصات عمومی و ارزشیابی شخصی شما از مهارت ها و شامل 32 سوال فنی است و حدود 45 دقیقه ممکن است نیاز به زمان داشته باشد<br/>.
پیشاپیش از وقتی که میگذارید صمیمانه سپاسگزاریم و آرزوی بهترین ها را برای شما داریم .<br/>
بنا بر این اگر آماده یک چالش کوچک هستید </p>
</div>
<Button text="بیا شروع کنیم" className="px-4" primary/>
</div>
)
}
export default Landing

@ -0,0 +1,77 @@
import proxy from "~/redux/proxy";
const prefix = "admin/";
const admin = {
backupLink:
(data = {}) =>
async (dispatch) =>
await proxy.get("admin/backupLink", data, { dispatch }),
list:
(data = {}) =>
async (dispatch) => {
return await proxy.get(
prefix + data._service + "/",
{ ...data, schema: true },
{ dispatch }
);
},
info:
(data = {}) =>
async (dispatch) => {
return await proxy.get(prefix + data._service + "/" + data.id, data, {
dispatch,
});
},
add:
(data = {}) =>
async (dispatch) => {
return await proxy.post(prefix + data._service + "/add", data, {
dispatch,
});
},
delete:
(data = {}) =>
async (dispatch) => {
return await proxy.delete(
prefix + data._service + "/delete/" + data.id,
data,
{
dispatch,
}
);
},
update:
(data = {}) =>
async (dispatch) => {
return await proxy.put(
prefix + data._service + "/update/" + data.id,
data,
{
dispatch,
}
);
},
getExcelData: (data) => async (dispatch) => {
return await proxy.get(
prefix + data._service + "/list",
{ ...data, excelData: true },
{ dispatch }
);
},
clearExcelData:
(data = {}) =>
async (dispatch) => {
await dispatch({
type: prefix + data._service + "/clearExcelData",
data,
});
},
timeReport:
(data = {}) =>
async (dispatch) => {
return await proxy.get(prefix + data._service + "/timeReport", data, {
dispatch,
});
},
};
export default admin;

@ -0,0 +1,21 @@
import proxy from "../proxy";
const audit = {
check:
(data = {}) =>
async (dispatch) =>
await proxy.get("audit/check", data, { dispatch }),
revokeRole:
(data = {}) =>
async (dispatch) =>
await proxy.get("audit/revokeRole", data, { dispatch }),
revokeTask:
(data = {}) =>
async (dispatch) =>
await proxy.get("audit/revokeTask", data, { dispatch }),
multiAssign:
(data = {}) =>
async (dispatch) =>
await proxy.post("audit/multiAssign", data, { dispatch }),
};
export default audit;

@ -0,0 +1,73 @@
import proxy from "~/redux/proxy";
const prefix = "auto/";
const auto = {
list:
(data = {}) =>
async (dispatch) => {
return await proxy.get(
prefix + data._service + "/",
{ ...data, schema: true },
{ dispatch }
);
},
info:
(data = {}) =>
async (dispatch) => {
return await proxy.get(prefix + data._service + "/" + data.id, data, {
dispatch,
});
},
add:
(data = {}) =>
async (dispatch) => {
return await proxy.post(prefix + data._service + "/add", data, {
dispatch,
});
},
delete:
(data = {}) =>
async (dispatch) => {
return await proxy.delete(
prefix + data._service + "/delete/" + data.id,
data,
{
dispatch,
}
);
},
update:
(data = {}) =>
async (dispatch) => {
return await proxy.put(
prefix + data._service + "/update/" + data.id,
data,
{
dispatch,
}
);
},
getExcelData: (data) => async (dispatch) => {
return await proxy.get(
prefix + data._service + "/",
{ ...data, excelData: true },
{ dispatch }
);
},
clearExcelData:
(data = {}) =>
async (dispatch) => {
await dispatch({
type: prefix + data._service + "/clearExcelData",
data,
});
},
timeReport:
(data = {}) =>
async (dispatch) => {
return await proxy.get(prefix + data._service + "/timeReport", data, {
dispatch,
});
},
};
export default auto;

@ -0,0 +1,37 @@
import proxy from "../proxy";
const book = {
list:
(data = {}) =>
async (dispatch) =>
await proxy.get("book/list", data, { dispatch }),
info:
(data = {}) =>
async (dispatch) =>
await proxy.get("book/info", data, { dispatch }),
update:
(data = {}, data2 = {}) =>
async (dispatch) => {
return await proxy.put("book/update", data);
return await proxy.get("book/list", data2, { dispatch });
},
add:
(data = {}, data2 = {}) =>
async (dispatch) => {
return await proxy.post("book/add", data);
return await proxy.get("book/list", data2, { dispatch });
},
del:
(data = {}, data2 = {}) =>
async (dispatch) => {
return await proxy.delete("book/delete", data);
return await proxy.get("book/list", data2, { dispatch });
},
searchBook: (data) => async (dispatch) => {
dispatch({ type: "book/search", data: data });
},
filterBook: (data) => async (dispatch) => {
dispatch({ type: "book/filter", data: data });
},
};
export default book;

@ -0,0 +1,43 @@
import proxy from "~/redux/proxy";
const certificate = {
list:
(data = {}) =>
async (dispatch) =>
await proxy.get("certificate/list", data, { dispatch }),
add:
(data = {}) =>
async (dispatch) =>
await proxy.post("certificate/add", data, { dispatch }),
healthQualification_start:
(data = {}) =>
async (dispatch) =>
await proxy.post("certificate/healthQualification/start", data, {
dispatch,
}),
freeAuditRegistration_start:
(data = {}) =>
async (dispatch) =>
await proxy.post("certificate/freeAuditRegistration/start", data, {
dispatch,
}),
certifiedGuildAddUnitStart:
(data = {}) =>
async (dispatch) =>
await proxy.post("certificate/certifiedGuildAddUnitStart", data, {
dispatch,
}),
freeAuditAddUnitStart:
(data = {}) =>
async (dispatch) =>
await proxy.post("certificate/freeAuditAddUnitStart", data, {
dispatch,
}),
checkConflict:
(data = {}) =>
async (dispatch) =>
await proxy.get("certificate/checkConflict", data, {
dispatch,
}),
};
export default certificate;

@ -0,0 +1,35 @@
import proxy from "~/redux/proxy";
const comment = {
list:
(data = {}) =>
async (dispatch) => {
return await proxy.get("comment/list", data, { dispatch });
},
info:
(data = {}) =>
async (dispatch) => {
return await proxy.get("comment/info", data, { dispatch });
},
add:
(data = {}) =>
async (dispatch) => {
return await proxy.post("comment/add", data, { dispatch });
},
homePage:
(data = {}) =>
async (dispatch) => {
return await proxy.get("comment/homePage", data, { dispatch });
},
delete:
(data = {}) =>
async (dispatch) => {
return await proxy.delete("comment/delete", data, { dispatch });
},
update:
(data = {}) =>
async (dispatch) => {
return await proxy.put("comment/update", data, { dispatch });
},
};
export default comment;

@ -0,0 +1,30 @@
const config = {
setDialog:
(data = {}) =>
async (dispatch) => {
await dispatch({ type: "config/setDialog", data });
},
setBottomSheet:
(data = {}) =>
async (dispatch) =>
await dispatch({ type: "config/setBottomSheet", data }),
setMenu:
(data = {}) =>
async (dispatch) =>
await dispatch({ type: "config/setMenu", data }),
setHeader:
(data = {}) =>
async (dispatch) =>
await dispatch({ type: "config/setHeader", data }),
setTheme: (data) => async (dispatch) =>
await dispatch({ type: "config/setTheme", data }),
addTheme: (data) => async (dispatch) =>
await dispatch({ type: "config/addTheme", data }),
deleteTheme: (data) => async (dispatch) =>
await dispatch({ type: "config/deleteTheme", data }),
setDevice: (data) => async (dispatch) =>
await dispatch({ type: "config/setDevice", data }),
};
export default config;

@ -0,0 +1,17 @@
import proxy from "~/redux/proxy";
const content = {
list:
(data = {}) =>
async (dispatch) =>
await proxy.get("content/list", data, { dispatch }),
add:
(data = {}) =>
async (dispatch) =>
await proxy.post("content/add", data, { dispatch }),
info:
(data = {}) =>
async (dispatch) =>
await proxy.get("content/info", data, { dispatch }),
};
export default content;

@ -0,0 +1,17 @@
import proxy from "../proxy";
const craft = {
add:
(data = {}) =>
async (dispatch) =>
await proxy.post("layout/add", data, { dispatch }),
get:
(data = {}) =>
async (dispatch) =>
await proxy.get("layout/info", data, { dispatch }),
update:
(data = {}) =>
async (dispatch) =>
await proxy.put("layout/update", data, { dispatch }),
};
export default craft;

@ -0,0 +1,9 @@
import proxy from "../proxy";
const documents = {
list:
(data = {}) =>
async (dispatch) =>
await proxy.post("sync/documentDataModel", data, { dispatch }),
};
export default documents;

@ -0,0 +1,19 @@
import proxy from "~/redux/proxy";
const faq = {
list:
(data = {}) =>
async (dispatch) =>
await proxy.get("faq/list", data, { dispatch }),
register:
(data = {}) =>
async (dispatch) =>
await proxy.post("faq/add", data, { dispatch }),
selectFaq:
(data = {}) =>
async (dispatch) =>
await dispatch({ type: "faq/selectFaq", data: data }),
searchFaq: (data) => async (dispatch) =>
await dispatch({ type: "faq/search", data: data }),
};
export default faq;

@ -0,0 +1,19 @@
import proxy from "~/redux/proxy";
const faq = {
list:
(data = {}) =>
async (dispatch) =>
await proxy.get("faq/list", data, { dispatch }),
add:
(data = {}) =>
async (dispatch) =>
await proxy.post("faq/add", data, { dispatch }),
selectFaq:
(data = {}) =>
async (dispatch) =>
await dispatch({ type: "faq/selectFaq", data: data }),
searchFaq: (data) => async (dispatch) =>
await dispatch({ type: "faq/search", data: data }),
};
export default faq;

@ -0,0 +1,122 @@
import proxy from "~/redux/proxy";
const extToMimes = {
jpg: "image/jpeg",
png: "image/png",
mp4: "video/mp4",
doc: "application/msword",
bmp: "image/bmp",
docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
mp3: "audio/mpeg",
pdf: "application/pdf",
zip: "application/zip",
rar: "application/vnd.rar",
};
const headers = {
"504B0304": "application/zip",
25504446: "application/pdf",
"504b34":
"application/x-zip-compressed|application/vnd.openxmlformats-officedocument.wordprocessingml.document|application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"89504e47": "image/png",
ffd8ffe0: "image/jpeg",
ffd8ffe1: "image/jpeg",
ffd8ffe2: "image/jpeg",
ffd8ffe3: "image/jpeg",
ffd8ffe8: "image/jpeg",
47494638: "image/gif",
d0cf11e0: "application/msword",
"6674797069736F6D": "video/mp4",
494433: "audio/mpeg",
"526172211A0700": "application/vnd.rar",
"526172211A070100": "application/vnd.rar",
"424D": "image/bmp",
"223f636f": "text/csv",
};
function getMimeType(file, callback) {
const fileReader = new FileReader();
fileReader.onloadend = function (event) {
let mimeType = "";
const arr = new Uint8Array(event.target.result).subarray(0, 4);
let header = "";
for (let index = 0; index < arr.length; index++) {
header += arr[index].toString(16);
}
mimeType = headers[header];
if (!mimeType) console.log("!mimeType Header:", header);
callback(mimeType);
};
fileReader.readAsArrayBuffer(file);
}
// import * as fileType from "file-type";
const file = {
getLimits:
(data = {}) =>
async (dispatch) =>
await proxy.get("file/limits", data, { dispatch }),
setSignature:
(data = {}) =>
async (dispatch) =>
await dispatch({ type: "file/setSignature", data }),
upload:
(data = {}) =>
async (dispatch) => {
let mimeType = await new Promise((r) => getMimeType(data.file, r));
if (
!window.config.admin_config_uploadExtensions
.split(",")
.includes(data.file.name.split(".").slice(-1)[0])
)
return { statusCode: 400, message: "پسوند فایل ارسالی مجاز نیست" };
if (!mimeType || !mimeType.split("|").includes(data.file.type))
return { statusCode: 400, message: "فرمت فایل ارسالی مجاز نیست" };
if (
data.file.size >
window.config.admin_config_maxUploadSize * 1024 * 1024
)
return {
statusCode: 400,
message: `حجم فایل ارسالی باید کمتر از ${window.config.admin_config_maxUploadSize} مگابایت باشد`,
};
var formData = new FormData();
for (let key in data) formData.append(key, data[key]);
return await proxy.post(
"file/upload",
formData,
{
dispatch,
headers: {
"Content-Type": "multipart/form-data",
},
},
data
);
},
directUpload:
(data = {}) =>
async (dispatch) => {
var formData = new FormData();
for (let key in data) formData.append(key, data[key]);
return await proxy.post(
"file/directUpload",
formData,
{
dispatch,
headers: {
"Content-Type": "multipart/form-data",
},
},
data
);
},
loading: (data) => (dispatch) => dispatch({ type: "file/loading", data }),
groupList:
(data = {}) =>
async (dispatch) =>
await proxy.get("file/group/list", data, { dispatch }),
};
export default file;

@ -0,0 +1,89 @@
import proxy from "~/redux/proxy";
const healthCard = {
updatePrintDate:
(data = {}) =>
async (dispatch) => {
return await proxy.put("healthCard/updatePrintDate", data, { dispatch });
},
setVoid:
(data = {}) =>
async (dispatch) => {
return await proxy.put("healthCard/setVoid", data, { dispatch });
},
revertAutoCancel:
(data = {}) =>
async (dispatch) => {
return await proxy.put("healthCard/revertAutoCancel", data, { dispatch });
},
changeJobId:
(data = {}) =>
async (dispatch) => {
return await proxy.put("healthCard/changeJobId", data, { dispatch });
},
abate:
(data = {}) =>
async (dispatch) => {
return await proxy.post("healthCard/abate", data, { dispatch });
},
forceApprove:
(data = {}) =>
async (dispatch) => {
return await proxy.post("healthCard/forceApprove", data, { dispatch });
},
voidIncorrectUniversity:
(data = {}) =>
async (dispatch) => {
return await proxy.post("healthCard/voidIncorrectUniversity", data, {
dispatch,
});
},
getJobs:
(data = {}) =>
async (dispatch) => {
return await proxy.get("healthCard/getJobs", data, { dispatch });
},
list:
(data = {}) =>
async (dispatch) => {
return await proxy.get("healthCard/list", data, { dispatch });
},
getExcelData: (data) => async (dispatch) => {
return await proxy.get(
"healthCard/list",
{ ...data, excelData: true },
{ dispatch }
);
},
clearExcelData:
(data = {}) =>
async (dispatch) => {
await dispatch({ type: "healthCard/clearExcelData", data });
},
getlog:
(data = {}) =>
async (dispatch) => {
return await proxy.get("healthCard/nationalIdLog", data, { dispatch });
},
info:
(data = {}) =>
async (dispatch) => {
return await proxy.get("healthCard/info", data, { dispatch });
},
add:
(data = {}) =>
async (dispatch) => {
return await proxy.post("healthCard/add", data, { dispatch });
},
delete:
(data = {}) =>
async (dispatch) => {
return await proxy.delete("healthCard/delete", data, { dispatch });
},
update:
(data = {}) =>
async (dispatch) => {
return await proxy.put("healthCard/update", data, { dispatch });
},
};
export default healthCard;

@ -0,0 +1,38 @@
// @create-index
export { default as book } from "./book.js";
export { default as comment } from "./comment.js";
export { default as config } from "./config.js";
export { default as faq } from "./faq.js";
export { default as file } from "./file.js";
export { default as map } from "./map.js";
export { default as menu } from "./menu.js";
export { default as offCode } from "./offCode.js";
export { default as otp } from "./otp.js";
export { default as process } from "./process.js";
export { default as product } from "./product.js";
export { default as publicApi } from "./publicApi.js";
export { default as report } from "./report.js";
export { default as role } from "./role.js";
export { default as roleFunction } from "./roleFunction.js";
export { default as user } from "./user.js";
export { default as userFactor } from "./userFactor.js";
export { default as userProduct } from "./userProduct.js";
export { default as userFavorite } from "./userFavorite.js";
export { default as userAddress } from "./userAddress.js";
export { default as admin } from "./admin.js";
export { default as auto } from "./auto.js";
export { default as craft } from "./craft.js";
export { default as transport } from "./transport.js";
export { default as task } from "./task.js";
export { default as unit } from "./unit.js";
export { default as healthCard } from "./healthCard.js";
export { default as network } from "./network.js";
export { default as inspection } from "./inspection.js";
export { default as waterSupply } from "./waterSupply.js";
export { default as content } from "./content.js";
export { default as certificate } from "./certificate.js";
export { default as workFlow } from "./workFlow.js";
export { default as documents } from "./documents.js";
export { default as audit } from "./audit.js";

@ -0,0 +1,49 @@
import proxy from "~/redux/proxy";
const inspection = {
getStatics:
(data = {}) =>
async (dispatch) => {
return await proxy.get("bpms/inspection/statistics/network", data, {
dispatch,
});
},
list:
(data = {}) =>
async (dispatch) => {
return await proxy.get("inspection/list", data, { dispatch });
},
getExcelData: (data) => async (dispatch) => {
return await proxy.get(
"inspection/list",
{ ...data, excelData: true },
{ dispatch }
);
},
clearExcelData:
(data = {}) =>
async (dispatch) => {
await dispatch({ type: "inspection/clearExcelData", data });
},
info:
(data = {}) =>
async (dispatch) => {
return await proxy.get("inspection/info", data, { dispatch });
},
add:
(data = {}) =>
async (dispatch) => {
return await proxy.post("inspection/add", data, { dispatch });
},
delete:
(data = {}) =>
async (dispatch) => {
return await proxy.delete("inspection/delete", data, { dispatch });
},
update:
(data = {}) =>
async (dispatch) => {
return await proxy.put("inspection/update", data, { dispatch });
},
};
export default inspection;

@ -0,0 +1,13 @@
import proxy from "~/redux/proxy";
const map = {
setDrawJSON:
(data = {}) =>
(dispatch) =>
dispatch({ type: "map/setDrawJSON", data }),
setMap:
(data = {}) =>
(dispatch) =>
dispatch({ type: "map/setMap", data }),
};
export default map;

@ -0,0 +1,45 @@
import proxy from "~/redux/proxy";
const menu = {
list:
(data = {}) =>
async (dispatch) => {
return await proxy.get("menu/list", data, { dispatch });
},
homePage:
(data = {}) =>
async (dispatch) => {
return await proxy.get("menu/homePage", data, { dispatch });
},
Adminlist:
(data = {}) =>
async (dispatch) => {
return await proxy.get("menu/admin/list", data, { dispatch });
},
info:
(data = {}) =>
async (dispatch) => {
return await proxy.get("menu/info", data, { dispatch });
},
add:
(data = {}) =>
async (dispatch) => {
return await proxy.post("menu/add", data, { dispatch });
},
homePage:
(data = {}) =>
async (dispatch) => {
return await proxy.get("menu/homePage", data, { dispatch });
},
delete:
(data = {}) =>
async (dispatch) => {
return await proxy.delete("menu/delete", data, { dispatch });
},
update:
(data = {}) =>
async (dispatch) => {
return await proxy.put("menu/update", data, { dispatch });
},
};
export default menu;

@ -0,0 +1,42 @@
import proxy from "~/redux/proxy";
const network = {
list:
(data = {}) =>
async (dispatch) => {
return await proxy.get("network/list", data, { dispatch });
},
getExcelData: (data) => async (dispatch) => {
return await proxy.get(
"network/list",
{ ...data, excelData: true },
{ dispatch }
);
},
clearExcelData:
(data = {}) =>
async (dispatch) => {
await dispatch({ type: "network/clearExcelData", data });
},
info:
(data = {}) =>
async (dispatch) => {
return await proxy.get("network/info", data, { dispatch });
},
add:
(data = {}) =>
async (dispatch) => {
return await proxy.post("network/add", data, { dispatch });
},
delete:
(data = {}) =>
async (dispatch) => {
return await proxy.delete("network/delete", data, { dispatch });
},
update:
(data = {}) =>
async (dispatch) => {
return await proxy.put("network/update", data, { dispatch });
},
};
export default network;

@ -0,0 +1,47 @@
import proxy from "~/redux/proxy";
const network = {
list:
(data = {}) =>
async (dispatch) => {
return await proxy.get("network/list", data, { dispatch });
},
getExcelData: (data) => async (dispatch) => {
return await proxy.get(
"network/list",
{ ...data, excelData: true },
{ dispatch }
);
},
clearExcelData:
(data = {}) =>
async (dispatch) => {
await dispatch({ type: "network/clearExcelData", data });
},
info:
(data = {}) =>
async (dispatch) => {
return await proxy.get("network/info", data, { dispatch });
},
add:
(data = {}) =>
async (dispatch) => {
return await proxy.post("network/add", data, { dispatch });
},
delete:
(data = {}) =>
async (dispatch) => {
return await proxy.delete("network/delete", data, { dispatch });
},
update:
(data = {}) =>
async (dispatch) => {
return await proxy.put("network/update", data, { dispatch });
},
transfer:
(data = {}) =>
async (dispatch) => {
return await proxy.put("network/transfer", data, { dispatch });
},
};
export default network;

@ -0,0 +1,9 @@
import proxy from "../proxy";
const offCode = {
list:
(data = {}) =>
async (dispatch) =>
await proxy.get("offCode/list", data, { dispatch }),
};
export default offCode;

@ -0,0 +1,8 @@
const otp = {
set: (data) => async (dispatch) =>
await dispatch({ type: "authentication/otp/set", data: data }),
reset: (data) => async (dispatch) =>
await dispatch({ type: "authentication/otp/reset" }),
};
export default otp;

@ -0,0 +1,35 @@
import proxy from "~/redux/proxy";
const user = {
list:
(data = {}) =>
async (dispatch) => {
return await proxy.get("process/list", data, { dispatch });
},
info:
(data = {}) =>
async (dispatch) => {
return await proxy.get("process/info", data, { dispatch });
},
add:
(data = {}) =>
async (dispatch) => {
return await proxy.post("process/add", data, { dispatch });
},
copy:
(data = {}) =>
async (dispatch) => {
return await proxy.post("process/copy", data, { dispatch });
},
delete:
(data = {}) =>
async (dispatch) => {
return await proxy.delete("process/delete", data, { dispatch });
},
update:
(data = {}) =>
async (dispatch) => {
return await proxy.put("process/update", data, { dispatch });
},
};
export default user;

@ -0,0 +1,51 @@
import proxy from "~/redux/proxy";
const product = {
getSimilar:
(data = {}) =>
async (dispatch) =>
await proxy.get("product/similar", data, { dispatch }),
list:
(data = {}) =>
async (dispatch) => {
return await proxy.get("product/list", data, { dispatch });
},
getExcelData: (data) => async (dispatch) => {
return await proxy.get(
"product/list",
{ ...data, excelData: true },
{ dispatch }
);
},
clearExcelData:
(data = {}) =>
async (dispatch) => {
await dispatch({ type: "product/clearExcelData", data });
},
info:
(data = {}) =>
async (dispatch) => {
return await proxy.get("product/info", data, { dispatch });
},
add:
(data = {}) =>
async (dispatch) => {
return await proxy.post("product/add", data, { dispatch });
},
homePage:
(data = {}) =>
async (dispatch) => {
return await proxy.get("product/homePage", data, { dispatch });
},
delete:
(data = {}) =>
async (dispatch) => {
return await proxy.delete("product/delete", data, { dispatch });
},
update:
(data = {}) =>
async (dispatch) => {
return await proxy.put("product/update", data, { dispatch });
},
};
export default product;

@ -0,0 +1,59 @@
import proxy from "~/redux/proxy";
const publicApi = {
report:
(data = {}) =>
async (dispatch) =>
await proxy.post("public/report", data, { dispatch }),
//blog start
captcha:
(data = {}) =>
async (dispatch) =>
await proxy.get("public/captcha", data, { dispatch }),
setHashtag: (data) => async (dispatch) =>
await dispatch({ type: "public/setHashtag", data }),
blogList:
(data = {}) =>
async (dispatch) =>
await proxy.get("public/blogList", data, { dispatch }),
blogInfo:
(data = {}) =>
async (dispatch) =>
await proxy.get("public/blogInfo", data, { dispatch }),
// blog end
bookInfo:
(data = {}, data2 = {}) =>
async (dispatch) => {
return await proxy.get("public/vod/bookCourse", data, { dispatch });
// return await proxy.get("book/info", data2, { dispatch });
},
bookSection:
(data = {}) =>
async (dispatch) =>
await proxy.get("public/vod/bookSection", data, { dispatch }),
activeSeason: (data) => async (dispatch) =>
await dispatch({ type: "public/vod/activeSeason", data }),
activeVOD: (data) => async (dispatch) =>
await dispatch({ type: "public/vod/activeVOD", data }),
loginMenu:
(data = {}) =>
async (dispatch) =>
await proxy.get("public/loginMenu", data, { dispatch }),
changesLog:
(data = {}) =>
async (dispatch) =>
await proxy.get("public/changesLog", data, { dispatch }),
sliderList: (data) => async (dispatch) =>
await proxy.get("public/slider/list", data, { dispatch }),
sendOtp:
(data = {}) =>
async (dispatch) =>
await proxy.get("public/otp", data, { dispatch }),
clearOtp:
(data = {}) =>
async (dispatch) =>
dispatch({ type: "public/clearOtp", data }),
getArList: (data) => async (dispatch) =>
await proxy.get("public/ar", data, { dispatch }),
};
export default publicApi;

@ -0,0 +1,48 @@
import proxy from "../proxy";
const report = {
product_dashboard:
(data = {}) =>
async (dispatch) =>
await proxy.get("report/product/dashboard", data, { dispatch }),
content_dashboard:
(data = {}) =>
async (dispatch) =>
await proxy.get("report/content/dashboard", data, { dispatch }),
productType_sold_count:
(data = {}) =>
async (dispatch) =>
await proxy.get("report/productType/sold/count", data, { dispatch }),
getClinets:
(data = {}) =>
async (dispatch) =>
await proxy.get("report/clients", data, { dispatch }),
grade_sold_count:
(data = {}) =>
async (dispatch) =>
await proxy.get("report/grade/sold/count", data, { dispatch }),
book_sold_count:
(data = {}) =>
async (dispatch) =>
await proxy.get("report/book/sold/count", data, { dispatch }),
product_total_sold:
(data = {}) =>
async (dispatch) =>
await proxy.get("report/product/total/sold", data, { dispatch }),
code_total_sold:
(data = {}) =>
async (dispatch) =>
await proxy.get("report/code/total/sold", data, { dispatch }),
getData:
(data = {}) =>
async (dispatch) =>
await proxy.get("report/getData", data, { dispatch }),
list:
(data = {}) =>
async (dispatch) =>
await proxy.get("report/list", data, { dispatch }),
clearData: (data) => async (dispatch) =>
await dispatch({ type: "report/clearData", data }),
};
export default report;

@ -0,0 +1,6 @@
const role = {
set: (data) => async (dispatch) =>
await dispatch({ type: "authentication/role/set", data }),
};
export default role;

@ -0,0 +1,40 @@
import proxy from "~/redux/proxy";
const menu = {
list:
(data = {}) =>
async (dispatch) => {
return await proxy.get(
"admin/roleFunction",
{ ...data, schema: true },
{ dispatch }
);
},
info:
(data = {}) =>
async (dispatch) => {
return await proxy.get("admin/roleFunction/" + data.id, data, {
dispatch,
});
},
add:
(data = {}) =>
async (dispatch) => {
return await proxy.post("admin/roleFunction/add", data, { dispatch });
},
delete:
(data = {}) =>
async (dispatch) => {
return await proxy.delete("admin/roleFunction/delete/" + data.id, data, {
dispatch,
});
},
update:
(data = {}) =>
async (dispatch) => {
return await proxy.put("admin/roleFunction/update/" + data.id, data, {
dispatch,
});
},
};
export default menu;

@ -0,0 +1,118 @@
import proxy from "../proxy";
const task = {
inactive:
(data = {}) =>
async (dispatch) => {
return await proxy.post("bpms/taskFlow/inactive", data, { dispatch });
},
draft:
(data = {}) =>
async (dispatch) => {
return await proxy.post("bpms/task/draft", data, { dispatch });
},
done:
(data = {}) =>
async (dispatch) => {
return await proxy.post("bpms/task/done", data, { dispatch });
},
archive:
(data = {}) =>
async (dispatch) => {
return await proxy.put("bpms/task/archive", data, { dispatch });
},
revert:
(data = {}) =>
async (dispatch) => {
return await proxy.post("bpms/task/revert", data, { dispatch });
},
cancel:
(data = {}) =>
async (dispatch) => {
return await proxy.post("bpms/task/cancel", data, { dispatch });
},
rollback:
(data = {}) =>
async (dispatch) => {
return await proxy.get("bpms/task/rollback", data, { dispatch });
},
rollback2:
(data = {}) =>
async (dispatch) => {
return await proxy.get("bpms/task/rollback2", data, { dispatch });
},
startable:
(data = {}) =>
async (dispatch) => {
return await proxy.get("bpms/process/startable", data, { dispatch });
},
inboxInfo:
(data = {}) =>
async (dispatch) => {
return await proxy.get("bpms/inboxInfo", data, { dispatch });
},
start:
(data = {}) =>
async (dispatch) => {
return await proxy.post("bpms/process/start", data, { dispatch });
},
list:
(data = {}) =>
async (dispatch) => {
return await proxy.get("bpms/task/list", data, { dispatch });
},
processList:
(data = {}) =>
async (dispatch) => {
return await proxy.get("bpms/process/list", data, { dispatch });
},
getExcelData:
(data = {}) =>
async (dispatch) => {
return await proxy.get("bpms/task/list", data, { dispatch });
},
htmlCreator:
(data = {}) =>
async (dispatch) => {
return await proxy.get("bpms/htmlCreator", data, { dispatch });
},
checklistInfo:
(data = {}) =>
async (dispatch) => {
return await proxy.get("bpms/task/checklistInfo", data, { dispatch });
},
info:
(data = {}) =>
async (dispatch) => {
return await proxy.get("bpms/task/info", data, { dispatch });
},
tree:
(data = {}) =>
async (dispatch) => {
return await proxy.get("bpms/task/tree", data, { dispatch });
},
done:
(data = {}) =>
async (dispatch) => {
return await proxy.post("bpms/task/done", data, { dispatch });
},
periodicSampling:
(data = {}) =>
async (dispatch) => {
return await proxy.get("bpms/periodicSampling", data, { dispatch });
},
samplingStart:
(data = {}) =>
async (dispatch) => {
return await proxy.post("bpms/samplingStart", data, { dispatch });
},
watersupply_startInspection:
(data = {}) =>
async (dispatch) => {
return await proxy.post("bpms/watersupply/startInspection", data, {
dispatch,
});
},
};
export default task;

@ -0,0 +1,17 @@
import proxy from "../proxy";
const transport = {
list:
(data = {}) =>
async (dispatch) => {
return await proxy.get("transport/list", data, { dispatch });
},
set:
(data = {}, data2 = {}, data3 = {}) =>
async (dispatch) => {
return await proxy.post("transport/setTransport", data, { dispatch });
return await proxy.get("userFactor/info", data2, { dispatch });
return await proxy.get("transport/list", data3, { dispatch });
},
};
export default transport;

@ -0,0 +1,66 @@
import proxy from "~/redux/proxy";
const unit = {
instructions:
(data = {}) =>
async (dispatch) => {
return await proxy.get("unit/instructions", data, { dispatch });
},
list:
(data = {}) =>
async (dispatch) => {
return await proxy.get("unit/list", data, { dispatch });
},
getExcelData: (data) => async (dispatch) => {
return await proxy.get(
"unit/list",
{ ...data, excelData: true },
{ dispatch }
);
},
clearExcelData:
(data = {}) =>
async (dispatch) => {
return await dispatch({ type: "unit/clearExcelData", data });
},
info:
(data = {}) =>
async (dispatch) => {
return await proxy.get("unit/info", data, { dispatch });
},
checkContractLimit:
(data = {}) =>
async (dispatch) => {
return await proxy.get("unit/checkContractLimit", data, { dispatch });
},
add:
(data = {}) =>
async (dispatch) => {
return await proxy.post("unit/add", data, { dispatch });
},
delete:
(data = {}) =>
async (dispatch) => {
return await proxy.delete("unit/delete", data, { dispatch });
},
update:
(data = {}) =>
async (dispatch) => {
return await proxy.put("unit/update", data, { dispatch });
},
healthQualification_list:
(data = {}) =>
async (dispatch) => {
return await proxy.get("unit/healthQualification/list", data, {
dispatch,
});
},
freeAuditorRevoke:
(data = {}) =>
async (dispatch) => {
return await proxy.post("unit/freeAuditorRevoke", data, {
dispatch,
});
},
};
export default unit;

@ -0,0 +1,155 @@
import proxy from "~/redux/proxy";
const user = {
signer:
(data = {}) =>
async (dispatch) =>
await proxy.post("user/signer", data, { dispatch }),
setActiveRoleId: (data) => async (dispatch) =>
dispatch({ type: "user/setActiveRoleId", data }),
login: (data) => async (dispatch) =>
await proxy.login("user/login", data, { dispatch }),
switchRole:
(data = {}) =>
async (dispatch) => {
return await proxy.login("user/switchRole", data, { dispatch });
},
otp_login: (data) => async (dispatch) =>
await proxy.login("user/otp/login", data, { dispatch }),
sso_login: (data) => async (dispatch) =>
await proxy.login("user/sso/login", data, { dispatch }),
sso_login2: (data) => async (dispatch) =>
await proxy.login("user/sso/login2", data, { dispatch }),
otp_register: (data) => async (dispatch) =>
await proxy.login("user/otp/register", data, { dispatch }),
logout: (data) => async (dispatch) =>
await proxy.logout("user/logout", data, { dispatch }),
getUserRole: (data) => async (dispatch) =>
await proxy.get("user/getUserRole", data, { dispatch }),
getProfile:
(data = {}) =>
async (dispatch) =>
await proxy.get("user/getProfile", data, { dispatch }),
setProfile:
(data = {}) =>
async (dispatch) => {
return await proxy.put("user/setProfile", data, { dispatch });
},
list:
(data = {}) =>
async (dispatch) => {
return await proxy.get("user/list", data, { dispatch });
},
getExcelData: (data) => async (dispatch) => {
return await proxy.get(
"user/list",
{ ...data, excelData: true },
{ dispatch }
);
},
clearExcelData:
(data = {}) =>
async (dispatch) => {
await dispatch({ type: "user/clearExcelData", data });
},
info:
(data = {}) =>
async (dispatch) => {
return await proxy.get("user/info", data, { dispatch });
},
add:
(data = {}) =>
async (dispatch) => {
return await proxy.post("user/add", data, { dispatch });
},
setDefaultPassword:
(data = {}) =>
async (dispatch) => {
return await proxy.put("user/setDefaultPassword", data, { dispatch });
},
resetPassword:
(data = {}) =>
async (dispatch) => {
return await proxy.post("user/resetPassword", data, { dispatch });
},
addUserRole:
(data = {}) =>
async (dispatch) => {
return await proxy.post("user/addUserRole", data, { dispatch });
},
deleteUserRole:
(data = {}) =>
async (dispatch) => {
return await proxy.delete("user/deleteUserRole", data, { dispatch });
},
updateUserRole:
(data = {}) =>
async (dispatch) => {
return await proxy.put("user/updateUserRole", data, { dispatch });
},
referAndDeleteUserRole:
(data = {}) =>
async (dispatch) => {
return await proxy.delete("user/referAndDeleteUserRole", data, {
dispatch,
});
},
copyRoleFunction:
(data = {}) =>
async (dispatch) => {
return await proxy.post("user/copyRoleFunction", data, {
dispatch,
});
},
delete:
(data = {}) =>
async (dispatch) => {
return await proxy.delete("user/delete", data, { dispatch });
},
update:
(data = {}) =>
async (dispatch) => {
return await proxy.put("user/update", data, { dispatch });
},
names:
(data = {}) =>
async (dispatch) => {
return await proxy.get("user/names", data, { dispatch });
},
setName:
(data = {}) =>
async (dispatch) => {
return await proxy.put("user/setName", data, { dispatch });
},
examination_info:
(data = {}) =>
async (dispatch) => {
return await proxy.get("user/examination/info", data, { dispatch });
},
examination_add:
(data = {}) =>
async (dispatch) => {
return await proxy.post("user/examination/add", data, { dispatch });
},
examination_update:
(data = {}) =>
async (dispatch) => {
return await proxy.put("user/examination/update", data, { dispatch });
},
changeNetwork:
(data = {}) =>
async (dispatch) => {
return await proxy.put("user/changeNetwork", data, { dispatch });
},
changeNetwork3:
(data = {}) =>
async (dispatch) => {
return await proxy.put("user/changeNetwork3", data, { dispatch });
},
admin_otlt:
(data = {}) =>
async (dispatch) => {
await dispatch({ type: "user/admin/otlt", data });
},
};
export default user;

@ -0,0 +1,34 @@
import proxy from "../proxy";
const userAddress = {
list:
(data = {}) =>
async (dispatch) => {
return await proxy.get("userAddress/list", data, { dispatch });
},
info:
(data = {}) =>
async (dispatch) => {
return await proxy.get("userAddress/info", data, { dispatch });
},
update:
(data = {}, data2 = {}) =>
async (dispatch) => {
return await proxy.put("userAddress/update", data, { dispatch });
// return await proxy.get("userAddress/list", data2, { dispatch });
},
add:
(data = {}, data2 = {}, data3 = {}) =>
async (dispatch) => {
return await proxy.post("userAddress/add", data, { dispatch });
// return await proxy.get("userAddress/list", data2, { dispatch });
},
del:
(data = {}, data2 = {}) =>
async (dispatch) => {
return await proxy.delete("userAddress/delete", data, { dispatch });
// return await proxy.get("userAddress/list", data2, { dispatch });
},
};
export default userAddress;

@ -0,0 +1,82 @@
import proxy from "../proxy";
const userFactor = {
list:
(data = {}) =>
async (dispatch) =>
await proxy.get("userFactor/list", data, { dispatch }),
getExcelData: (data) => async (dispatch) => {
return await proxy.get(
"userFactor/list",
{ ...data, excelData: true },
{ dispatch }
);
},
clearExcelData:
(data = {}) =>
async (dispatch) => {
await dispatch({ type: "userFactor/clearExcelData", data });
},
orders:
(data = {}) =>
async (dispatch) =>
await proxy.get("userFactor/orders", data, { dispatch }),
info:
(data = {}) =>
async (dispatch) =>
await proxy.get("userFactor/info", data, { dispatch }),
AdminInfo:
(data = {}) =>
async (dispatch) =>
await proxy.get("userFactor/admin/info", data, { dispatch }),
update:
(data = {}) =>
async (dispatch) => {
return await proxy.put("userFactor/update", data, { dispatch });
},
delete:
(data = {}) =>
async (dispatch) => {
return await proxy.delete("userFactor/delete", data, { dispatch });
},
payment:
(data = {}, data2 = {}) =>
async (dispatch) => {
return await proxy.post("userFactor/payment", data, { dispatch });
},
verify:
(data = {}) =>
async (dispatch) => {
return await proxy.post("userFactor/verify", data, { dispatch });
},
add:
(data = {}, data2 = {}) =>
async (dispatch) => {
return await proxy.post("userFactor/add", data, { dispatch });
return await proxy.get("userFactor/list", data2, { dispatch });
},
del:
(data = {}, data2 = {}) =>
async (dispatch) => {
return await proxy.delete("userFactor/delete", data, { dispatch });
return await proxy.get("userFactor/list", data2, { dispatch });
},
donate:
(data = {}) =>
async (dispatch) => {
return await proxy.post("userFactor/donate", data, { dispatch });
},
deleteUserOffCode:
(data = {}, data2 = {}) =>
async (dispatch) => {
return await proxy.delete("userFactor/deleteUserOffCode", data, {
dispatch,
});
return await proxy.get("userFactor/info", data2, { dispatch });
},
fullList:
(data = {}) =>
async (dispatch) =>
await proxy.get("userFactor/fullList", data, { dispatch }),
};
export default userFactor;

@ -0,0 +1,27 @@
import proxy from "../proxy";
const userFavorite = {
list:
(data = {}) =>
async (dispatch) => {
return await proxy.get("userFavorite/list", data, { dispatch });
},
update:
(data = {}, data2 = {}) =>
async (dispatch) => {
return await proxy.put("userFavorite/update", data);
return await proxy.get("userFavorite/list", data2, { dispatch });
},
add:
(data = {}, data2 = {}, data3 = {}) =>
async (dispatch) => {
return await proxy.post("userFavorite/add", data, { dispatch });
},
del:
(data = {}, data2 = {}) =>
async (dispatch) => {
return await proxy.delete("userFavorite/delete", data, { dispatch });
},
};
export default userFavorite;

@ -0,0 +1,59 @@
import proxy from "../proxy";
const userProduct = {
list:
(data = {}) =>
async (dispatch) => {
return await proxy.get("userProduct/list", data, { dispatch });
},
getExcelData: (data) => async (dispatch) => {
return await proxy.get(
"userProduct/list",
{ ...data, excelData: true },
{ dispatch }
);
},
clearExcelData:
(data = {}) =>
async (dispatch) => {
await dispatch({ type: "userProduct/clearExcelData", data });
},
myList:
(data = {}) =>
async (dispatch) => {
return await proxy.get("userProduct/myList", data, { dispatch });
},
info:
(data = {}) =>
async (dispatch) =>
await proxy.get("userProduct/info", data, { dispatch }),
update:
(data = {}) =>
async (dispatch) => {
return await proxy.put("userProduct/update", data, { dispatch });
},
delete:
(data = {}) =>
async (dispatch) => {
return await proxy.delete("userProduct/delete", data, { dispatch });
},
add:
(data = {}) =>
async (dispatch) => {
return await proxy.post("userProduct/add", data, { dispatch });
},
addShow:
(data = {}, data2 = {}) =>
async (dispatch) => {
return await proxy.post("userProduct/addShow", data, { dispatch });
return await proxy.get("userProduct/list", data2, { dispatch });
// return await proxy.get("userFactor/info", data3, { dispatch });
},
del:
(data = {}, data2 = {}) =>
async (dispatch) => {
return await proxy.delete("userProduct/delete", data);
return await proxy.get("userProduct/list", data2, { dispatch });
},
};
export default userProduct;

@ -0,0 +1,42 @@
import proxy from "~/redux/proxy";
const waterSupply = {
list:
(data = {}) =>
async (dispatch) => {
return await proxy.get("waterSupply/list", data, { dispatch });
},
getExcelData: (data) => async (dispatch) => {
return await proxy.get(
"waterSupply/list",
{ ...data, excelData: true },
{ dispatch }
);
},
clearExcelData:
(data = {}) =>
async (dispatch) => {
await dispatch({ type: "waterSupply/clearExcelData", data });
},
info:
(data = {}) =>
async (dispatch) => {
return await proxy.get("waterSupply/info", data, { dispatch });
},
add:
(data = {}) =>
async (dispatch) => {
return await proxy.post("waterSupply/add", data, { dispatch });
},
delete:
(data = {}) =>
async (dispatch) => {
return await proxy.delete("waterSupply/delete", data, { dispatch });
},
update:
(data = {}) =>
async (dispatch) => {
return await proxy.put("waterSupply/update", data, { dispatch });
},
};
export default waterSupply;

@ -0,0 +1,13 @@
import proxy from "~/redux/proxy";
const prefix = "auto/";
const workFlow = {
info:
(data = {}) =>
async (dispatch) => {
return await proxy.get(prefix + data._service + "/" + data.id, data, {
dispatch,
});
},
};
export default workFlow;

@ -0,0 +1,7 @@
// @create-index
export * as actions from './actions';
export { default as proxy } from './proxy.js';
export * as reducers from './reducers';
export { default as store } from './store.js';

@ -0,0 +1,241 @@
import _ from "lodash";
import axios from "axios";
import config from "~/config";
import bcrypt from "bcryptjs";
let { baseUrl, TTL = 360 } = config;
if (window.location.href.includes("barnamenegar.com"))
baseUrl = "https://sameh.barnamenegar.com/api/v2/";
let Axios;
let progressDespatch;
const race = (promises) =>
new Promise((resolve, reject) => {
for (const promise of promises) promise.then(resolve, reject);
});
export const reAxios = async (baseUrl) => {
if (window.location.href.includes("barnamenegar.com"))
baseUrl = "https://sameh.barnamenegar.com/api/v2/";
let access;
let sessionId = sessionStorage.getItem("sessionId");
if (sessionId) access = btoa(bcrypt.hashSync(sessionId, 10));
baseUrl = baseUrl || config.baseUrl;
Axios = axios.create({
onUploadProgress: (progressEvent) => {
if (progressDespatch) {
progressDespatch(
Math.round((progressEvent.loaded / progressEvent.total) * 100)
);
}
},
withCredentials: true,
validateStatus: null,
baseURL: baseUrl,
headers: access ? { Authorization: `Bearer ${access}` } : {},
});
window.Axios = Axios;
};
reAxios();
window.reAxios = reAxios;
class Proxy {
get = async (url, params, opt, data) =>
await this.check(
url,
opt,
async () => await Axios.get(url, { params, _service: undefined, ...opt }),
data || params
);
post = async (url, params, opt, data) =>
await this.check(
url,
opt,
async () => await Axios.post(url, params, opt),
data || params
);
put = async (url, params, opt, data) => {
if (window.location.href.includes("barnamenegar.com"))
return await this.post(url, params, opt, data);
return await this.check(
url,
opt,
async () => await Axios.put(url, params, opt),
data || params
);
};
delete = async (url, params, opt, data) => {
if (window.location.href.includes("barnamenegar.com"))
return await this.post(url, params, opt, data);
return await this.check(
url,
opt,
async () => await Axios.delete(url, { ...opt, data: params }),
data || params
);
};
timeout = new Promise((r) =>
setTimeout(
() => r({ data: { status: 500, message: "سرور پاسخگو نیست" } }),
TTL * 1000
)
);
check = async (url, { dispatch }, fetch, params) => {
dispatch = dispatch || (() => {});
url && dispatch({ type: url.split("/")[0] + "/loading", params });
progressDespatch = (p) => {
dispatch({ type: url.split("/")[0] + "/progress", data: p });
};
const response = await race([
new Promise(async (r) => r(await fetch())),
new Promise(async (r) =>
setTimeout(
() => r({ status: 500, message: "خطا: عدم پاسخگویی اتصال به سرور" }),
TTL * 1000
)
),
]);
switch (response.status) {
case 200:
window.serverDate = response.data.date;
(response.data?.logs || []).forEach((r) => {
if (r[0].etag)
console[r[0].mode](
`${config.baseUrl}/${url} ${r[0].name}:${r[0].line}:${r[0].time}ms`,
...r.slice(1)
);
});
dispatch({
type: url,
data: response.data.data,
schema: response.data.schema,
count: response.data.count,
message: response.data.message,
params,
headers: response.headers,
});
return response.data.data;
case 401:
let refresh = false; // await this.refresh();
if (refresh) {
let response = await fetch();
dispatch({ type: url, data: response.data.data });
return response.data.data;
} else {
sessionStorage.removeItem("userData");
sessionStorage.removeItem("sessionId");
window.location.href = "/login";
}
// dispatch({
// type: url.split("/")[0] + "/error",
// data: response.data || response,
// });
break;
case 403:
default:
dispatch({
type: url.split("/")[0] + "/error",
data: response?.data?.data ||
response?.data || { message: "خطای برقراری ارتباط" },
message:
response.data?.message == undefined
? "خطای برقراری ارتباط"
: response.data?.message,
params,
});
return { statusCode: response.status, message: response.data?.message };
}
return false;
};
login = async (url, params, opt = {}) => {
let { dispatch } = opt;
this.post(url, params, {
dispatch: async (obj) => {
console.log({ obj });
let login = obj.data;
let sessionId = obj.headers?.sessionid;
if (!login) return dispatch(obj);
console.log({ obj });
sessionStorage.removeItem("userData");
sessionStorage.removeItem("sessionId");
await new Promise((r) => setTimeout(r, 100));
delete login.accessToken;
delete login.refreshToken;
if (!login.statusCode) {
sessionStorage.setItem("userData", JSON.stringify(login));
sessionStorage.setItem("sessionId", sessionId);
}
if (!localStorage.getItem("activeRoleId"))
localStorage.setItem("activeRoleId", 0);
// clearInterval(window.checkValidation);
// window.checkValidation = setInterval(() => {
// console.log("start validation");
// try {
// let validation = JSON.parse(
// sessionStorage.getItem("userData")
// ).validation;
// console.log({ validation, now: new Date().getTime() });
// if (!validation || validation < new Date().getTime())
// throw new Error("not validated");
// } catch (e) {
// console.log(e.message, e);
// localStorage.removeItem("activeRoleId");
// window.sessionStorage.clear();
// return window.location.reload();
// }
// }, 300 * 1000);
reAxios();
dispatch(obj);
},
});
};
logout = async (url, params, { dispatch }) => {
clearInterval(window.checkValidation);
dispatch({ type: url.split("/")[0] + "/loading" });
await this.post(url, params, {
dispatch: (obj) => {
localStorage.removeItem("activeRoleId");
window.navigator.serviceWorker
.getRegistrations()
.then(function (registrations) {
for (let registration of registrations) {
registration.unregister();
}
});
dispatch(obj);
},
});
};
status = () => {
const userData = sessionStorage.getItem("userData");
if (userData) {
// clearInterval(window.checkValidation);
// window.checkValidation = setInterval(() => {
// try {
// let validation = JSON.parse(
// sessionStorage.getItem("userData")
// ).validation;
// console.log({ validation, now: new Date().getTime() });
// if (!validation || validation < new Date().getTime())
// throw new Error("not validated");
// } catch (e) {
// console.log(e.message, e);
// localStorage.removeItem("activeRoleId");
// window.sessionStorage.clear();
// return window.location.reload();
// }
// }, 300 * 1000);
}
return userData ? JSON.parse(userData) : null;
// let profile = await axios.get("user/fetProfile");
// sessionStorage.setItem("userData", JSON.stringify(profile.data));
// console.log(profile);
// return profile.data;
};
}
const _proxy = new Proxy();
export default _proxy;

@ -0,0 +1,146 @@
import config from "~/config";
import { toast } from "react-toastify";
let { baseUrl } = config;
if (window.location.href.includes("barnamenegar.com"))
baseUrl = "https://sameh.barnamenegar.com/api/v2/";
const initialState = {
backupLink: null,
userFactor: {
beforeSchema: [
{
text: "نمایش",
description: "نمایش",
type: "button",
link: "`factor?id=${row.id}`",
},
],
},
file: {
beforeSchema: [
{
text: "نمایش",
description: "نمایش",
link:
"`${row.type=='folder'? 'file/?pid='+row.id: '" +
baseUrl +
"file/'+row.id}`",
type: "button",
},
],
},
};
export default function admin(state = initialState, action) {
let { type, data, schema, count, params, message } = action;
if (type == "admin/backupLink")
return { ...state, loading: false, backupLink: data, error: null };
if (!params && !params?._service) return state;
const pathPrefix = `admin/${params._service}/`;
switch (type.split(pathPrefix)[1]) {
case "":
if (params.excelData)
return {
...state,
[params._service]: {
...state[params._service],
loading: false,
error: null,
schema: schema,
excelData: data,
},
};
return {
...state,
[params._service]: {
...state[params._service],
loading: false,
error: null,
list: data,
schema: schema,
count,
pageCount: +Math.floor((count - 1) / params.pageSize) + 1,
},
};
case "clearExcelData": {
return {
...state,
[params._service]: {
...state[params._service],
loading: false,
excelData: null,
},
};
}
case "/" + params.id:
return {
...state,
[params._service]: {
...state[params._service],
loading: false,
error: null,
info: data,
},
};
case "add":
toast.success(message);
return {
...state,
[params._service]: {
...state[params._service],
loading: false,
error: null,
},
};
case "update/" + params.id:
toast.success(message);
return {
...state,
[params._service]: {
...state[params._service],
loading: false,
error: null,
},
};
case "delete/" + params.id:
toast.success(message);
return {
...state,
[params._service]: {
...state[params._service],
loading: false,
error: null,
},
};
case "loading":
return {
...state,
[params._service]: {
...state[params._service],
loading: true,
},
};
case "error":
toast.error(message, { autoClose: !message.includes("!!") });
return {
...state,
[params._service]: {
...state[params._service],
loading: false,
error: data.message,
},
};
case "timeReport":
return {
...state,
[params._service]: {
...state[params._service],
timeReport: data,
error: null,
},
};
default:
return state;
}
}

@ -0,0 +1,40 @@
import { toast } from "react-toastify";
const initialState = {
loading: false,
error: null,
};
export default function audit(state = initialState, action) {
let { type, data, message } = action;
switch (type) {
case "audit/revokeRole":
toast.success(message, { autoClose: false });
return {
...state,
loading: false,
error: null,
};
case "audit/revokeTask":
toast.success(message, { autoClose: false });
return {
...state,
loading: false,
error: null,
};
case "audit/check":
toast.info(message, { autoClose: false });
return {
...state,
loading: false,
error: null,
};
case "audit/loading":
return { ...state, loading: true };
case "audit/error":
toast.error(data.message, { autoClose: !data.message.includes("!!") });
return { ...state, loading: false, error: data.message || message };
default:
return state;
}
}

@ -0,0 +1,186 @@
import config from "~/config";
import { toast } from "react-toastify";
let { baseUrl } = config;
if (window.location.href.includes("barnamenegar.com"))
baseUrl = "https://sameh.barnamenegar.com/api/v2/";
const initialState = {
userFactor: {
beforeSchema: [
{
text: "نمایش",
description: "نمایش",
type: "button",
link: "`factor?id=${row.id}`",
},
],
},
file: {
beforeSchema: [
{
text: "نمایش",
description: "نمایش",
link:
"`${row.type=='folder'? 'file/?pid='+row.id: '" +
baseUrl +
"file/'+row.id}`",
type: "button",
},
],
},
info: {},
};
export default function auto(state = initialState, action) {
let { type, data, schema, count, params, message } = action;
if (!params && !params?._service) return state;
const pathPrefix = `auto/${params._service}/`;
if (type == "auto/loading")
return {
...state,
loading: true,
};
if (type == "auto/error") {
toast.error(message, { autoClose: !message.includes("!!") });
return {
...state,
loading: false,
};
}
switch (type.split(pathPrefix)[1]) {
case "":
if (params.excelData)
return {
...state,
loading: false,
[params._service]: {
...state[params._service],
loading: false,
error: null,
excelData: data,
},
};
if (params._append)
return {
...state,
loading: false,
[params._service]: {
...state[params._service],
loading: false,
error: null,
append: { ...state[params._service].append, [params.pid]: data },
},
};
return {
...state,
loading: false,
[params._service]: {
...state[params._service],
loading: false,
error: null,
list: data,
schema: schema,
count,
append: {},
done: false,
pageCount: +Math.floor((count - 1) / params.pageSize) + 1,
},
};
case "clearExcelData": {
return {
...state,
loading: false,
[params._service]: {
...state[params._service],
loading: false,
excelData: null,
},
};
}
case "/" + params.id:
return {
...state,
loading: false,
[params._service]: {
...state[params._service],
loading: false,
error: null,
info: data,
},
};
case "add":
toast.success(message);
return {
...state,
loading: false,
[params._service]: {
...state[params._service],
loading: false,
error: null,
done: true,
},
};
case "update/" + params.id:
if (!params["silent"]) toast.success(message);
return {
...state,
loading: false,
[params._service]: {
...state[params._service],
loading: false,
error: null,
done: true,
},
};
case "delete/" + params.id:
if (!params["silent"]) toast.success(message);
return {
...state,
loading: false,
[params._service]: {
...state[params._service],
loading: false,
error: null,
done: true,
},
};
case "loading":
return {
...state,
loading: true,
[params._service]: {
...state[params._service],
loading: true,
done: false,
},
};
case "error":
toast.error(message, { autoClose: !message.includes("!!") });
return {
...state,
loading: false,
[params._service]: {
...state[params._service],
loading: false,
error: data.message,
done: false,
},
};
case "timeReport":
return {
...state,
loading: false,
[params._service]: {
...state[params._service],
timeReport: data,
error: null,
},
};
case "bpms_workflow/" + params.id:
console.log("case");
return { ...state, loading: false, info: { data: "sd" } };
default:
return state;
}
}

@ -0,0 +1,127 @@
import { toast } from "react-toastify";
const initialState = {
loading: false,
error: null,
list: [],
info: null,
searchResult: [],
filterResult: [],
subjects: [],
levels: [],
sortFilters: ["مرتب سازی", "محبوب ترین", "جدیدترین"],
};
const grades = [
"پیش دبستان",
"اول",
"دوم",
"سوم",
"چهارم",
"پنجم",
"ششم",
"هفتم",
"هشتم",
"نهم",
"دهم",
"یازدهم",
"دوازدهم",
];
export default function book(state = initialState, action) {
let { type, data } = action;
switch (type) {
case "book/list":
let itemsSubject = (Array.isArray(data) ? data : []).map(
(item, index) => item.name
);
if (window.innerWidth < 1000) {
itemsSubject.unshift("نام کتاب");
}
let itemsLevel = (Array.isArray(data) ? data : [])
.map((item) => item.gradeId * 1)
.sort((a, b) => a - b)
.map((e) => grades[e]);
if (window.innerWidth < 1000) {
itemsLevel.unshift("پایه تحصیلی");
}
return {
...state,
loading: false,
list: data,
subjects: [...new Set(itemsSubject)],
levels: [...new Set(itemsLevel)],
filterResult: data,
error: null,
};
case "book/info":
return { ...state, loading: false, info: data, error: null };
case "book/update":
return { ...state, loading: false, error: null };
case "book/add":
return { ...state, loading: false, error: null };
case "book/delete":
return { ...state, loading: false, error: null };
case "book/search":
return { ...state };
case "book/filter":
const realList = state.list;
const level = data.level;
const subject = data.subject;
const sort = data.sort;
const search = data.search;
if (level.length > 0 || subject.length > 0 || sort || search) {
localStorage.setItem("filter", "ON");
}
let finalSort;
let byLevelFilter = [];
if (level.length > 0) {
level.forEach((item1) => {
for (let i = 0; i < realList.length; i++) {
if (grades[realList[i].gradeId] === item1) {
byLevelFilter.push(realList[i]);
}
}
});
} else {
byLevelFilter = realList;
}
let bySubjectFilter = [];
if (subject.length > 0) {
subject.forEach((item1) => {
for (let i = 0; i < byLevelFilter.length; i++) {
if (byLevelFilter[i].name === item1) {
bySubjectFilter.push(byLevelFilter[i]);
}
}
});
} else {
bySubjectFilter = byLevelFilter;
}
const bySearchFilter = search
? bySubjectFilter.filter((item1) => item1.name.indexOf(search) !== -1)
: bySubjectFilter;
if (sort === "گران ترین") {
finalSort = bySearchFilter.sort((item1, item2) => {
return item1.product[0].price - item2.product[0].price;
});
} else {
finalSort = bySearchFilter;
}
return {
...state,
loading: false,
error: null,
filterResult: finalSort,
};
case "book/loading":
return { ...state, loading: true };
case "book/error":
toast.error(data.message, { autoClose: !data.message.includes("!!") });
return { ...state, loading: false, error: data.message };
default:
return state;
}
}

@ -0,0 +1,37 @@
const initialState = {
list: [
{
id: 0,
title: "بازرسی بهداشت محیط",
text: "",
fileIds: "/images/catalog/0.jpg",
},
{
id: 1,
title: "بازرسی بهداشت حرفهای",
text: "",
fileIds: "/images/catalog/1.jpg",
},
{
id: 2,
title: "بازرسی بهداشت حرفهای",
text: "",
fileIds: "/images/catalog/2.jpg",
},
{
id: 3,
title: "بازرسی بهداشت محیط ",
text: "",
fileIds: "/images/catalog/3.jpg",
},
],
};
export default function catalog(state = initialState, action) {
let { type, data } = action;
switch (type) {
default:
return state;
}
}

@ -0,0 +1,51 @@
import { toast } from "react-toastify";
const initialState = {
loading: false,
error: null,
list: [],
searchResult: [],
search: null,
roleConflicts: [],
};
export default function certificate(state = initialState, action) {
let { type, data } = action;
switch (type) {
case "certificate/checkConflict":
return { ...state, loading: false, roleConflicts: data, error: null };
case "certificate/list":
return { ...state, loading: false, list: data, error: null };
case "certificate/add":
return { ...state, loading: false, error: null };
case "certificate/healthQualification/start":
return {
...state,
loading: false,
error: null,
start: data,
};
case "certificate/freeAuditRegistration/start":
return {
...state,
loading: false,
error: null,
start: data,
};
case "certificate/certifiedGuildAddUnitStart":
case "certificate/freeAuditAddUnitStart":
return {
...state,
loading: false,
error: null,
start: data,
};
case "certificate/loading":
return { ...state, loading: true };
case "certificate/error":
toast.error(data.message, { autoClose: !data.message.includes("!!") });
return { ...state, loading: false, error: data.message };
default:
return state;
}
}

@ -0,0 +1,37 @@
import proxy from "~/redux/proxy";
import { toast } from "react-toastify";
const status = proxy.status();
const initialState = {
status,
loading: false,
error: null,
list: [],
schema: [],
};
export default function comment(state = initialState, action) {
let { type, data, schema, count, params } = action;
switch (type) {
case "comment/list":
return {
...state,
loading: false,
error: null,
list: data,
schema: schema,
count,
pageCount: +Math.floor((count - 1) / params.pageSize) + 1,
};
case "comment/add":
return { ...state, loading: false, error: null };
case "comment/delete":
return { ...state, loading: false, error: null };
case "comment/loading":
return { ...state, loading: true };
case "comment/error":
toast.error(data.message, { autoClose: !data.message.includes("!!") });
return { ...state, loading: false, error: data.message };
default:
return state;
}
}

@ -0,0 +1,188 @@
const initialState = {
themeName: window.localStorage.getItem("themeName") || "default",
version: window.localStorage.getItem("version"),
menu: true,
header: true,
bottomSheet: {
children: null,
open: null,
},
dialog: {
text: null,
type: null,
accept: null,
open: null,
},
device: "mobile",
themeColors: {
default: {
name: "روشن",
"--primary": "#3D5AFE",
"--primaryLight": "#536DFE",
"--primaryText": "#FFFFFF",
"--primaryDark": "#304FFE",
"--secondary": "#2196F3",
"--secondaryText": "#fff",
"--secondaryDark": "#356dc4",
"--secondaryLight": "#609bf7",
"--background": "#f9fbfc",
"--backgroundText": "#00253A",
"--surface": "#f2f7fc",
"--surfaceDark": "#f1f8ff",
"--surfaceLight": "#f9fcff",
"--surfaceText": "#333333",
"--surfaceBorder": "#e9e9e9",
"--info": "#43c1ff",
"--infoText": "#000000",
"--success": "#42b258",
"--successText": "#fff",
"--warning": "#ffcc00",
"--warningText": "#000000",
"--error": "#D81111",
"--errorText": "#FFFFFF",
"--borderColor": "#E4E4E4",
"--backgroundBorder": "#ECECEC",
"--white": "#ffffff",
},
dark: {
name: "تیره",
"--primary": "#37AA9C",
"--primaryLight": "#48b5a6",
"--primaryText": "#fff",
"--primaryDark": "#2c998a",
"--secondary": "#94F3E4",
"--secondaryText": "#000000",
"--secondaryDark": "#60c1b1",
"--secondaryLight": "#bffff4",
"--background": "#20292d",
"--backgroundText": "#EEE",
"--surface": "#333F44",
"--surfaceDark": "#2b363a",
"--surfaceLight": "#38454B",
"--surfaceText": "#cccccc",
"--surfaceBorder": "#e9e9e9",
"--info": "#43c1ff",
"--infoText": "#000000",
"--success": "#42b258",
"--successText": "#fff",
"--warning": "#f1d416",
"--warningText": "#000000",
"--error": "#c4342d",
"--errorText": "#FFFFFF",
"--borderColor": "#E4E4E430",
"--backgroundBorder": "#ECECEC",
"--white": "#ffffff",
},
brown: {
name: "قهوهای",
"--primary": "#806854",
"--primaryLight": "#967e6a",
"--primaryText": "#fff",
"--primaryDark": "#3e0c5b",
"--secondary": "#A8BAA9",
"--secondaryText": "#000000",
"--secondaryDark": "#6d5cd1",
"--secondaryLight": "#b3a6fc",
"--background": "#fcf7e5",
"--backgroundText": "#494949",
"--surface": "#fffde2",
"--surfaceDark": "#e0dcd2",
"--surfaceLight": "#ebdec0",
"--surfaceText": "#000000",
"--surfaceBorder": "#c4beb4",
"--info": "#43c1ff",
"--infoText": "#000000",
"--success": "#42b258",
"--successText": "#000000",
"--warning": "#ffa200",
"--warningText": "#000000",
"--error": "#D81111",
"--errorText": "#FFFFFF",
"--borderColor": "#c4beb499",
"--backgroundBorder": "#c4bdb4",
"--white": "#ffffff",
},
purpule: {
name: "بنفش",
"--primary": "#561977",
"--primaryLight": "#7F3AB8",
"--primaryText": "#fff",
"--primaryDark": "#3e0c5b",
"--secondary": "#9D8AFF",
"--secondaryText": "#000000",
"--secondaryDark": "#6d5cd1",
"--secondaryLight": "#b3a6fc",
"--background": "#f8f7fc",
"--backgroundText": "#494949",
"--surface": "#f8f4ff",
"--surfaceDark": "#e5f9f9",
"--surfaceLight": "#c7e8fc",
"--surfaceText": "#000000",
"--surfaceBorder": "#b4bec4",
"--info": "#43c1ff",
"--infoText": "#000000",
"--success": "#42b258",
"--successText": "#000000",
"--warning": "#ffa200",
"--warningText": "#000000",
"--error": "#D81111",
"--errorText": "#FFFFFF",
"--borderColor": "#b4bec430",
"--backgroundBorder": "#b4bec4",
"--white": "#ffffff",
},
},
};
export default function config(state = initialState, action) {
let { type, data } = action;
switch (type) {
case "config/setMenu":
return {
...state,
menu: data,
};
case "config/setHeader":
return {
...state,
header: data,
};
case "config/setDialog":
return {
...state,
dialog: data,
};
case "config/setBottomSheet":
return {
...state,
bottomSheet: data,
};
case "config/setTheme":
return {
...state,
themeName: data,
};
case "config/addTheme":
return {
...state,
themeColors: { ...state.themeColors, [data.key]: { ...data.value } },
};
case "config/deleteTheme":
return {
...state,
themeColors: data,
};
case "config/setDevice":
return {
...state,
device: data,
};
default:
return state;
}
}

@ -0,0 +1,31 @@
import { toast } from "react-toastify";
const initialState = {
loading: false,
error: null,
list: [],
info: null,
};
export default function content(state = initialState, action) {
let { type, data } = action;
switch (type) {
case "content/list":
return { ...state, loading: false, list: data, error: null };
case "content/add":
return { ...state, loading: false, error: null };
case "content/info":
return {
...state,
loading: false,
error: null,
info: data,
};
case "content/loading":
return { ...state, loading: true };
case "content/error":
toast.error(data.message, { autoClose: !data.message.includes("!!") });
return { ...state, loading: false, error: data.message };
default:
return state;
}
}

@ -0,0 +1,23 @@
import proxy from "~/redux/proxy";
import { toast } from "react-toastify";
const initialState = {
loading: false,
error: null,
info: null,
};
export default function craft(state = initialState, action) {
let { type, data } = action;
switch (type) {
case "layout/info":
return { ...state, loading: false, error: null, info: data };
case "layout/loading":
return { ...state, loading: true };
case "layout/error":
toast.error(data.message, { autoClose: !data.message.includes("!!") });
return { ...state, loading: false, error: data.message };
default:
return state;
}
}

@ -0,0 +1,17 @@
import { toast } from "react-toastify";
const initialState = {
loading: false,
error: null,
list: [],
info: null,
};
export default function content(state = initialState, action) {
let { type, data } = action;
switch (type) {
case "sync/documentDataModel":
return { ...state, loading: false, list: data, error: null };
default:
return state;
}
}

@ -0,0 +1,57 @@
import { toast } from "react-toastify";
const initialState = {
loading: false,
error: null,
list: [],
searchResult: [],
search: null,
};
export default function faq(state = initialState, action) {
let { type, data } = action;
switch (type) {
case "faq/list":
return { ...state, loading: false, list: data, error: null };
case "faq/add":
return { ...state, loading: false, error: null };
case "faq/selectFaq":
return {
...state,
loading: false,
error: null,
list: !state.search
? state.list.map((item) =>
item.id === data
? { ...item, active: !item.active }
: { ...item, active: false }
)
: state.list,
searchResult: state.search
? state.searchResult.map((item) =>
item.id === data
? { ...item, active: !item.active }
: { ...item, active: false }
)
: state.searchResult,
};
case "faq/search":
return {
...state,
loading: false,
error: null,
search: data,
searchResult: state.list.filter(
(item) =>
item.title.indexOf(data) !== -1 ||
item.description.indexOf(data) !== -1
),
};
case "faq/loading":
return { ...state, loading: true };
case "faq/error":
toast.error(data.message, { autoClose: !data.message.includes("!!") });
return { ...state, loading: false, error: data.message };
default:
return state;
}
}

@ -0,0 +1,87 @@
import { toast } from "react-toastify";
window.config = {
...(window.config || {}),
admin_config_maxUploadSize: 50,
admin_config_uploadExtensions: "doc,docx,pdf,jpg,png,bmp,xls,xlsx,mp4,zip",
};
const initialState = {
loading: false,
error: null,
id: null,
signature: "",
progress: 0,
groupList: [],
list: [
{
id: 1,
name: "file a",
type: "PNG",
size: 50,
uploadAt: "2022-09-10",
},
{
id: 1,
name: "file b",
type: "JPG",
size: 50,
uploadAt: "2022-09-10",
},
{
id: 1,
name: "folder a",
type: "folder",
size: 50,
uploadAt: "2022-09-10",
},
],
schema: [
{ name: "id", desc: "شناسه", description: "شناسه", type: "number" },
{ name: "name", desc: "نام", description: "نام", type: "string" },
{ name: "type", desc: "نوع", description: "شناسه", type: "string" },
{ name: "size", desc: "حجم", description: "شناسه", type: "number" },
{
name: "uploadAt",
desc: "تاریخ آپلود",
description: "شناسه",
type: "date",
},
],
};
export default function file(state = initialState, action) {
let { type, data, params } = action;
switch (type) {
case "file/setSignature":
return {
...state,
signature: data,
};
case "file/directUpload":
case "file/upload":
toast.success("فایل با موفقیت بارگذاری و ثبت شد");
return {
...state,
loading: false,
error: null,
id: data.id,
};
case "message/send":
return { ...state, id: null };
case "file/limits":
window.config = {
...(window.config || {}),
...data,
};
return { ...state, loading: false, error: null };
case "file/group/list":
return { ...state, groupList: data, loading: false, error: null };
case "file/loading":
return { ...state, loading: true, progress: 0 };
case "file/progress":
return { ...state, progress: data };
case "file/error":
return { ...state, loading: false, error: data.message };
default:
return state;
}
}

@ -0,0 +1,19 @@
const initialState = {
text:
`خدماتی که از طریق این پنجره میتوانید به آن دسترسی داشته باشید:` +
//` پیگیری درخواست مجوزها(در کد باشد اما کامنت شود.)`
`ثبت نام متصدیان واحدهای صنفی
ثبت و پیگیری درخواست صلاحیت بهداشتی
ثبت نام مشاوران آزاد/ مشاوران دفاتر خدمات سلامت`,
// درخواست کارت بهداشت (در کد باشد اما کامنت شود.)
// دریافت گواهی آموزش اصناف (در کد باشد اما کامنت شود.)
// `,
};
export default function guide(state = initialState, action) {
let { type, data } = action;
switch (type) {
default:
return state;
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save