Compare commits

..

11 Commits

Author SHA1 Message Date
hamid zarghami 328402fd7f drag and drop
deploy to danak / build_and_deploy (push) Has been cancelled
2026-06-11 12:30:45 +03:30
hamid zarghami eb2f23c403 add new columg design 2026-06-11 12:30:45 +03:30
hamid zarghami f3d7296b06 height fit 2026-06-11 12:30:45 +03:30
hamid zarghami d1f28367d9 add task design 2026-06-11 12:30:45 +03:30
hamid zarghami e2e96a03d3 Columnn page 2026-06-11 12:30:45 +03:30
hamid zarghami 1bef61588b Task + column scroll 2026-06-11 12:30:45 +03:30
hamid zarghami cccc0896b5 add task 2026-06-11 12:30:45 +03:30
hamid zarghami b7b3d0e9e9 base columnn component 2026-06-11 12:30:45 +03:30
hamid zarghami 284b69e298 move component 2026-06-11 12:30:45 +03:30
hamid zarghami 8d66437e7b base design workspace 2026-06-11 12:30:45 +03:30
hamid zarghami 9d2401d951 Add to sidebar 2026-06-11 12:30:45 +03:30
17 changed files with 799 additions and 784 deletions
+90 -60
View File
@@ -9,6 +9,7 @@
"version": "0.0.0",
"dependencies": {
"@headlessui/react": "^2.2.0",
"@hello-pangea/dnd": "^18.0.1",
"@material-tailwind/react": "^2.1.10",
"@tanstack/react-query": "^5.62.8",
"axios": "^1.7.9",
@@ -1568,7 +1569,6 @@
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1585,7 +1585,6 @@
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1602,7 +1601,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1619,7 +1617,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1636,7 +1633,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1653,7 +1649,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1670,7 +1665,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1687,7 +1681,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1704,7 +1697,6 @@
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1721,7 +1713,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1738,7 +1729,6 @@
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1755,7 +1745,6 @@
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1772,7 +1761,6 @@
"cpu": [
"mips64el"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1789,7 +1777,6 @@
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1806,7 +1793,6 @@
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1823,7 +1809,6 @@
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1840,7 +1825,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1857,7 +1841,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1874,7 +1857,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1891,7 +1873,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1908,7 +1889,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1925,7 +1905,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1942,7 +1921,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1959,7 +1937,6 @@
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1976,7 +1953,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2215,6 +2191,23 @@
"react-dom": "^18 || ^19 || ^19.0.0-rc"
}
},
"node_modules/@hello-pangea/dnd": {
"version": "18.0.1",
"resolved": "https://registry.npmjs.org/@hello-pangea/dnd/-/dnd-18.0.1.tgz",
"integrity": "sha512-xojVWG8s/TGrKT1fC8K2tIWeejJYTAeJuj36zM//yEm/ZrnZUSFGS15BpO+jGZT1ybWvyXmeDJwPYb4dhWlbZQ==",
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime": "^7.26.7",
"css-box-model": "^1.2.1",
"raf-schd": "^4.0.3",
"react-redux": "^9.2.0",
"redux": "^5.0.1"
},
"peerDependencies": {
"react": "^18.0.0 || ^19.0.0",
"react-dom": "^18.0.0 || ^19.0.0"
}
},
"node_modules/@humanfs/core": {
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
@@ -2747,7 +2740,6 @@
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2761,7 +2753,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2775,7 +2766,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2789,7 +2779,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2803,7 +2792,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2817,7 +2805,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2831,7 +2818,6 @@
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2845,7 +2831,6 @@
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2859,7 +2844,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2873,7 +2857,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2887,7 +2870,6 @@
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2901,7 +2883,6 @@
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2915,7 +2896,6 @@
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2929,7 +2909,6 @@
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2943,7 +2922,6 @@
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2957,7 +2935,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2971,7 +2948,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2985,7 +2961,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2999,7 +2974,6 @@
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -3013,7 +2987,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -3098,7 +3071,7 @@
"version": "7.20.5",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
"integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.20.7",
@@ -3112,7 +3085,7 @@
"version": "7.6.8",
"resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz",
"integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.0.0"
@@ -3122,7 +3095,7 @@
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
"integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.1.0",
@@ -3133,7 +3106,7 @@
"version": "7.20.6",
"resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz",
"integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.20.7"
@@ -3235,6 +3208,12 @@
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
"license": "MIT"
},
"node_modules/@types/use-sync-external-store": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
"integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
"license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.18.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.18.1.tgz",
@@ -4136,6 +4115,15 @@
"node": ">=8"
}
},
"node_modules/css-box-model": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz",
"integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==",
"license": "MIT",
"dependencies": {
"tiny-invariant": "^1.0.6"
}
},
"node_modules/cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
@@ -4491,7 +4479,6 @@
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz",
"integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
@@ -6050,7 +6037,7 @@
"version": "1.21.7",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
"integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
"dev": true,
"devOptional": true,
"license": "MIT",
"bin": {
"jiti": "bin/jiti.js"
@@ -6434,7 +6421,6 @@
"version": "3.3.8",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
"integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
"dev": true,
"funding": [
{
"type": "github",
@@ -6786,7 +6772,6 @@
"version": "8.5.3",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
"integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
"dev": true,
"funding": [
{
"type": "opencollective",
@@ -7045,6 +7030,12 @@
"node": ">= 12.0.0"
}
},
"node_modules/raf-schd": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz",
"integrity": "sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==",
"license": "MIT"
},
"node_modules/randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@@ -7226,6 +7217,29 @@
"react-dom": ">=16.8.6 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-redux": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.3.0.tgz",
"integrity": "sha512-KQopgqFo/p/fgmAs5qz6p5RWaNAzq40WAu7fJIXnQpYxFPbJYtsJPWvGeF2rOBaY/kEuV77AVsX8TsQzKm+A/g==",
"license": "MIT",
"dependencies": {
"@types/use-sync-external-store": "^0.0.6",
"use-sync-external-store": "^1.4.0"
},
"peerDependencies": {
"@types/react": "^18.2.25 || ^19",
"react": "^18.0 || ^19",
"redux": "^5.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"redux": {
"optional": true
}
}
},
"node_modules/react-refresh": {
"version": "0.14.2",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
@@ -7320,6 +7334,12 @@
"node": ">=8.10.0"
}
},
"node_modules/redux": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
"license": "MIT"
},
"node_modules/reflect.getprototypeof": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
@@ -7496,7 +7516,6 @@
"version": "4.40.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.0.tgz",
"integrity": "sha512-Noe455xmA96nnqH5piFtLobsGbCij7Tu+tb3c1vYjNbTkfzGqXqQXG3wJaYXkRZuQ0vEYN4bhwg7QnIrqB5B+w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/estree": "1.0.7"
@@ -7840,7 +7859,6 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
@@ -8352,6 +8370,12 @@
"integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==",
"license": "MIT"
},
"node_modules/tiny-invariant": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
"integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==",
"license": "MIT"
},
"node_modules/tiny-warning": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
@@ -8557,7 +8581,7 @@
"version": "5.6.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz",
"integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==",
"dev": true,
"devOptional": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
@@ -8745,6 +8769,15 @@
"punycode": "^2.1.0"
}
},
"node_modules/use-sync-external-store": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz",
"integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==",
"license": "MIT",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -8756,7 +8789,6 @@
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz",
"integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
"dev": true,
"license": "MIT",
"dependencies": {
"esbuild": "^0.25.0",
@@ -8861,7 +8893,6 @@
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12.0.0"
@@ -8879,7 +8910,6 @@
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@@ -9477,7 +9507,7 @@
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz",
"integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==",
"dev": true,
"devOptional": true,
"license": "ISC",
"bin": {
"yaml": "bin.mjs"
+1
View File
@@ -11,6 +11,7 @@
},
"dependencies": {
"@headlessui/react": "^2.2.0",
"@hello-pangea/dnd": "^18.0.1",
"@material-tailwind/react": "^2.1.10",
"@tanstack/react-query": "^5.62.8",
"axios": "^1.7.9",
+3
View File
@@ -166,4 +166,7 @@ export const Pages = {
create: "/reseller/create",
withdraw: "/reseller/withdraw",
},
taskmanager: {
workspace: "/taskmanager/workspace/",
},
};
+2
View File
@@ -4,6 +4,7 @@
html {
direction: rtl;
min-height: 100%;
}
body {
@@ -16,6 +17,7 @@ body {
background: #eceef6;
font-weight: 300;
overflow: hidden;
min-height: 100%;
}
html,
body,
+2 -1
View File
@@ -90,7 +90,8 @@
"domain": "دامنه",
"reseller": "نماینده",
"resellers": "نمایندگان",
"withdraw": "درخواست های برداشت"
"withdraw": "درخواست های برداشت",
"taskmanager": "مدیریت تسک ها"
},
"reseller": {
"list": "لیست نمایندکان",
@@ -0,0 +1,13 @@
import { AddCircle } from "iconsax-react";
import { type FC } from "react";
const AddNewColumn: FC = () => {
return (
<button type="button" className="bg-[#F0F3F7BF] bg-opacity-75 rounded-full px-6 py-4 flex items-center gap-2 shrink-0 self-start cursor-pointer">
<AddCircle size={16} color="black" />
<span className="text-xs text-black">اضافه کردن ستون جدید</span>
</button>
);
};
export default AddNewColumn;
+121
View File
@@ -0,0 +1,121 @@
import { Add, AddCircle, CloseCircle, More } from "iconsax-react";
import { useState, type FC } from "react";
import type { Column as ColumnType, Task as TaskType } from "../types";
import Task from "./Task";
type Props = {
column: ColumnType;
tasks: TaskType[];
draggedTaskId: string | null;
onDragStart: (taskId: string) => void;
onDragEnd: () => void;
onDrop: (columnId: string, index: number) => void;
};
const Column: FC<Props> = ({
column,
tasks,
draggedTaskId,
onDragStart,
onDragEnd,
onDrop,
}) => {
const [isAdding, setIsAdding] = useState(false);
const [isDragOver, setIsDragOver] = useState(false);
const handleDragOver = (e: React.DragEvent) => {
e.preventDefault();
e.dataTransfer.dropEffect = "move";
setIsDragOver(true);
};
const handleDragLeave = (e: React.DragEvent) => {
if (!e.currentTarget.contains(e.relatedTarget as Node)) {
setIsDragOver(false);
}
};
const handleDrop = (e: React.DragEvent, index: number) => {
e.preventDefault();
e.stopPropagation();
setIsDragOver(false);
onDrop(column.id, index);
};
return (
<div
className={`bg-[#F0F3F7] rounded-xl p-6 max-w-[310px] w-full flex flex-col self-start transition-colors ${
isDragOver ? "ring-2 ring-primary/40" : ""
}`}
onDragOver={handleDragOver}
onDragLeave={handleDragLeave}
onDrop={(e) => handleDrop(e, tasks.length)}
>
<div className="flex justify-between items-center shrink-0">
<div className="font-bold text-sm">{column.title}</div>
<More size={20} color="black" />
</div>
{tasks.length > 0 && (
<div className="mt-5 flex flex-col gap-4">
{tasks.map((task, index) => (
<div
key={task.id}
onDragOver={(e) => {
e.preventDefault();
e.stopPropagation();
}}
onDrop={(e) => handleDrop(e, index)}
>
<Task
task={task}
isDragging={draggedTaskId === task.id}
onDragStart={onDragStart}
onDragEnd={onDragEnd}
/>
</div>
))}
</div>
)}
{isAdding ? (
<div className="mt-5 shrink-0 flex flex-col gap-3">
<input
type="text"
placeholder="عنوان تسک"
className="w-full bg-white rounded-lg px-3 py-2.5 text-sm outline-none"
autoFocus
/>
<div className="flex items-center gap-2">
<button
type="button"
className="flex items-center gap-2 bg-black text-white text-[13px] rounded-full px-4 py-2 cursor-pointer"
>
<span>اضافه کردن</span>
<Add size={18} color="white" />
</button>
<button
type="button"
onClick={() => setIsAdding(false)}
className="cursor-pointer"
aria-label="انصراف"
>
<CloseCircle size={22} color="#888888" variant="Bold" />
</button>
</div>
</div>
) : (
<button
type="button"
onClick={() => setIsAdding(true)}
className="mt-5 flex gap-2 items-center shrink-0 cursor-pointer"
>
<AddCircle size={18} color="#888888" />
<span className="text-description text-[13px] mt-0.5">اضافه کردن تسک</span>
</button>
)}
</div>
);
};
export default Column;
@@ -0,0 +1,23 @@
import { InfoCircle, Setting2, UserAdd } from "iconsax-react";
const HeaderWorkspace = () => {
return (
<div className="flex justify-between items-center bg-primary h-[102px] px-8">
<div className="flex gap-4 items-center">
<div className="text-white text-xl">طراحی Dpage</div>
<InfoCircle size={20} color="white" />
</div>
<div className="flex gap-4 items-center">
<div className="flex gap-1 items-center px-2 rounded-lg bg-white h-8">
<UserAdd size={18} color="black" />
<div className="text-black text-xs">اشتراک گذاری</div>
</div>
<Setting2 size={20} color="white" />
</div>
</div>
);
};
export default HeaderWorkspace;
+52
View File
@@ -0,0 +1,52 @@
import { AttachCircle, Calendar, TickSquare } from "iconsax-react";
import { type FC } from "react";
import type { Task as TaskType } from "../types";
type Props = {
task: TaskType;
isDragging?: boolean;
onDragStart: (taskId: string) => void;
onDragEnd: () => void;
};
const Task: FC<Props> = ({ task, isDragging, onDragStart, onDragEnd }) => {
return (
<div
draggable
onDragStart={() => onDragStart(task.id)}
onDragEnd={onDragEnd}
className={`bg-white rounded-lg p-2 cursor-grab active:cursor-grabbing transition-opacity ${
isDragging ? "opacity-40" : ""
}`}
>
<div className="h-10 bg-yellow-500 rounded-lg"></div>
<div className="bg-[#FF76C2] h-5 px-3 flex items-center mt-2 text-[10px] text-white rounded-md w-fit">
{task.tag}
</div>
<div className="font-bold text-xs mt-2">{task.title}</div>
<div className="mt-2 flex items-center gap-4 text-xs">
<div className="flex items-center gap-1 text-[10px]">
<Calendar size={16} color="#292D32" />
<div>{task.dateRange}</div>
</div>
<div className="flex gap-1">
<AttachCircle size={16} color="#292D32" />
<div>{task.attachments}</div>
</div>
<div className="flex gap-1">
<TickSquare size={16} color="#292D32" />
<div>
{task.checklistDone}/{task.checklistTotal}
</div>
</div>
</div>
<div className="mt-2 flex justify-end">
<div className="size-6 bg-gray-200 rounded-full"></div>
</div>
</div>
);
};
export default Task;
+53
View File
@@ -0,0 +1,53 @@
{
"columns": [
{ "id": "todo", "title": "برای انجام" },
{ "id": "in-progress", "title": "درحال انجام" },
{ "id": "done", "title": "انجام شده" }
],
"tasks": [
{
"id": "task-1",
"columnId": "todo",
"order": 0,
"title": "اضافه شدن پیش نمایش",
"tag": "برچشب",
"dateRange": "۱ اردیبهشت - ۲۰ اردیبهشت",
"attachments": 1,
"checklistDone": 1,
"checklistTotal": 5
},
{
"id": "task-2",
"columnId": "todo",
"order": 1,
"title": "طراحی صفحه اصلی",
"tag": "طراحی",
"dateRange": "۵ اردیبهشت - ۱۵ اردیبهشت",
"attachments": 2,
"checklistDone": 3,
"checklistTotal": 8
},
{
"id": "task-3",
"columnId": "todo",
"order": 2,
"title": "بررسی فیدبک کاربران",
"tag": "بازبینی",
"dateRange": "۱۰ اردیبهشت - ۱۲ اردیبهشت",
"attachments": 0,
"checklistDone": 0,
"checklistTotal": 3
},
{
"id": "task-4",
"columnId": "done",
"order": 0,
"title": "تنظیمات اولیه پروژه",
"tag": "راه‌اندازی",
"dateRange": "۱ فروردین - ۵ فروردین",
"attachments": 1,
"checklistDone": 5,
"checklistTotal": 5
}
]
}
+21
View File
@@ -0,0 +1,21 @@
export type Column = {
id: string;
title: string;
};
export type Task = {
id: string;
columnId: string;
order: number;
title: string;
tag: string;
dateRange: string;
attachments: number;
checklistDone: number;
checklistTotal: number;
};
export type WorkspaceData = {
columns: Column[];
tasks: Task[];
};
@@ -0,0 +1,38 @@
import type { Task } from "../types";
export const reorderTasks = (
tasks: Task[],
taskId: string,
destColumnId: string,
destIndex: number,
): Task[] => {
const task = tasks.find((t) => t.id === taskId);
if (!task) return tasks;
const sourceColumnId = task.columnId;
const without = tasks.filter((t) => t.id !== taskId);
const destColumnTasks = without
.filter((t) => t.columnId === destColumnId)
.sort((a, b) => a.order - b.order);
destColumnTasks.splice(destIndex, 0, { ...task, columnId: destColumnId });
const updatedDest = destColumnTasks.map((t, i) => ({ ...t, order: i }));
if (sourceColumnId === destColumnId) {
const rest = without.filter((t) => t.columnId !== destColumnId);
return [...rest, ...updatedDest];
}
const sourceTasks = without
.filter((t) => t.columnId === sourceColumnId)
.sort((a, b) => a.order - b.order)
.map((t, i) => ({ ...t, order: i }));
const rest = without.filter(
(t) => t.columnId !== destColumnId && t.columnId !== sourceColumnId,
);
return [...rest, ...sourceTasks, ...updatedDest];
};
+59
View File
@@ -0,0 +1,59 @@
import { useMemo, useState, type FC } from "react";
import AddNewColumn from "./components/AddNewColumn";
import Column from "./components/Column";
import HeaderWorkspace from "./components/HeaderWorkspace";
import tasksData from "./data/tasks.json";
import type { Task, WorkspaceData } from "./types";
import { reorderTasks } from "./utils/reorderTasks";
const Workspace: FC = () => {
const { columns } = tasksData as WorkspaceData;
const [tasks, setTasks] = useState<Task[]>(tasksData.tasks as Task[]);
const [draggedTaskId, setDraggedTaskId] = useState<string | null>(null);
const tasksByColumn = useMemo(() => {
return columns.reduce<Record<string, Task[]>>((acc, column) => {
acc[column.id] = tasks
.filter((task) => task.columnId === column.id)
.sort((a, b) => a.order - b.order);
return acc;
}, {});
}, [columns, tasks]);
const handleDragStart = (taskId: string) => {
setDraggedTaskId(taskId);
};
const handleDragEnd = () => {
setDraggedTaskId(null);
};
const handleDrop = (columnId: string, index: number) => {
if (!draggedTaskId) return;
setTasks((prev) => reorderTasks(prev, draggedTaskId, columnId, index));
setDraggedTaskId(null);
};
return (
<div className="bg-[#01347A] h-full rounded-[32px] overflow-hidden flex flex-col">
<HeaderWorkspace />
<div className="px-8 flex gap-7 mt-6 flex-1 min-h-0 overflow-auto pb-6 items-start">
{columns.map((column) => (
<Column
key={column.id}
column={column}
tasks={tasksByColumn[column.id] ?? []}
draggedTaskId={draggedTaskId}
onDragStart={handleDragStart}
onDragEnd={handleDragEnd}
onDrop={handleDrop}
/>
))}
<AddNewColumn />
</div>
</div>
);
};
export default Workspace;
+214 -208
View File
@@ -1,220 +1,226 @@
import { FC } from 'react'
import SideBar from '../shared/SideBar'
import Header from '../shared/Header'
import { Route, Routes } from 'react-router-dom'
import { Pages } from '../config/Pages'
import Home from '../pages/home/Home'
import MyServices from '../pages/service/MyServices'
import DiscountsList from '../pages/discounts/DiscountsList'
import CreateDiscount from '../pages/discounts/CreateDiscount'
import AdsList from '../pages/ads/AdsList'
import BlogList from '../pages/blog/BlogList'
import CreateBlog from '../pages/blog/CreateBlog'
import BlogCategory from '../pages/blog/BlogCategory'
import CreateAds from '../pages/ads/CreateAds'
import TicketList from '../pages/ticket/TicketList'
import CreateTicket from '../pages/ticket/CreateTicket'
import TicketDetail from '../pages/ticket/Detail'
import TransactionList from '../pages/transaction/List'
import ReceiptsList from '../pages/receipts/List'
import AnnouncementtList from '../pages/annoncement/List'
import LearningList from '../pages/learning/List'
import Setting from '../pages/setting/Setting'
import Wallet from '../pages/wallet/Wallet'
import ReceiptsDetail from '../pages/receipts/Detail'
import Profile from '../pages/profile/Profile'
import OtherServices from '../pages/service/OtherServices'
import Footer from '../shared/Footer'
import DetailService from '../pages/service/DetailService'
import { clx } from '../helpers/utils'
import { useSharedStore } from '../shared/store/sharedStore'
import CreateReceipt from '../pages/receipts/Create'
import AddService from '../pages/service/AddService'
import ListService from '../pages/service/List'
import Category from '../pages/service/Category'
import CustomerList from '../pages/customer/List'
import CreateCustomer from '../pages/customer/Create'
import TicketCategory from '../pages/ticket/Category'
import MessagesList from '../pages/messages/List'
import CriticismsList from '../pages/criticisms/List'
import CriticismsDetail from '../pages/criticisms/Detail'
import Create from '../pages/annoncement/Create'
import UsersList from '../pages/users/List'
import CreateUser from '../pages/users/Create'
import RolesList from '../pages/users/RolesList'
import RoleCreate from '../pages/users/RoleCreate'
import MessageDetail from '../pages/messages/Detail'
import CreateBankCard from '../pages/cardBank/Create'
import CardBankList from '../pages/cardBank/List'
import EditBankCard from '../pages/cardBank/Edit'
import PaymentList from '../pages/payment/List'
import LearningCategory from '../pages/learning/Category'
import CreateLearning from '../pages/learning/Create'
import Plans from '../pages/service/Plans'
import GroupCreate from '../pages/users/GroupCreate'
import GroupList from '../pages/users/GroupList'
import Reviews from '../pages/service/Reviews'
import UpdateAds from '../pages/ads/Update'
import UpdateService from '../pages/service/UpdateService'
import UpdateCustomer from '../pages/customer/Update'
import UpdateBlog from '../pages/blog/Update'
import Update from '../pages/annoncement/Update'
import UpdateDiscount from '../pages/discounts/UpdateDiscount'
import UpdateUser from '../pages/users/Update'
import CreateSlider from '../pages/slider/Create'
import SliderList from '../pages/slider/List'
import UpdateSlider from '../pages/slider/Update'
import Comments from '../pages/blog/Comments'
import CreatePlan from '../pages/support/Create'
import SupportList from '../pages/support/List'
import UpdateSupport from '../pages/support/Update'
import PlanUsers from '../pages/support/PlanUsers'
import List from '../pages/guide/List'
import CreateGuide from '../pages/guide/Create'
import UpdateGuide from '../pages/guide/Update.tsx'
import ListFeedback from '../pages/feedback/List'
import AccessLogsList from '../pages/accessLogs/AccessLogsList'
import AccessLogsStats from '../pages/accessLogs/AccessLogsStats'
import ErrorLogs from '../pages/accessLogs/ErrorLogs'
import PermissionLogs from '../pages/accessLogs/PermissionLogs'
import IconsList from '../pages/dmenu/icon/List'
import GroupIconList from '../pages/dmenu/icon/GroupList'
import WarningsList from '../pages/dmenu/report/List.tsx'
import RestaurantsList from '../pages/dmenu/restaurant/List.tsx'
import SmsCountList from '../pages/dmenu/restaurant/SmsCountList.tsx'
import UpdateRestaurant from '../pages/dmenu/restaurant/Update.tsx'
import DkalaIconsList from '../pages/dkala/icon/List'
import DkalaGroupIconList from '../pages/dkala/icon/GroupList'
import DkalaWarningsList from '../pages/dkala/report/List.tsx'
import ShopsList from '../pages/dkala/shop/List.tsx'
import DkalaSmsCountList from '../pages/dkala/shop/SmsCountList.tsx'
import UpdateShop from '../pages/dkala/shop/Update.tsx'
import DpageStickersList from '../pages/dpage/sticker/List'
import SubscriptionsList from '../pages/subscriptions/List.tsx'
import Domains from '../pages/dmail/Domains.tsx'
import ResellerList from '../pages/reseller/List.tsx'
import CreateReseller from '../pages/reseller/Create.tsx'
import Withdraw from '../pages/reseller/Withdraw.tsx'
import { FC } from "react";
import { Route, Routes, useLocation } from "react-router-dom";
import { Pages } from "../config/Pages";
import { clx } from "../helpers/utils";
import AccessLogsList from "../pages/accessLogs/AccessLogsList";
import AccessLogsStats from "../pages/accessLogs/AccessLogsStats";
import ErrorLogs from "../pages/accessLogs/ErrorLogs";
import PermissionLogs from "../pages/accessLogs/PermissionLogs";
import AdsList from "../pages/ads/AdsList";
import CreateAds from "../pages/ads/CreateAds";
import UpdateAds from "../pages/ads/Update";
import Create from "../pages/annoncement/Create";
import AnnouncementtList from "../pages/annoncement/List";
import Update from "../pages/annoncement/Update";
import BlogCategory from "../pages/blog/BlogCategory";
import BlogList from "../pages/blog/BlogList";
import Comments from "../pages/blog/Comments";
import CreateBlog from "../pages/blog/CreateBlog";
import UpdateBlog from "../pages/blog/Update";
import CreateBankCard from "../pages/cardBank/Create";
import EditBankCard from "../pages/cardBank/Edit";
import CardBankList from "../pages/cardBank/List";
import CriticismsDetail from "../pages/criticisms/Detail";
import CriticismsList from "../pages/criticisms/List";
import CreateCustomer from "../pages/customer/Create";
import CustomerList from "../pages/customer/List";
import UpdateCustomer from "../pages/customer/Update";
import CreateDiscount from "../pages/discounts/CreateDiscount";
import DiscountsList from "../pages/discounts/DiscountsList";
import UpdateDiscount from "../pages/discounts/UpdateDiscount";
import DkalaGroupIconList from "../pages/dkala/icon/GroupList";
import DkalaIconsList from "../pages/dkala/icon/List";
import DkalaWarningsList from "../pages/dkala/report/List.tsx";
import ShopsList from "../pages/dkala/shop/List.tsx";
import DkalaSmsCountList from "../pages/dkala/shop/SmsCountList.tsx";
import UpdateShop from "../pages/dkala/shop/Update.tsx";
import Domains from "../pages/dmail/Domains.tsx";
import GroupIconList from "../pages/dmenu/icon/GroupList";
import IconsList from "../pages/dmenu/icon/List";
import WarningsList from "../pages/dmenu/report/List.tsx";
import RestaurantsList from "../pages/dmenu/restaurant/List.tsx";
import SmsCountList from "../pages/dmenu/restaurant/SmsCountList.tsx";
import UpdateRestaurant from "../pages/dmenu/restaurant/Update.tsx";
import DpageStickersList from "../pages/dpage/sticker/List";
import ListFeedback from "../pages/feedback/List";
import CreateGuide from "../pages/guide/Create";
import List from "../pages/guide/List";
import UpdateGuide from "../pages/guide/Update.tsx";
import Home from "../pages/home/Home";
import LearningCategory from "../pages/learning/Category";
import CreateLearning from "../pages/learning/Create";
import LearningList from "../pages/learning/List";
import MessageDetail from "../pages/messages/Detail";
import MessagesList from "../pages/messages/List";
import PaymentList from "../pages/payment/List";
import Profile from "../pages/profile/Profile";
import CreateReceipt from "../pages/receipts/Create";
import ReceiptsDetail from "../pages/receipts/Detail";
import ReceiptsList from "../pages/receipts/List";
import CreateReseller from "../pages/reseller/Create.tsx";
import ResellerList from "../pages/reseller/List.tsx";
import Withdraw from "../pages/reseller/Withdraw.tsx";
import AddService from "../pages/service/AddService";
import Category from "../pages/service/Category";
import DetailService from "../pages/service/DetailService";
import ListService from "../pages/service/List";
import MyServices from "../pages/service/MyServices";
import OtherServices from "../pages/service/OtherServices";
import Plans from "../pages/service/Plans";
import Reviews from "../pages/service/Reviews";
import UpdateService from "../pages/service/UpdateService";
import Setting from "../pages/setting/Setting";
import CreateSlider from "../pages/slider/Create";
import SliderList from "../pages/slider/List";
import UpdateSlider from "../pages/slider/Update";
import SubscriptionsList from "../pages/subscriptions/List.tsx";
import CreatePlan from "../pages/support/Create";
import SupportList from "../pages/support/List";
import PlanUsers from "../pages/support/PlanUsers";
import UpdateSupport from "../pages/support/Update";
import Workspace from "../pages/taskmanager/workspace.tsx";
import TicketCategory from "../pages/ticket/Category";
import CreateTicket from "../pages/ticket/CreateTicket";
import TicketDetail from "../pages/ticket/Detail";
import TicketList from "../pages/ticket/TicketList";
import TransactionList from "../pages/transaction/List";
import CreateUser from "../pages/users/Create";
import GroupCreate from "../pages/users/GroupCreate";
import GroupList from "../pages/users/GroupList";
import UsersList from "../pages/users/List";
import RoleCreate from "../pages/users/RoleCreate";
import RolesList from "../pages/users/RolesList";
import UpdateUser from "../pages/users/Update";
import Wallet from "../pages/wallet/Wallet";
import Footer from "../shared/Footer";
import Header from "../shared/Header";
import SideBar from "../shared/SideBar";
import { useSharedStore } from "../shared/store/sharedStore";
// import WarningsList from '../pages/dmenu/reports/List' // TODO: Create this component
const MainRouter: FC = () => {
const { hasSubMenu } = useSharedStore();
const { pathname } = useLocation();
const isWorkspace = pathname.startsWith(Pages.taskmanager.workspace);
const { hasSubMenu } = useSharedStore()
return (
<div className="p-4 overflow-hidden">
{!isWorkspace && <SideBar />}
<Header />
<div
className={clx(
"flex-1 mt-[68px] xl:mt-[81px]",
!isWorkspace && "xl:ms-[269px]",
!isWorkspace && hasSubMenu && "xl:ms-[305px]",
)}
>
<div className={clx(`overflow-auto w-[${window.innerWidth}] h-[calc(100vh-113px)] flex flex-col`)}>
<div className="flex-1 min-h-0">
<Routes>
<Route path={Pages.dashboard} element={<Home />} />
<Route path={Pages.services.mine} element={<MyServices />} />
<Route path={Pages.services.other} element={<OtherServices />} />
<Route path={Pages.services.detail + ":id"} element={<DetailService />} />
<Route path={Pages.services.add} element={<AddService />} />
<Route path={Pages.services.list} element={<ListService />} />
<Route path={Pages.services.update + ":id"} element={<UpdateService />} />
<Route path={Pages.services.category} element={<Category />} />
<Route path={Pages.services.plan + ":id"} element={<Plans />} />
<Route path={Pages.services.review} element={<Reviews />} />
<Route path={Pages.ticket.list} element={<TicketList />} />
<Route path={Pages.ticket.create} element={<CreateTicket />} />
<Route path={Pages.ticket.category} element={<TicketCategory />} />
<Route path={Pages.ticket.detail + ":id"} element={<TicketDetail />} />
<Route path={Pages.ads.list} element={<AdsList />} />
<Route path={Pages.ads.create} element={<CreateAds />} />
<Route path={Pages.ads.update + ":id"} element={<UpdateAds />} />
<Route path={Pages.discount.list} element={<DiscountsList />} />
<Route path={Pages.discount.create} element={<CreateDiscount />} />
<Route path={Pages.discount.detail + ":id"} element={<UpdateDiscount />} />
<Route path={Pages.blog.list} element={<BlogList />} />
<Route path={Pages.blog.create} element={<CreateBlog />} />
<Route path={Pages.blog.category} element={<BlogCategory />} />
<Route path={Pages.blog.detail + ":id"} element={<UpdateBlog />} />
<Route path={Pages.transactions} element={<TransactionList />} />
<Route path={Pages.receipts.index} element={<ReceiptsList />} />
<Route path={Pages.receipts.detail + ":id"} element={<ReceiptsDetail />} />
<Route path={Pages.receipts.create} element={<CreateReceipt />} />
<Route path={Pages.announcement.list} element={<AnnouncementtList />} />
<Route path={Pages.announcement.detail + ":id"} element={<Update />} />
<Route path={Pages.announcement.create} element={<Create />} />
<Route path={Pages.criticisms.list} element={<CriticismsList />} />
<Route path={Pages.criticisms.detail + ":id"} element={<CriticismsDetail />} />
<Route path={Pages.learning.list} element={<LearningList />} />
<Route path={Pages.learning.create} element={<CreateLearning />} />
<Route path={Pages.learning.category} element={<LearningCategory />} />
<Route path={Pages.setting} element={<Setting />} />
<Route path={Pages.wallet} element={<Wallet />} />
<Route path={Pages.profile} element={<Profile />} />
<Route path={Pages.customer.list} element={<CustomerList />} />
<Route path={Pages.customer.create} element={<CreateCustomer />} />
<Route path={Pages.customer.update + ":id"} element={<UpdateCustomer />} />
<Route path={Pages.messages.list} element={<MessagesList />} />
<Route path={Pages.messages.detail + ":id"} element={<MessageDetail />} />
<Route path={Pages.users.list} element={<UsersList />} />
<Route path={Pages.users.create} element={<CreateUser />} />
<Route path={Pages.users.detail + ":id"} element={<UpdateUser />} />
<Route path={Pages.users.roleList} element={<RolesList />} />
<Route path={Pages.users.roleCreate} element={<RoleCreate />} />
<Route path={Pages.users.groupAdd} element={<GroupCreate />} />
<Route path={Pages.users.groupList} element={<GroupList />} />
<Route path={Pages.cardBank.create} element={<CreateBankCard />} />
<Route path={Pages.cardBank.list} element={<CardBankList />} />
<Route path={Pages.cardBank.detail + ":id"} element={<EditBankCard />} />
<Route path={Pages.payment.list} element={<PaymentList />} />
<Route path={Pages.sliders.create} element={<CreateSlider />} />
<Route path={Pages.sliders.list} element={<SliderList />} />
<Route path={Pages.sliders.detail + ":id"} element={<UpdateSlider />} />
<Route path={Pages.blog.comments} element={<Comments />} />
<Route path={Pages.support.create} element={<CreatePlan />} />
<Route path={Pages.support.list} element={<SupportList />} />
<Route path={Pages.support.detail + ":id"} element={<UpdateSupport />} />
<Route path={Pages.support.planUsers + ":id"} element={<PlanUsers />} />
<Route path={Pages.services.guide + ":id"} element={<List />} />
<Route path={Pages.services.guide + ":id/create"} element={<CreateGuide />} />
<Route path={Pages.services.guide + ":id/:guideId"} element={<UpdateGuide />} />
<Route path={Pages.feedback.list} element={<ListFeedback />} />
<Route path={Pages.accessLogs.list} element={<AccessLogsList />} />
<Route path={Pages.accessLogs.stats} element={<AccessLogsStats />} />
<Route path={Pages.accessLogs.errors} element={<ErrorLogs />} />
<Route path={Pages.accessLogs.permissions} element={<PermissionLogs />} />
return (
<div className='p-4 overflow-hidden'>
<SideBar />
<Header />
<div className={clx(
'flex-1 xl:ms-[269px] mt-[68px] xl:mt-[81px]',
hasSubMenu && 'xl:ms-[305px]',
)}>
<div className={clx(
`overflow-auto w-[${window.innerWidth}] max-h-[calc(100vh-113px)]`,
)}>
<div className='pb-20'>
<Routes>
<Route path={Pages.dashboard} element={<Home />} />
<Route path={Pages.services.mine} element={<MyServices />} />
<Route path={Pages.services.other} element={<OtherServices />} />
<Route path={Pages.services.detail + ':id'} element={<DetailService />} />
<Route path={Pages.services.add} element={<AddService />} />
<Route path={Pages.services.list} element={<ListService />} />
<Route path={Pages.services.update + ':id'} element={<UpdateService />} />
<Route path={Pages.services.category} element={<Category />} />
<Route path={Pages.services.plan + ':id'} element={<Plans />} />
<Route path={Pages.services.review} element={<Reviews />} />
<Route path={Pages.ticket.list} element={<TicketList />} />
<Route path={Pages.ticket.create} element={<CreateTicket />} />
<Route path={Pages.ticket.category} element={<TicketCategory />} />
<Route path={Pages.ticket.detail + ':id'} element={<TicketDetail />} />
<Route path={Pages.ads.list} element={<AdsList />} />
<Route path={Pages.ads.create} element={<CreateAds />} />
<Route path={Pages.ads.update + ':id'} element={<UpdateAds />} />
<Route path={Pages.discount.list} element={<DiscountsList />} />
<Route path={Pages.discount.create} element={<CreateDiscount />} />
<Route path={Pages.discount.detail + ':id'} element={<UpdateDiscount />} />
<Route path={Pages.blog.list} element={<BlogList />} />
<Route path={Pages.blog.create} element={<CreateBlog />} />
<Route path={Pages.blog.category} element={<BlogCategory />} />
<Route path={Pages.blog.detail + ':id'} element={<UpdateBlog />} />
<Route path={Pages.transactions} element={<TransactionList />} />
<Route path={Pages.receipts.index} element={<ReceiptsList />} />
<Route path={Pages.receipts.detail + ':id'} element={<ReceiptsDetail />} />
<Route path={Pages.receipts.create} element={<CreateReceipt />} />
<Route path={Pages.announcement.list} element={<AnnouncementtList />} />
<Route path={Pages.announcement.detail + ':id'} element={<Update />} />
<Route path={Pages.announcement.create} element={<Create />} />
<Route path={Pages.criticisms.list} element={<CriticismsList />} />
<Route path={Pages.criticisms.detail + ':id'} element={<CriticismsDetail />} />
<Route path={Pages.learning.list} element={<LearningList />} />
<Route path={Pages.learning.create} element={<CreateLearning />} />
<Route path={Pages.learning.category} element={<LearningCategory />} />
<Route path={Pages.setting} element={<Setting />} />
<Route path={Pages.wallet} element={<Wallet />} />
<Route path={Pages.profile} element={<Profile />} />
<Route path={Pages.customer.list} element={<CustomerList />} />
<Route path={Pages.customer.create} element={<CreateCustomer />} />
<Route path={Pages.customer.update + ':id'} element={<UpdateCustomer />} />
<Route path={Pages.messages.list} element={<MessagesList />} />
<Route path={Pages.messages.detail + ':id'} element={<MessageDetail />} />
<Route path={Pages.users.list} element={<UsersList />} />
<Route path={Pages.users.create} element={<CreateUser />} />
<Route path={Pages.users.detail + ':id'} element={<UpdateUser />} />
<Route path={Pages.users.roleList} element={<RolesList />} />
<Route path={Pages.users.roleCreate} element={<RoleCreate />} />
<Route path={Pages.users.groupAdd} element={<GroupCreate />} />
<Route path={Pages.users.groupList} element={<GroupList />} />
<Route path={Pages.cardBank.create} element={<CreateBankCard />} />
<Route path={Pages.cardBank.list} element={<CardBankList />} />
<Route path={Pages.cardBank.detail + ':id'} element={<EditBankCard />} />
<Route path={Pages.payment.list} element={<PaymentList />} />
<Route path={Pages.sliders.create} element={<CreateSlider />} />
<Route path={Pages.sliders.list} element={<SliderList />} />
<Route path={Pages.sliders.detail + ':id'} element={<UpdateSlider />} />
<Route path={Pages.blog.comments} element={<Comments />} />
<Route path={Pages.support.create} element={<CreatePlan />} />
<Route path={Pages.support.list} element={<SupportList />} />
<Route path={Pages.support.detail + ':id'} element={<UpdateSupport />} />
<Route path={Pages.support.planUsers + ':id'} element={<PlanUsers />} />
<Route path={Pages.services.guide + ':id'} element={<List />} />
<Route path={Pages.services.guide + ':id/create'} element={<CreateGuide />} />
<Route path={Pages.services.guide + ':id/:guideId'} element={<UpdateGuide />} />
<Route path={Pages.feedback.list} element={<ListFeedback />} />
<Route path={Pages.accessLogs.list} element={<AccessLogsList />} />
<Route path={Pages.accessLogs.stats} element={<AccessLogsStats />} />
<Route path={Pages.accessLogs.errors} element={<ErrorLogs />} />
<Route path={Pages.accessLogs.permissions} element={<PermissionLogs />} />
<Route path={Pages.dmenu.icons.list} element={<IconsList />} />
<Route path={Pages.dmenu.icons.groupList} element={<GroupIconList />} />
<Route path={Pages.dmenu.warnings.list} element={<WarningsList />} />
<Route path={Pages.dmenu.restaurants.list} element={<RestaurantsList />} />
<Route path={Pages.dmenu.restaurants.smsCountList} element={<SmsCountList />} />
<Route path={Pages.dmenu.restaurants.update + ":id"} element={<UpdateRestaurant />} />
<Route path={Pages.dmenu.icons.list} element={<IconsList />} />
<Route path={Pages.dmenu.icons.groupList} element={<GroupIconList />} />
<Route path={Pages.dmenu.warnings.list} element={<WarningsList />} />
<Route path={Pages.dmenu.restaurants.list} element={<RestaurantsList />} />
<Route path={Pages.dmenu.restaurants.smsCountList} element={<SmsCountList />} />
<Route path={Pages.dmenu.restaurants.update + ':id'} element={<UpdateRestaurant />} />
<Route path={Pages.dkala.icons.list} element={<DkalaIconsList />} />
<Route path={Pages.dkala.icons.groupList} element={<DkalaGroupIconList />} />
<Route path={Pages.dkala.warnings.list} element={<DkalaWarningsList />} />
<Route path={Pages.dkala.shops.list} element={<ShopsList />} />
<Route path={Pages.dkala.shops.smsCountList} element={<DkalaSmsCountList />} />
<Route path={Pages.dkala.shops.update + ":id"} element={<UpdateShop />} />
<Route path={Pages.dkala.icons.list} element={<DkalaIconsList />} />
<Route path={Pages.dkala.icons.groupList} element={<DkalaGroupIconList />} />
<Route path={Pages.dkala.warnings.list} element={<DkalaWarningsList />} />
<Route path={Pages.dkala.shops.list} element={<ShopsList />} />
<Route path={Pages.dkala.shops.smsCountList} element={<DkalaSmsCountList />} />
<Route path={Pages.dkala.shops.update + ':id'} element={<UpdateShop />} />
<Route path={Pages.dpage.stickers.list} element={<DpageStickersList />} />
<Route path={Pages.dpage.stickers.list} element={<DpageStickersList />} />
<Route path={Pages.subscriptions.list} element={<SubscriptionsList />} />
<Route path={Pages.subscriptions.list} element={<SubscriptionsList />} />
<Route path={Pages.dmail.list} element={<Domains />} />
<Route path={Pages.dmail.list} element={<Domains />} />
<Route path={Pages.reseller.list} element={<ResellerList />} />
<Route path={Pages.reseller.create} element={<CreateReseller />} />
<Route path={Pages.reseller.withdraw} element={<Withdraw />} />
<Route path={Pages.reseller.list} element={<ResellerList />} />
<Route path={Pages.reseller.create} element={<CreateReseller />} />
<Route path={Pages.reseller.withdraw} element={<Withdraw />} />
</Routes>
</div>
</div>
</div>
<Footer />
<Route path={Pages.taskmanager.workspace + ":slug"} element={<Workspace />} />
</Routes>
</div>
<div className="h-20 shrink-0 xl:hidden" />
</div>
)
}
</div>
<Footer />
</div>
);
};
export default MainRouter
export default MainRouter;
+6 -1
View File
@@ -5,6 +5,7 @@ import AvatarImage from '../assets/images/avatar_image.png'
import { useTranslation } from 'react-i18next'
import { Link, useLocation } from 'react-router-dom'
import { Pages } from '../config/Pages'
import { clx } from '../helpers/utils'
import Notifications from '../pages/notification/Notification'
import { useSharedStore } from './store/sharedStore'
import { useGetProfile } from '../pages/profile/hooks/useProfileData'
@@ -14,6 +15,7 @@ import { removeRefreshToken, removeToken } from '../config/func'
const Header: FC = () => {
const location = useLocation();
const isWorkspace = location.pathname.startsWith(Pages.taskmanager.workspace);
const [popoverKey, setPopoverKey] = useState(0);
const { t } = useTranslation('global')
const { setOpenSidebar, openSidebar } = useSharedStore()
@@ -30,7 +32,10 @@ const Header: FC = () => {
}
return (
<div className='fixed z-10 right-4 left-4 xl:right-[285px] top-4 xl:h-16 h-12 flex items-center px-6 bg-white justify-between rounded-[32px] xl:w-[calc(100%-305px)]'>
<div className={clx(
'fixed z-10 right-4 left-4 top-4 xl:h-16 h-12 flex items-center px-6 bg-white justify-between rounded-[32px]',
!isWorkspace && 'xl:right-[285px] xl:w-[calc(100%-305px)]',
)}>
<div className='min-w-[270px] hidden xl:block'>
<Input
+100 -514
View File
@@ -27,6 +27,7 @@ import {
Setting2,
Sms,
SmsTracking,
Task,
Teacher,
TicketDiscount,
UserSquare,
@@ -56,14 +57,7 @@ import SideBarItem from "./SideBarItem";
import { useSharedStore } from "./store/sharedStore";
const SideBar: FC = () => {
const { t } = useTranslation("global");
const {
openSidebar,
setOpenSidebar,
hasSubMenu,
setSubMenuName,
setSubtMenu,
subMenuName,
} = useSharedStore();
const { openSidebar, setOpenSidebar, hasSubMenu, setSubMenuName, setSubtMenu, subMenuName } = useSharedStore();
const location = useLocation();
const { data: profile } = useGetProfile();
const { data: adminPermissions } = useGetAdminPermissions();
@@ -102,12 +96,7 @@ const SideBar: FC = () => {
return (
<>
{openSidebar && (
<div
className="fixed top-0 left-0 right-0 bottom-0 bg-black bg-opacity-50 z-10"
onClick={() => setOpenSidebar(false)}
/>
)}
{openSidebar && <div className="fixed top-0 left-0 right-0 bottom-0 bg-black bg-opacity-50 z-10" onClick={() => setOpenSidebar(false)} />}
<div
className={clx(
"fixed xl:flex translate-x-[400px] xl:translate-x-0 transition-all ease-in-out opacity-0 invisible xl:visible xl:opacity-100 xl:right-4 right-0 xl:top-4 top-0 xl:bottom-4 bottom-0 xl:rounded-[32px] w-[250px] bg-white flex-col py-12",
@@ -115,63 +104,30 @@ const SideBar: FC = () => {
hasSubMenu && "w-24 !rounded-tl-none !rounded-bl-none",
)}
>
<div className="flex justify-center">
{!hasSubMenu ? (
<img src={LogoImage} className="w-[140px]" />
) : (
<img src={LogoSmall} className="w-7" />
)}
</div>
<div className="flex justify-center">{!hasSubMenu ? <img src={LogoImage} className="w-[140px]" /> : <img src={LogoSmall} className="w-7" />}</div>
<div className="flex-1 flex flex-col h-full overflow-y-auto no-scrollbar">
<div
onClick={() => handleOpenMenu("menu")}
className={clx(
"mt-10 px-12 text-header text-sm font-normal cursor-pointer",
hasSubMenu && "px-2 text-center",
!hasSubMenu && "flex gap-2 items-center",
)}
className={clx("mt-10 px-12 text-header text-sm font-normal cursor-pointer", hasSubMenu && "px-2 text-center", !hasSubMenu && "flex gap-2 items-center")}
>
{t("sidebar.menu")}
<div
className={clx(
"transition-all",
!openMenu.includes("menu") && "rotate-180",
hasSubMenu && "hidden",
)}
>
<div className={clx("transition-all", !openMenu.includes("menu") && "rotate-180", hasSubMenu && "hidden")}>
<ArrowDown2 size={18} color="#c3c7dd" />
</div>
</div>
<div
className={clx(
"text-xs text-[#8C90A3]",
!openMenu.includes("menu") && "hidden",
)}
>
<div className={clx("text-xs text-[#8C90A3]", !openMenu.includes("menu") && "hidden")}>
<SideBarItem
icon={
<Home2
variant={isActive("dashboard") ? "Bold" : "Outline"}
color={isActive("dashboard") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<Home2 variant={isActive("dashboard") ? "Bold" : "Outline"} color={isActive("dashboard") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.mainpage")}
isActive={isActive("dashboard")}
link={Pages.dashboard}
activeName=""
/>
<SideBarItem
icon={
<Element3
variant={isActive("services") ? "Bold" : "Outline"}
color={isActive("services") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<Element3 variant={isActive("services") ? "Bold" : "Outline"} color={isActive("services") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.services")}
isActive={isActive("services")}
link={Pages.services.list}
@@ -180,13 +136,7 @@ const SideBar: FC = () => {
/>
<SideBarItem
icon={
<Headphone
variant={isActive("support") ? "Bold" : "Outline"}
color={isActive("support") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<Headphone variant={isActive("support") ? "Bold" : "Outline"} color={isActive("support") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.support")}
isActive={isActive("support")}
link={Pages.support.list}
@@ -194,39 +144,21 @@ const SideBar: FC = () => {
/>
<SideBarItem
icon={
<People
variant={isActive("customers") ? "Bold" : "Outline"}
color={isActive("customers") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<People variant={isActive("customers") ? "Bold" : "Outline"} color={isActive("customers") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.customers")}
isActive={isActive("customers")}
link={Pages.customers.list}
activeName="customers"
/>
<SideBarItem
icon={
<UserSquare
variant={isActive("representatives") ? "Bold" : "Outline"}
color={isActive("representatives") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<UserSquare variant={isActive("representatives") ? "Bold" : "Outline"} color={isActive("representatives") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.representatives")}
isActive={isActive("representatives")}
link={Pages.representative.list}
activeName="agents"
/>
<SideBarItem
icon={
<CodeCircle
variant={isActive("developers") ? "Bold" : "Outline"}
color={isActive("developers") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<CodeCircle variant={isActive("developers") ? "Bold" : "Outline"} color={isActive("developers") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.developers")}
isActive={isActive("developers")}
link={Pages.developers.list}
@@ -234,13 +166,7 @@ const SideBar: FC = () => {
/>
<SideBarItem
icon={
<Money3
variant={isActive("payments") ? "Bold" : "Outline"}
color={isActive("payments") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<Money3 variant={isActive("payments") ? "Bold" : "Outline"} color={isActive("payments") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.payments")}
isActive={isActive("payments")}
link={Pages.payment.list}
@@ -248,39 +174,21 @@ const SideBar: FC = () => {
/>
<SideBarItem
icon={
<Code
variant={isActive("referral-code") ? "Bold" : "Outline"}
color={isActive("referral-code") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<Code variant={isActive("referral-code") ? "Bold" : "Outline"} color={isActive("referral-code") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.code_referral")}
isActive={isActive("referral-code")}
link={Pages.referralCode.list}
activeName="referralCode"
/>
<SideBarItem
icon={
<Profile
variant={isActive("users") ? "Bold" : "Outline"}
color={isActive("users") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<Profile variant={isActive("users") ? "Bold" : "Outline"} color={isActive("users") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.users")}
isActive={isActive("users")}
link={Pages.users.list}
activeName="admins"
/>
<SideBarItem
icon={
<Gallery
variant={isActive("sliders") ? "Bold" : "Outline"}
color={isActive("sliders") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<Gallery variant={isActive("sliders") ? "Bold" : "Outline"} color={isActive("sliders") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.sliders")}
isActive={isActive("sliders")}
link={Pages.sliders.list}
@@ -291,39 +199,18 @@ const SideBar: FC = () => {
{
<div
onClick={() => handleOpenMenu("financial")}
className={clx(
"mt-10 px-12 text-header text-sm font-normal cursor-pointer",
hasSubMenu && "px-2 text-center",
!hasSubMenu && "flex gap-2 items-center",
)}
className={clx("mt-10 px-12 text-header text-sm font-normal cursor-pointer", hasSubMenu && "px-2 text-center", !hasSubMenu && "flex gap-2 items-center")}
>
{t("sidebar.financial")}
<div
className={clx(
"transition-all",
!openMenu.includes("financial") && "rotate-180",
hasSubMenu && "hidden",
)}
>
<div className={clx("transition-all", !openMenu.includes("financial") && "rotate-180", hasSubMenu && "hidden")}>
<ArrowDown2 size={18} color="#c3c7dd" />
</div>
</div>
}
<div
className={clx(
"text-xs text-[#8C90A3]",
!openMenu.includes("financial") && "hidden",
)}
>
<div className={clx("text-xs text-[#8C90A3]", !openMenu.includes("financial") && "hidden")}>
<SideBarItem
icon={
<BagTick
variant={isActive("subscriptions") ? "Bold" : "Outline"}
color={isActive("subscriptions") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<BagTick variant={isActive("subscriptions") ? "Bold" : "Outline"} color={isActive("subscriptions") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.subscriptions")}
isActive={isActive("subscriptions")}
link={Pages.subscriptions.list}
@@ -331,13 +218,7 @@ const SideBar: FC = () => {
/>
<SideBarItem
icon={
<Receipt21
variant={isActive("receipts") ? "Bold" : "Outline"}
color={isActive("receipts") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<Receipt21 variant={isActive("receipts") ? "Bold" : "Outline"} color={isActive("receipts") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.receipt_list")}
isActive={isActive("receipts")}
link={Pages.receipts.index}
@@ -345,13 +226,7 @@ const SideBar: FC = () => {
/>
<SideBarItem
icon={
<Card
variant={isActive("transactions") ? "Bold" : "Outline"}
color={isActive("transactions") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<Card variant={isActive("transactions") ? "Bold" : "Outline"} color={isActive("transactions") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.transactions")}
isActive={isActive("transactions")}
link={Pages.transactions}
@@ -359,13 +234,7 @@ const SideBar: FC = () => {
/>
<SideBarItem
icon={
<TicketDiscount
variant={isActive("discounts") ? "Bold" : "Outline"}
color={isActive("discounts") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<TicketDiscount variant={isActive("discounts") ? "Bold" : "Outline"} color={isActive("discounts") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.discounts")}
isActive={isActive("discounts")}
link={Pages.discount.list}
@@ -373,13 +242,7 @@ const SideBar: FC = () => {
/>
<SideBarItem
icon={
<Card
variant={isActive("card") ? "Bold" : "Outline"}
color={isActive("card") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<Card variant={isActive("card") ? "Bold" : "Outline"} color={isActive("card") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.card")}
isActive={isActive("card")}
link={Pages.cardBank.list}
@@ -387,45 +250,22 @@ const SideBar: FC = () => {
/>
</div>
{profile?.data?.user?.roles.some(
(role: { name: string }) => role.name === "super_admin",
) && (
{profile?.data?.user?.roles.some((role: { name: string }) => role.name === "super_admin") && (
<div
onClick={() => handleOpenMenu("other")}
className={clx(
"mt-10 px-12 text-header text-sm font-normal cursor-pointer",
hasSubMenu && "px-2 text-center",
!hasSubMenu && "flex gap-2 items-center",
)}
className={clx("mt-10 px-12 text-header text-sm font-normal cursor-pointer", hasSubMenu && "px-2 text-center", !hasSubMenu && "flex gap-2 items-center")}
>
{t("sidebar.other")}
<div
className={clx(
"transition-all",
!openMenu.includes("other") && "rotate-180",
hasSubMenu && "hidden",
)}
>
<div className={clx("transition-all", !openMenu.includes("other") && "rotate-180", hasSubMenu && "hidden")}>
<ArrowDown2 size={18} color="#c3c7dd" />
</div>
</div>
)}
<div
className={clx(
"text-xs text-[#8C90A3]",
!openMenu.includes("other") && "hidden",
)}
>
<div className={clx("text-xs text-[#8C90A3]", !openMenu.includes("other") && "hidden")}>
<SideBarItem
icon={
<Messages3
variant={isActive("tickets") ? "Bold" : "Outline"}
color={isActive("tickets") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<Messages3 variant={isActive("tickets") ? "Bold" : "Outline"} color={isActive("tickets") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.ticket")}
isActive={isActive("tickets")}
link={Pages.ticket.list}
@@ -433,13 +273,7 @@ const SideBar: FC = () => {
/>
<SideBarItem
icon={
<Chart21
variant={isActive("feedback") ? "Bold" : "Outline"}
color={isActive("feedback") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<Chart21 variant={isActive("feedback") ? "Bold" : "Outline"} color={isActive("feedback") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.feedback")}
isActive={isActive("feedback")}
link={Pages.feedback.list}
@@ -448,13 +282,7 @@ const SideBar: FC = () => {
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<Activity
variant={isActive("access-logs") ? "Bold" : "Outline"}
color={isActive("access-logs") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<Activity variant={isActive("access-logs") ? "Bold" : "Outline"} color={isActive("access-logs") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.accessLogs")}
isActive={isActive("access-logs")}
link={Pages.accessLogs.list}
@@ -465,13 +293,7 @@ const SideBar: FC = () => {
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<DocumentText
variant={isActive("criticisms") ? "Bold" : "Outline"}
color={isActive("criticisms") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<DocumentText variant={isActive("criticisms") ? "Bold" : "Outline"} color={isActive("criticisms") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.criticisms")}
isActive={isActive("criticisms")}
link={Pages.criticisms.list}
@@ -479,70 +301,58 @@ const SideBar: FC = () => {
/>
</div>
</div>
{profile?.data?.user?.roles?.some(
(role: { name: string }) => role.name === "super_admin",
) && (
{
<div
onClick={() => handleOpenMenu("taskmanager")}
className={clx("mt-10 px-12 text-header text-sm font-normal cursor-pointer", hasSubMenu && "px-2 text-center", !hasSubMenu && "flex gap-2 items-center")}
>
{t("sidebar.taskmanager")}
<div className={clx("transition-all", !openMenu.includes("taskmanager") && "rotate-180", hasSubMenu && "hidden")}>
<ArrowDown2 size={18} color="#c3c7dd" />
</div>
</div>
}
<div className={clx("text-xs text-[#8C90A3]")}>
<SideBarItem
icon={<Task variant={isActive("taskmanager") ? "Bold" : "Outline"} color={isActive("taskmanager") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.taskmanager")}
isActive={isActive("taskmanager")}
link={Pages.taskmanager.workspace + "dpage"}
activeName=""
/>
</div>
{profile?.data?.user?.roles?.some((role: { name: string }) => role.name === "super_admin") && (
<div
onClick={() => handleOpenMenu("content")}
className={clx(
"mt-10 px-12 text-header text-sm font-normal cursor-pointer",
hasSubMenu && "px-2 text-center text-xs",
!hasSubMenu && "flex gap-2 items-center",
)}
className={clx("mt-10 px-12 text-header text-sm font-normal cursor-pointer", hasSubMenu && "px-2 text-center text-xs", !hasSubMenu && "flex gap-2 items-center")}
>
{t("sidebar.mnage_content")}
<div
className={clx(
"transition-all",
!openMenu.includes("content") && "rotate-180",
hasSubMenu && "hidden",
)}
>
<div className={clx("transition-all", !openMenu.includes("content") && "rotate-180", hasSubMenu && "hidden")}>
<ArrowDown2 size={18} color="#c3c7dd" />
</div>
</div>
)}
{adminPermissions?.data?.permissions?.some(
(permission: { name: string }) => permission.name === "reseller",
) && (
{adminPermissions?.data?.permissions?.some((permission: { name: string }) => permission.name === "reseller") && (
<>
<div
onClick={() => handleOpenMenu("reseller")}
className={clx(
"mt-10 px-12 text-header text-sm font-normal cursor-pointer",
hasSubMenu && "px-2 text-center",
!hasSubMenu && "flex gap-2 items-center",
)}
className={clx("mt-10 px-12 text-header text-sm font-normal cursor-pointer", hasSubMenu && "px-2 text-center", !hasSubMenu && "flex gap-2 items-center")}
>
{t("sidebar.reseller")}
<div
className={clx(
"transition-all",
!openMenu.includes("reseller") && "rotate-180",
hasSubMenu && "hidden",
)}
>
<div className={clx("transition-all", !openMenu.includes("reseller") && "rotate-180", hasSubMenu && "hidden")}>
<ArrowDown2 size={18} color="#c3c7dd" />
</div>
</div>
<div
className={clx(
"flex-1 flex flex-col justify-end",
!openMenu.includes("reseller") && "hidden",
)}
>
<div className={clx("flex-1 flex flex-col justify-end", !openMenu.includes("reseller") && "hidden")}>
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<UserTick
variant={isActive("reseller/list") ? "Bold" : "Outline"}
color={isActive("reseller/list") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<UserTick variant={isActive("reseller/list") ? "Bold" : "Outline"} color={isActive("reseller/list") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.resellers")}
isActive={isActive("reseller/list")}
link={Pages.reseller.list}
@@ -552,17 +362,7 @@ const SideBar: FC = () => {
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<Money
variant={
isActive("reseller/withdraw") ? "Bold" : "Outline"
}
color={
isActive("reseller/withdraw") ? "black" : "#8C90A3"
}
size={iconSizeSideBar}
/>
}
icon={<Money variant={isActive("reseller/withdraw") ? "Bold" : "Outline"} color={isActive("reseller/withdraw") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.withdraw")}
isActive={isActive("reseller/withdraw")}
link={Pages.reseller.withdraw}
@@ -576,13 +376,7 @@ const SideBar: FC = () => {
<div className={clx(!openMenu.includes("content") && "hidden")}>
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<DocumentLike
variant={isActive("ads") ? "Bold" : "Outline"}
color={isActive("ads") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<DocumentLike variant={isActive("ads") ? "Bold" : "Outline"} color={isActive("ads") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.ads")}
isActive={isActive("ads")}
link={Pages.ads.list}
@@ -592,13 +386,7 @@ const SideBar: FC = () => {
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<NotificationStatus
variant={isActive("announcement") ? "Bold" : "Outline"}
color={isActive("announcement") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<NotificationStatus variant={isActive("announcement") ? "Bold" : "Outline"} color={isActive("announcement") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.announcement")}
isActive={isActive("announcement")}
link={Pages.announcement.list}
@@ -608,13 +396,7 @@ const SideBar: FC = () => {
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<DocumentText
variant={isActive("blog") ? "Bold" : "Outline"}
color={isActive("blog") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<DocumentText variant={isActive("blog") ? "Bold" : "Outline"} color={isActive("blog") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.blog")}
isActive={isActive("blog")}
link={Pages.blog.list}
@@ -624,13 +406,7 @@ const SideBar: FC = () => {
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<Teacher
variant={isActive("learning") ? "Bold" : "Outline"}
color={isActive("learning") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<Teacher variant={isActive("learning") ? "Bold" : "Outline"} color={isActive("learning") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.learning")}
isActive={isActive("learning")}
link={Pages.learning.list}
@@ -640,13 +416,7 @@ const SideBar: FC = () => {
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<SmsTracking
variant={isActive("messages") ? "Bold" : "Outline"}
color={isActive("messages") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<SmsTracking variant={isActive("messages") ? "Bold" : "Outline"} color={isActive("messages") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.messages")}
isActive={isActive("messages")}
link={Pages.messages.list}
@@ -655,49 +425,22 @@ const SideBar: FC = () => {
</div>
</div>
{adminPermissions?.data?.permissions?.some(
(permission: { name: string }) => permission.name === "dmenu",
) && (
{adminPermissions?.data?.permissions?.some((permission: { name: string }) => permission.name === "dmenu") && (
<>
<div
onClick={() => handleOpenMenu("dmenu")}
className={clx(
"mt-10 px-12 text-header text-sm font-normal cursor-pointer",
hasSubMenu && "px-2 text-center",
!hasSubMenu && "flex gap-2 items-center",
)}
className={clx("mt-10 px-12 text-header text-sm font-normal cursor-pointer", hasSubMenu && "px-2 text-center", !hasSubMenu && "flex gap-2 items-center")}
>
{t("sidebar.dmenu")}
<div
className={clx(
"transition-all",
!openMenu.includes("dmenu") && "rotate-180",
hasSubMenu && "hidden",
)}
>
<div className={clx("transition-all", !openMenu.includes("dmenu") && "rotate-180", hasSubMenu && "hidden")}>
<ArrowDown2 size={18} color="#c3c7dd" />
</div>
</div>
<div
className={clx(
"flex-1 flex flex-col justify-end",
!openMenu.includes("dmenu") && "hidden",
)}
>
<div className={clx("flex-1 flex flex-col justify-end", !openMenu.includes("dmenu") && "hidden")}>
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<Icon
variant={
isActive("dmenu/icons/list") ? "Bold" : "Outline"
}
color={
isActive("dmenu/icons/list") ? "black" : "#8C90A3"
}
size={iconSizeSideBar}
/>
}
icon={<Icon variant={isActive("dmenu/icons/list") ? "Bold" : "Outline"} color={isActive("dmenu/icons/list") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.icons")}
isActive={isActive("dmenu/icons/list")}
link={Pages.dmenu.icons.list}
@@ -707,21 +450,7 @@ const SideBar: FC = () => {
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<Category
variant={
isActive("dmenu/icons/group/list")
? "Bold"
: "Outline"
}
color={
isActive("dmenu/icons/group/list")
? "black"
: "#8C90A3"
}
size={iconSizeSideBar}
/>
}
icon={<Category variant={isActive("dmenu/icons/group/list") ? "Bold" : "Outline"} color={isActive("dmenu/icons/group/list") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.groups_icon")}
isActive={isActive("dmenu/icons/group/list")}
link={Pages.dmenu.icons.groupList}
@@ -731,13 +460,7 @@ const SideBar: FC = () => {
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<Warning2
variant={isActive("dmenu/reports") ? "Bold" : "Outline"}
color={isActive("dmenu/reports") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<Warning2 variant={isActive("dmenu/reports") ? "Bold" : "Outline"} color={isActive("dmenu/reports") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.reports")}
isActive={isActive("dmenu/reports")}
link={Pages.dmenu.warnings.list}
@@ -747,13 +470,7 @@ const SideBar: FC = () => {
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<Building
variant={isActive("restaurants") ? "Bold" : "Outline"}
color={isActive("restaurants") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<Building variant={isActive("restaurants") ? "Bold" : "Outline"} color={isActive("restaurants") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.restaurants")}
isActive={isActive("restaurants")}
link={Pages.dmenu.restaurants.list}
@@ -763,13 +480,7 @@ const SideBar: FC = () => {
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<Sms
variant={isActive("sms-count") ? "Bold" : "Outline"}
color={isActive("sms-count") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<Sms variant={isActive("sms-count") ? "Bold" : "Outline"} color={isActive("sms-count") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.sms_count")}
isActive={isActive("sms-count")}
link={Pages.dmenu.restaurants.smsCountList}
@@ -780,49 +491,22 @@ const SideBar: FC = () => {
</>
)}
{adminPermissions?.data?.permissions?.some(
(permission: { name: string }) => permission.name === "dkala",
) && (
{adminPermissions?.data?.permissions?.some((permission: { name: string }) => permission.name === "dkala") && (
<>
<div
onClick={() => handleOpenMenu("dkala")}
className={clx(
"mt-10 px-12 text-header text-sm font-normal cursor-pointer",
hasSubMenu && "px-2 text-center",
!hasSubMenu && "flex gap-2 items-center",
)}
className={clx("mt-10 px-12 text-header text-sm font-normal cursor-pointer", hasSubMenu && "px-2 text-center", !hasSubMenu && "flex gap-2 items-center")}
>
{t("sidebar.dkala")}
<div
className={clx(
"transition-all",
!openMenu.includes("dkala") && "rotate-180",
hasSubMenu && "hidden",
)}
>
<div className={clx("transition-all", !openMenu.includes("dkala") && "rotate-180", hasSubMenu && "hidden")}>
<ArrowDown2 size={18} color="#c3c7dd" />
</div>
</div>
<div
className={clx(
"flex-1 flex flex-col justify-end",
!openMenu.includes("dkala") && "hidden",
)}
>
<div className={clx("flex-1 flex flex-col justify-end", !openMenu.includes("dkala") && "hidden")}>
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<Icon
variant={
isActive("dkala/icons/list") ? "Bold" : "Outline"
}
color={
isActive("dkala/icons/list") ? "black" : "#8C90A3"
}
size={iconSizeSideBar}
/>
}
icon={<Icon variant={isActive("dkala/icons/list") ? "Bold" : "Outline"} color={isActive("dkala/icons/list") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.icons")}
isActive={isActive("dkala/icons/list")}
link={Pages.dkala.icons.list}
@@ -832,17 +516,7 @@ const SideBar: FC = () => {
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<Category
variant={
isActive("dkala/icons/group") ? "Bold" : "Outline"
}
color={
isActive("dkala/icons/group") ? "black" : "#8C90A3"
}
size={iconSizeSideBar}
/>
}
icon={<Category variant={isActive("dkala/icons/group") ? "Bold" : "Outline"} color={isActive("dkala/icons/group") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.groups_icon")}
isActive={isActive("dkala/icons/group")}
link={Pages.dkala.icons.groupList}
@@ -852,13 +526,7 @@ const SideBar: FC = () => {
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<Warning2
variant={isActive("dkala/reports") ? "Bold" : "Outline"}
color={isActive("dkala/reports") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<Warning2 variant={isActive("dkala/reports") ? "Bold" : "Outline"} color={isActive("dkala/reports") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.reports")}
isActive={isActive("dkala/reports")}
link={Pages.dkala.warnings.list}
@@ -868,13 +536,7 @@ const SideBar: FC = () => {
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<Building
variant={isActive("dkala/shops") ? "Bold" : "Outline"}
color={isActive("dkala/shops") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<Building variant={isActive("dkala/shops") ? "Bold" : "Outline"} color={isActive("dkala/shops") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.shops")}
isActive={isActive("dkala/shops")}
link={Pages.dkala.shops.list}
@@ -884,17 +546,7 @@ const SideBar: FC = () => {
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<Sms
variant={
isActive("dkala/sms-count") ? "Bold" : "Outline"
}
color={
isActive("dkala/sms-count") ? "black" : "#8C90A3"
}
size={iconSizeSideBar}
/>
}
icon={<Sms variant={isActive("dkala/sms-count") ? "Bold" : "Outline"} color={isActive("dkala/sms-count") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.sms_count")}
isActive={isActive("dkala/sms-count")}
link={Pages.dkala.shops.smsCountList}
@@ -904,49 +556,22 @@ const SideBar: FC = () => {
</div>
</>
)}
{adminPermissions?.data?.permissions?.some(
(permission: { name: string }) => permission.name === "dpage",
) && (
{adminPermissions?.data?.permissions?.some((permission: { name: string }) => permission.name === "dpage") && (
<>
<div
onClick={() => handleOpenMenu("dpage")}
className={clx(
"mt-10 px-12 text-header text-sm font-normal cursor-pointer",
hasSubMenu && "px-2 text-center",
!hasSubMenu && "flex gap-2 items-center",
)}
className={clx("mt-10 px-12 text-header text-sm font-normal cursor-pointer", hasSubMenu && "px-2 text-center", !hasSubMenu && "flex gap-2 items-center")}
>
{t("sidebar.dpage")}
<div
className={clx(
"transition-all",
!openMenu.includes("dpage") && "rotate-180",
hasSubMenu && "hidden",
)}
>
<div className={clx("transition-all", !openMenu.includes("dpage") && "rotate-180", hasSubMenu && "hidden")}>
<ArrowDown2 size={18} color="#c3c7dd" />
</div>
</div>
<div
className={clx(
"flex-1 flex flex-col justify-end",
!openMenu.includes("dpage") && "hidden",
)}
>
<div className={clx("flex-1 flex flex-col justify-end", !openMenu.includes("dpage") && "hidden")}>
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<Icon
variant={
isActive("dpage/stickers/list") ? "Bold" : "Outline"
}
color={
isActive("dpage/stickers/list") ? "black" : "#8C90A3"
}
size={iconSizeSideBar}
/>
}
icon={<Icon variant={isActive("dpage/stickers/list") ? "Bold" : "Outline"} color={isActive("dpage/stickers/list") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.sticker")}
isActive={isActive("dpage/stickers/list")}
link={Pages.dpage.stickers.list}
@@ -957,49 +582,22 @@ const SideBar: FC = () => {
</>
)}
{adminPermissions?.data?.permissions?.some(
(permission: { name: string }) => permission.name === "dmail",
) && (
{adminPermissions?.data?.permissions?.some((permission: { name: string }) => permission.name === "dmail") && (
<>
<div
onClick={() => handleOpenMenu("dmail")}
className={clx(
"mt-10 px-12 text-header text-sm font-normal cursor-pointer",
hasSubMenu && "px-2 text-center",
!hasSubMenu && "flex gap-2 items-center",
)}
className={clx("mt-10 px-12 text-header text-sm font-normal cursor-pointer", hasSubMenu && "px-2 text-center", !hasSubMenu && "flex gap-2 items-center")}
>
{t("sidebar.dmail")}
<div
className={clx(
"transition-all",
!openMenu.includes("dmail") && "rotate-180",
hasSubMenu && "hidden",
)}
>
<div className={clx("transition-all", !openMenu.includes("dmail") && "rotate-180", hasSubMenu && "hidden")}>
<ArrowDown2 size={18} color="#c3c7dd" />
</div>
</div>
<div
className={clx(
"flex-1 flex flex-col justify-end",
!openMenu.includes("dmail") && "hidden",
)}
>
<div className={clx("flex-1 flex flex-col justify-end", !openMenu.includes("dmail") && "hidden")}>
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<Global
variant={
isActive("dmail/domain/list") ? "Bold" : "Outline"
}
color={
isActive("dmail/domain/list") ? "black" : "#8C90A3"
}
size={iconSizeSideBar}
/>
}
icon={<Global variant={isActive("dmail/domain/list") ? "Bold" : "Outline"} color={isActive("dmail/domain/list") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.domain")}
isActive={isActive("dmail/domain/list")}
link={Pages.dmail.list}
@@ -1014,13 +612,7 @@ const SideBar: FC = () => {
<div className="text-xs text-[#8C90A3]"></div>
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<Setting2
variant={isActive("setting") ? "Bold" : "Outline"}
color={isActive("setting") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<Setting2 variant={isActive("setting") ? "Bold" : "Outline"} color={isActive("setting") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.setting")}
isActive={isActive("setting")}
link={Pages.setting}
@@ -1029,13 +621,7 @@ const SideBar: FC = () => {
</div>
<div className="text-xs text-[#8C90A3]">
<SideBarItem
icon={
<Logout
variant={isActive("logout") ? "Bold" : "Outline"}
color={isActive("logout") ? "black" : "#8C90A3"}
size={iconSizeSideBar}
/>
}
icon={<Logout variant={isActive("logout") ? "Bold" : "Outline"} color={isActive("logout") ? "black" : "#8C90A3"} size={iconSizeSideBar} />}
title={t("sidebar.logout")}
isActive={isActive("logout")}
link={`#`}
+1
View File
@@ -12,6 +12,7 @@
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"resolveJsonModule": true,
"noEmit": true,
"jsx": "react-jsx",