create discount and ads section
This commit is contained in:
Generated
+237
@@ -11,9 +11,11 @@
|
|||||||
"@headlessui/react": "^2.2.0",
|
"@headlessui/react": "^2.2.0",
|
||||||
"@material-tailwind/react": "^2.1.10",
|
"@material-tailwind/react": "^2.1.10",
|
||||||
"@tanstack/react-query": "^5.62.8",
|
"@tanstack/react-query": "^5.62.8",
|
||||||
|
"draft-js": "^0.11.7",
|
||||||
"formik": "^2.4.6",
|
"formik": "^2.4.6",
|
||||||
"i18next": "^24.2.0",
|
"i18next": "^24.2.0",
|
||||||
"iconsax-react": "^0.0.8",
|
"iconsax-react": "^0.0.8",
|
||||||
|
"quill": "^2.0.3",
|
||||||
"rc-rate": "^2.13.0",
|
"rc-rate": "^2.13.0",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
@@ -1839,6 +1841,18 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/node": {
|
||||||
|
"version": "22.10.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.7.tgz",
|
||||||
|
"integrity": "sha512-V09KvXxFiutGp6B7XkpaDXlNadZxrzajcY50EuoLIpQ6WWYCSvf19lVIazzfIzQvhUN2HjX12spLojTnhuKlGg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"undici-types": "~6.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/prop-types": {
|
"node_modules/@types/prop-types": {
|
||||||
"version": "15.7.14",
|
"version": "15.7.14",
|
||||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz",
|
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz",
|
||||||
@@ -2227,6 +2241,12 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/asap": {
|
||||||
|
"version": "2.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
||||||
|
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/attr-accept": {
|
"node_modules/attr-accept": {
|
||||||
"version": "2.2.5",
|
"version": "2.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.5.tgz",
|
||||||
@@ -2515,6 +2535,26 @@
|
|||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/core-js": {
|
||||||
|
"version": "3.40.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.40.0.tgz",
|
||||||
|
"integrity": "sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/core-js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cross-fetch": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"node-fetch": "^2.7.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.6",
|
"version": "7.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
@@ -2597,6 +2637,21 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/draft-js": {
|
||||||
|
"version": "0.11.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/draft-js/-/draft-js-0.11.7.tgz",
|
||||||
|
"integrity": "sha512-ne7yFfN4sEL82QPQEn80xnADR8/Q6ALVworbC5UOSzOvjffmYfFsr3xSZtxbIirti14R7Y33EZC5rivpLgIbsg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"fbjs": "^2.0.0",
|
||||||
|
"immutable": "~3.7.4",
|
||||||
|
"object-assign": "^4.1.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=0.14.0",
|
||||||
|
"react-dom": ">=0.14.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/eastasianwidth": {
|
"node_modules/eastasianwidth": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
|
||||||
@@ -2858,6 +2913,12 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eventemitter3": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/fast-deep-equal": {
|
"node_modules/fast-deep-equal": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
@@ -2865,6 +2926,12 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-diff": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
"node_modules/fast-glob": {
|
"node_modules/fast-glob": {
|
||||||
"version": "3.3.2",
|
"version": "3.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
|
||||||
@@ -2919,6 +2986,28 @@
|
|||||||
"reusify": "^1.0.4"
|
"reusify": "^1.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fbjs": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-8XA8ny9ifxrAWlyhAbexXcs3rRMtxWcs3M0lctLfB49jRDHiaxj+Mo0XxbwE7nKZYzgCFoq64FS+WFd4IycPPQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"core-js": "^3.6.4",
|
||||||
|
"cross-fetch": "^3.0.4",
|
||||||
|
"fbjs-css-vars": "^1.0.0",
|
||||||
|
"loose-envify": "^1.0.0",
|
||||||
|
"object-assign": "^4.1.0",
|
||||||
|
"promise": "^7.1.1",
|
||||||
|
"setimmediate": "^1.0.5",
|
||||||
|
"ua-parser-js": "^0.7.18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fbjs-css-vars": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/file-entry-cache": {
|
"node_modules/file-entry-cache": {
|
||||||
"version": "8.0.0",
|
"version": "8.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
|
||||||
@@ -3296,6 +3385,15 @@
|
|||||||
"node": ">= 4"
|
"node": ">= 4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/immutable": {
|
||||||
|
"version": "3.7.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz",
|
||||||
|
"integrity": "sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/import-fresh": {
|
"node_modules/import-fresh": {
|
||||||
"version": "3.3.0",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||||
@@ -3566,6 +3664,18 @@
|
|||||||
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
|
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/lodash.clonedeep": {
|
||||||
|
"version": "4.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
|
||||||
|
"integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/lodash.isequal": {
|
||||||
|
"version": "4.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||||
|
"integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/lodash.merge": {
|
"node_modules/lodash.merge": {
|
||||||
"version": "4.6.2",
|
"version": "4.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||||
@@ -3693,6 +3803,26 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/node-fetch": {
|
||||||
|
"version": "2.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||||
|
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"whatwg-url": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "4.x || >=6.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"encoding": "^0.1.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"encoding": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/node-releases": {
|
"node_modules/node-releases": {
|
||||||
"version": "2.0.19",
|
"version": "2.0.19",
|
||||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
|
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
|
||||||
@@ -3796,6 +3926,12 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BlueOak-1.0.0"
|
"license": "BlueOak-1.0.0"
|
||||||
},
|
},
|
||||||
|
"node_modules/parchment": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/parchment/-/parchment-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-HUrJFQ/StvgmXRcQ1ftY6VEZUq3jA2t9ncFN4F84J/vN0/FPpQF+8FKXb3l6fLces6q0uOHj6NJn+2xvZnxO6A==",
|
||||||
|
"license": "BSD-3-Clause"
|
||||||
|
},
|
||||||
"node_modules/parent-module": {
|
"node_modules/parent-module": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||||
@@ -4072,6 +4208,15 @@
|
|||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/promise": {
|
||||||
|
"version": "7.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
|
||||||
|
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"asap": "~2.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/prop-types": {
|
"node_modules/prop-types": {
|
||||||
"version": "15.8.1",
|
"version": "15.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||||
@@ -4120,6 +4265,35 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/quill": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/quill/-/quill-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-xEYQBqfYx/sfb33VJiKnSJp8ehloavImQ2A6564GAbqG55PGw1dAWUn1MUbQB62t0azawUS2CZZhWCjO8gRvTw==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"eventemitter3": "^5.0.1",
|
||||||
|
"lodash-es": "^4.17.21",
|
||||||
|
"parchment": "^3.0.0",
|
||||||
|
"quill-delta": "^5.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"npm": ">=8.2.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/quill-delta": {
|
||||||
|
"version": "5.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-5.1.0.tgz",
|
||||||
|
"integrity": "sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"fast-diff": "^1.3.0",
|
||||||
|
"lodash.clonedeep": "^4.5.0",
|
||||||
|
"lodash.isequal": "^4.5.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/rc-rate": {
|
"node_modules/rc-rate": {
|
||||||
"version": "2.13.0",
|
"version": "2.13.0",
|
||||||
"resolved": "https://registry.npmjs.org/rc-rate/-/rc-rate-2.13.0.tgz",
|
"resolved": "https://registry.npmjs.org/rc-rate/-/rc-rate-2.13.0.tgz",
|
||||||
@@ -4499,6 +4673,12 @@
|
|||||||
"integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
|
"integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/setimmediate": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/shebang-command": {
|
"node_modules/shebang-command": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
@@ -4848,6 +5028,12 @@
|
|||||||
"integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==",
|
"integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/tr46": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||||
|
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/ts-api-utils": {
|
"node_modules/ts-api-utils": {
|
||||||
"version": "1.4.3",
|
"version": "1.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz",
|
||||||
@@ -4942,6 +5128,41 @@
|
|||||||
"typescript": ">=4.8.4 <5.8.0"
|
"typescript": ">=4.8.4 <5.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ua-parser-js": {
|
||||||
|
"version": "0.7.40",
|
||||||
|
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.40.tgz",
|
||||||
|
"integrity": "sha512-us1E3K+3jJppDBa3Tl0L3MOJiGhe1C6P0+nIvQAFYbxlMAx0h81eOwLmU57xgqToduDDPx3y5QsdjPfDu+FgOQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/ua-parser-js"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "paypal",
|
||||||
|
"url": "https://paypal.me/faisalman"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/faisalman"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"ua-parser-js": "script/cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/undici-types": {
|
||||||
|
"version": "6.20.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
|
||||||
|
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
"node_modules/update-browserslist-db": {
|
"node_modules/update-browserslist-db": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
|
||||||
@@ -5071,6 +5292,22 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/webidl-conversions": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
|
||||||
|
"license": "BSD-2-Clause"
|
||||||
|
},
|
||||||
|
"node_modules/whatwg-url": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"tr46": "~0.0.3",
|
||||||
|
"webidl-conversions": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/which": {
|
"node_modules/which": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
|
|||||||
@@ -13,9 +13,11 @@
|
|||||||
"@headlessui/react": "^2.2.0",
|
"@headlessui/react": "^2.2.0",
|
||||||
"@material-tailwind/react": "^2.1.10",
|
"@material-tailwind/react": "^2.1.10",
|
||||||
"@tanstack/react-query": "^5.62.8",
|
"@tanstack/react-query": "^5.62.8",
|
||||||
|
"draft-js": "^0.11.7",
|
||||||
"formik": "^2.4.6",
|
"formik": "^2.4.6",
|
||||||
"i18next": "^24.2.0",
|
"i18next": "^24.2.0",
|
||||||
"iconsax-react": "^0.0.8",
|
"iconsax-react": "^0.0.8",
|
||||||
|
"quill": "^2.0.3",
|
||||||
"rc-rate": "^2.13.0",
|
"rc-rate": "^2.13.0",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import { IApiErrorRepsonse } from './types/error.types'
|
|||||||
import MainRouter from './router/Main'
|
import MainRouter from './router/Main'
|
||||||
import AuthRouter from './router/Auth'
|
import AuthRouter from './router/Auth'
|
||||||
import { Pages } from './config/Pages'
|
import { Pages } from './config/Pages'
|
||||||
|
|
||||||
i18next.init({
|
i18next.init({
|
||||||
interpolation: { escapeValue: false },
|
interpolation: { escapeValue: false },
|
||||||
lng: 'fa',
|
lng: 'fa',
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import { forwardRef, useEffect, useLayoutEffect, useRef } from 'react';
|
||||||
|
|
||||||
|
// Editor is an uncontrolled React component
|
||||||
|
const Editor = forwardRef(
|
||||||
|
({ readOnly, defaultValue, onTextChange, onSelectionChange }, ref) => {
|
||||||
|
const containerRef = useRef(null);
|
||||||
|
const defaultValueRef = useRef(defaultValue);
|
||||||
|
const onTextChangeRef = useRef(onTextChange);
|
||||||
|
const onSelectionChangeRef = useRef(onSelectionChange);
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
onTextChangeRef.current = onTextChange;
|
||||||
|
onSelectionChangeRef.current = onSelectionChange;
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
ref.current?.enable(!readOnly);
|
||||||
|
}, [ref, readOnly]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const container = containerRef.current;
|
||||||
|
const editorContainer = container.appendChild(
|
||||||
|
container.ownerDocument.createElement('div'),
|
||||||
|
);
|
||||||
|
const quill = new Quill(editorContainer, {
|
||||||
|
theme: 'snow',
|
||||||
|
});
|
||||||
|
|
||||||
|
ref.current = quill;
|
||||||
|
|
||||||
|
if (defaultValueRef.current) {
|
||||||
|
quill.setContents(defaultValueRef.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
quill.on(Quill.events.TEXT_CHANGE, (...args) => {
|
||||||
|
onTextChangeRef.current?.(...args);
|
||||||
|
});
|
||||||
|
|
||||||
|
quill.on(Quill.events.SELECTION_CHANGE, (...args) => {
|
||||||
|
onSelectionChangeRef.current?.(...args);
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
ref.current = null;
|
||||||
|
container.innerHTML = '';
|
||||||
|
};
|
||||||
|
}, [ref]);
|
||||||
|
|
||||||
|
return <div ref={containerRef}></div>;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Editor.displayName = 'Editor';
|
||||||
|
|
||||||
|
export default Editor;
|
||||||
@@ -40,6 +40,7 @@ export const Pages = {
|
|||||||
},
|
},
|
||||||
discount: {
|
discount: {
|
||||||
list: "/discounts/list",
|
list: "/discounts/list",
|
||||||
|
create: "/discounts/create"
|
||||||
},
|
},
|
||||||
referralCode: {
|
referralCode: {
|
||||||
list: "/referral-code/list",
|
list: "/referral-code/list",
|
||||||
@@ -49,9 +50,11 @@ export const Pages = {
|
|||||||
},
|
},
|
||||||
ads: {
|
ads: {
|
||||||
list: "/ads/list",
|
list: "/ads/list",
|
||||||
|
create: "/ads/create"
|
||||||
},
|
},
|
||||||
blog: {
|
blog: {
|
||||||
list: "/blog/list",
|
list: "/blog/list",
|
||||||
|
create: "/blog/create"
|
||||||
},
|
},
|
||||||
messages: {
|
messages: {
|
||||||
list: "/messages/list",
|
list: "/messages/list",
|
||||||
|
|||||||
@@ -158,6 +158,82 @@
|
|||||||
"info_ticket": "اطلاعات تیکت",
|
"info_ticket": "اطلاعات تیکت",
|
||||||
"update_sms": "به روزرسانی این تیکت از طریق پیامک اطلاع داده میشود"
|
"update_sms": "به روزرسانی این تیکت از طریق پیامک اطلاع داده میشود"
|
||||||
},
|
},
|
||||||
|
"ads": {
|
||||||
|
"ads": "تبلیغات",
|
||||||
|
"upload": "آپلود",
|
||||||
|
"deactive": "غیرفعال",
|
||||||
|
"submit": "ثبت تبلیغ",
|
||||||
|
"upload_picture": "تصویر نمایش تبلیغ",
|
||||||
|
"to_upload_message": "تصویر مورد نظر را آپلود کنید",
|
||||||
|
"new_ads": "افزودن تبلیغ",
|
||||||
|
"location": "جایگاه",
|
||||||
|
"startDate": "تاریخ شروع نمایش",
|
||||||
|
"endDate": "تاریخ پایان نمایش",
|
||||||
|
"search": "جستجو",
|
||||||
|
"number": "شماره",
|
||||||
|
"title": "عنوان",
|
||||||
|
"date": "تاریخ",
|
||||||
|
"status": "وضعیت",
|
||||||
|
"enter_your_title": "عنوان تبلیغ را وارد کنید",
|
||||||
|
"link": "لینک",
|
||||||
|
"enter_your_link": "لینک تبلیغ را وارد کنید"
|
||||||
|
},
|
||||||
|
"discount": {
|
||||||
|
"list": "لیست تخفیفات",
|
||||||
|
"type": "نوع تخفیف",
|
||||||
|
"price": "مبلغ تخفیف",
|
||||||
|
"title": "عنوان کد",
|
||||||
|
"code": "کد تخفیف",
|
||||||
|
"enter_discount_description": "عنوان کد تخفیف را وارد کنید",
|
||||||
|
"add_new_discount": "افزودن تخفیف",
|
||||||
|
"auto_generate_code": "ساخت کد",
|
||||||
|
"price_or_percent": "درصد / مبلغ تخفیف",
|
||||||
|
"enter_price_or_percent": "درصد / مبلغ تخفیف را وارد کنید",
|
||||||
|
"service": "سرویس",
|
||||||
|
"status": "وضعیت",
|
||||||
|
"number": "شماره",
|
||||||
|
"startDate": "تاریخ شروع",
|
||||||
|
"endDate": "تاریخ پایان",
|
||||||
|
"service_status": "وضعیت سرویس",
|
||||||
|
"availabe_service": "سرویس هایی که شامل تخفیف میشوند",
|
||||||
|
"new_discount": "کد تخفیف جدید",
|
||||||
|
"submit": "ثبت تخفیف",
|
||||||
|
"discount_code": "کد تخفیف",
|
||||||
|
"direct_discount": "تخفیف مستقیم",
|
||||||
|
"fixed_amount": "مبلغ ثابت",
|
||||||
|
"percent": "درصد"
|
||||||
|
},
|
||||||
|
"blog": {
|
||||||
|
"blog": "بلاگ",
|
||||||
|
"category": "دسته بندی",
|
||||||
|
"new_blog": "افزودن بلاگ",
|
||||||
|
"blog_title": "عنوان بلاگ",
|
||||||
|
"blog_Summary": "خلاصه بلاگ",
|
||||||
|
"shareDate": "تاریخ انتشار",
|
||||||
|
"enter_your_title": "عنوان بلاگ را وارد کنید",
|
||||||
|
"add_blog": "افزودن بلاگ",
|
||||||
|
"price": "مبلغ تخفیف",
|
||||||
|
"title": "عنوان کد",
|
||||||
|
"code": "کد تخفیف",
|
||||||
|
"enter_discount_description": "عنوان کد تخفیف را وارد کنید",
|
||||||
|
"add_new_discount": "افزودن تخفیف",
|
||||||
|
"auto_generate_code": "ساخت کد",
|
||||||
|
"price_or_percent": "درصد / مبلغ تخفیف",
|
||||||
|
"enter_price_or_percent": "درصد / مبلغ تخفیف را وارد کنید",
|
||||||
|
"service": "سرویس",
|
||||||
|
"status": "وضعیت",
|
||||||
|
"number": "شماره",
|
||||||
|
"startDate": "تاریخ شروع",
|
||||||
|
"endDate": "تاریخ پایان",
|
||||||
|
"service_status": "وضعیت سرویس",
|
||||||
|
"availabe_service": "سرویس هایی که شامل تخفیف میشوند",
|
||||||
|
"new_discount": "کد تخفیف جدید",
|
||||||
|
"submit": "ثبت بلاگ",
|
||||||
|
"discount_code": "کد تخفیف",
|
||||||
|
"direct_discount": "تخفیف مستقیم",
|
||||||
|
"fixed_amount": "مبلغ ثابت",
|
||||||
|
"percent": "درصد"
|
||||||
|
},
|
||||||
"receip": {
|
"receip": {
|
||||||
"receip_list": "لیست صورتحساب ها",
|
"receip_list": "لیست صورتحساب ها",
|
||||||
"dont_pay": "پرداخت نشده",
|
"dont_pay": "پرداخت نشده",
|
||||||
|
|||||||
@@ -0,0 +1,135 @@
|
|||||||
|
import { FC } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import Button from '../../components/Button'
|
||||||
|
import { Add, Eye } from 'iconsax-react'
|
||||||
|
import Td from '../../components/Td'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
import { Pages } from '../../config/Pages'
|
||||||
|
import SwitchComponent from '../../components/Switch'
|
||||||
|
import DatePickerComponent from '../../components/DatePicker'
|
||||||
|
import Select from '../../components/Select'
|
||||||
|
import Input from '../../components/Input'
|
||||||
|
const TicketList: FC = () => {
|
||||||
|
const { t } = useTranslation('global')
|
||||||
|
return (
|
||||||
|
<div className='mt-4 min-h-[500px]'>
|
||||||
|
<div className='flex justify-between items-center'>
|
||||||
|
<div>
|
||||||
|
{t('ads.ads')}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Link to={Pages.ads.create}>
|
||||||
|
<Button
|
||||||
|
className='w-[172px]'
|
||||||
|
>
|
||||||
|
<div className='flex gap-2 items-center'>
|
||||||
|
<Add size={20} color='white' />
|
||||||
|
<div>
|
||||||
|
{t('ads.new_ads')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div className='mt-4'>
|
||||||
|
<div className='flex justify-between items-center'>
|
||||||
|
<div className='flex items-center gap-4'>
|
||||||
|
<div className='w-[200px]'>
|
||||||
|
<DatePickerComponent
|
||||||
|
label={t('ads.date')}
|
||||||
|
onChange={() => { }}
|
||||||
|
placeholder=''
|
||||||
|
defaulValue='1400-01-01'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className='w-[200px]'>
|
||||||
|
<Select
|
||||||
|
label={t('ads.status')}
|
||||||
|
items={[
|
||||||
|
{
|
||||||
|
label: 'فعال',
|
||||||
|
value: 'active'
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
className='bg-white border'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div className='xl:w-[300px] w-full'>
|
||||||
|
<Input
|
||||||
|
variant='search'
|
||||||
|
placeholder={t('ads.search')}
|
||||||
|
className='bg-white w-full'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div className='relative overflow-x-auto rounded-3xl mt-9 w-full'>
|
||||||
|
<table className='w-full text-sm '>
|
||||||
|
<thead className='thead'>
|
||||||
|
<tr>
|
||||||
|
<Td text={t('ads.number')} />
|
||||||
|
<Td text={t('ads.title')} />
|
||||||
|
<Td text={t('ads.location')} />
|
||||||
|
<Td text={t('ads.startDate')} />
|
||||||
|
<Td text={t('ads.endDate')} />
|
||||||
|
<Td text={t('ads.status')} />
|
||||||
|
<Td text={''} />
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr className='tr'>
|
||||||
|
<Td text={t('ads.number')} />
|
||||||
|
<Td text={t('ads.title')} />
|
||||||
|
<Td text={t('ads.location')} />
|
||||||
|
<Td text={t('ads.startDate')} />
|
||||||
|
<Td text={t('ads.endDate')} />
|
||||||
|
<Td text={t('')}>
|
||||||
|
<SwitchComponent
|
||||||
|
active={true}
|
||||||
|
onChange={() => { }}
|
||||||
|
/>
|
||||||
|
</Td>
|
||||||
|
<Td text={''}>
|
||||||
|
<Link to={Pages.ticket.detail + '1'}>
|
||||||
|
<Eye size={20} color='#8C90A3' />
|
||||||
|
</Link>
|
||||||
|
</Td>
|
||||||
|
</tr>
|
||||||
|
<tr className='tr'>
|
||||||
|
<Td text={t('ads.number')} />
|
||||||
|
<Td text={t('ads.title')} />
|
||||||
|
<Td text={t('ads.location')} />
|
||||||
|
<Td text={t('ads.startDate')} />
|
||||||
|
<Td text={t('ads.endDate')} />
|
||||||
|
<Td text={t('')}>
|
||||||
|
<SwitchComponent
|
||||||
|
active={true}
|
||||||
|
onChange={() => { }}
|
||||||
|
/>
|
||||||
|
</Td>
|
||||||
|
<Td text={''}>
|
||||||
|
<Link to={Pages.discount + '1'}>
|
||||||
|
<Eye size={20} color='#8C90A3' />
|
||||||
|
</Link>
|
||||||
|
</Td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TicketList
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
import { FC } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import Input from '../../components/Input'
|
||||||
|
import Button from '../../components/Button'
|
||||||
|
import SwitchComponent from '../../components/Switch'
|
||||||
|
import { TickCircle, TickSquare, Link2 } from 'iconsax-react'
|
||||||
|
import DatePickerComponent from '../../components/DatePicker'
|
||||||
|
import ImageUploader from './components/ImageUploader'
|
||||||
|
const CreateTicket: FC = () => {
|
||||||
|
const { t } = useTranslation('global')
|
||||||
|
return (
|
||||||
|
<div className='mt-4'>
|
||||||
|
<div className='flex justify-between items-center'>
|
||||||
|
<div>
|
||||||
|
{t('ads.new_ads')}
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
className='w-[172px]'
|
||||||
|
>
|
||||||
|
<div className='flex gap-2 items-center'>
|
||||||
|
<TickCircle size={20} color='white' />
|
||||||
|
<div>
|
||||||
|
{t('ads.submit')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className='flex gap-6 xl:mt-8 mt-4'>
|
||||||
|
<div className='flex-1 min-h-[calc(100vh-201px)] bg-white py-8 xl:px-10 px-4 rounded-3xl'>
|
||||||
|
<div className='mt-6'>
|
||||||
|
<Input
|
||||||
|
label={t('ads.title')}
|
||||||
|
placeholder={t('ads.enter_your_title')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className='mt-6 rowTwoInput'>
|
||||||
|
<DatePickerComponent
|
||||||
|
label={t('ads.startDate')}
|
||||||
|
onChange={() => { }}
|
||||||
|
placeholder=''
|
||||||
|
defaulValue='1400-01-01'
|
||||||
|
/>
|
||||||
|
<DatePickerComponent
|
||||||
|
label={t('ads.endDate')}
|
||||||
|
onChange={() => { }}
|
||||||
|
placeholder=''
|
||||||
|
defaulValue='1400-01-01'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className='mt-6 relative'>
|
||||||
|
<Input
|
||||||
|
label={t('ads.link')}
|
||||||
|
placeholder={t('ads.enter_your_link')}
|
||||||
|
/>
|
||||||
|
<Link2 size={20} color='blue' className='absolute left-4 bottom-[10px]' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='min-h-[calc(100vh-201px)] bg-white w-sidebar xl:block hidden py-10 px-5 h-fit rounded-3xl'>
|
||||||
|
<div className='text-sm flex items-center justify-between'>
|
||||||
|
<p>
|
||||||
|
وضعیت تبلیغ
|
||||||
|
</p>
|
||||||
|
<div className='flex gap-1 text-xs items-center text-description'>
|
||||||
|
<div>
|
||||||
|
{t('ads.deactive')}
|
||||||
|
</div>
|
||||||
|
<SwitchComponent
|
||||||
|
active={false}
|
||||||
|
onChange={() => { }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className='mt-6 text-sm'>{t('ads.location')}</p>
|
||||||
|
<div className='p-2 border border-[##D0D0D0] rounded-lg mt-1'>
|
||||||
|
<div className='flex items-start gap-2 py-2'>
|
||||||
|
<div>
|
||||||
|
<TickSquare size={20} color='black' variant='Bold' />
|
||||||
|
</div>
|
||||||
|
<div className='text-description text-xs leading-5'>
|
||||||
|
لورم ایپسوم
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-start gap-2 py-2'>
|
||||||
|
<div>
|
||||||
|
<TickSquare size={20} color='black' variant='Bold' />
|
||||||
|
</div>
|
||||||
|
<div className='text-description text-xs leading-5'>
|
||||||
|
لورم ایپسوم
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-start gap-2 py-2'>
|
||||||
|
<div>
|
||||||
|
<TickSquare size={20} color='black' variant='Bold' />
|
||||||
|
</div>
|
||||||
|
<div className='text-description text-xs leading-5'>
|
||||||
|
لورم ایپسوم
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ImageUploader />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CreateTicket
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
|
||||||
|
import { FC, useCallback, useState } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { Image, DocumentUpload } from 'iconsax-react'
|
||||||
|
import { useDropzone } from 'react-dropzone'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const ImageUploader: FC = () => {
|
||||||
|
const { t } = useTranslation('global')
|
||||||
|
const [file, setFile] = useState<File>()
|
||||||
|
const onDrop = useCallback((acceptedFiles: File[]) => {
|
||||||
|
setFile(acceptedFiles[0])
|
||||||
|
}, [])
|
||||||
|
const { getRootProps, getInputProps } = useDropzone({ onDrop })
|
||||||
|
|
||||||
|
return(
|
||||||
|
<>
|
||||||
|
<p className='mt-6 text-sm'>{t('ads.upload_picture')}</p>
|
||||||
|
<div
|
||||||
|
{...getRootProps()}
|
||||||
|
className='py-12 border border-dashed border-[#8C90A3] rounded-lg mt-2 flex items-center justify-center'>
|
||||||
|
<div className='flex flex-col items-center space-y-4'>
|
||||||
|
<Image size={45} color='#8C90A3' variant="Bold" className='border-[3px] border-[#8C90A3] rounded-md'
|
||||||
|
/>
|
||||||
|
<p className='text-sm text-[#8C90A3]'>
|
||||||
|
{
|
||||||
|
file ?
|
||||||
|
file.name
|
||||||
|
:
|
||||||
|
t('ads.to_upload_message')
|
||||||
|
|
||||||
|
}
|
||||||
|
</p>
|
||||||
|
<div className='flex gap-1'>
|
||||||
|
<DocumentUpload
|
||||||
|
size={20}
|
||||||
|
color='black'
|
||||||
|
/>
|
||||||
|
<button className='text-sm'>
|
||||||
|
<input {...getInputProps()} />
|
||||||
|
{t('ads.upload')}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default ImageUploader
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
import { FC } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import Button from '../../components/Button'
|
||||||
|
import { Add, Eye } from 'iconsax-react'
|
||||||
|
import Td from '../../components/Td'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
import { Pages } from '../../config/Pages'
|
||||||
|
import SwitchComponent from '../../components/Switch'
|
||||||
|
import DatePickerComponent from '../../components/DatePicker'
|
||||||
|
import Select from '../../components/Select'
|
||||||
|
import Input from '../../components/Input'
|
||||||
|
const BlogList: FC = () => {
|
||||||
|
const { t } = useTranslation('global')
|
||||||
|
return (
|
||||||
|
<div className='mt-4 min-h-[500px]'>
|
||||||
|
<div className='flex justify-between items-center'>
|
||||||
|
<div>
|
||||||
|
{t('blog.blog')}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Link to={Pages.blog.create}>
|
||||||
|
<Button
|
||||||
|
className='w-[172px]'
|
||||||
|
>
|
||||||
|
<div className='flex gap-2 items-center'>
|
||||||
|
<Add size={20} color='white' />
|
||||||
|
<div>
|
||||||
|
{t('blog.new_blog')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div className='mt-4'>
|
||||||
|
<div className='flex justify-between items-center'>
|
||||||
|
<div className='flex items-center gap-4'>
|
||||||
|
<div className='w-[200px]'>
|
||||||
|
<Select
|
||||||
|
label={t('blog.category')}
|
||||||
|
items={[
|
||||||
|
{
|
||||||
|
label: 'تست',
|
||||||
|
value: 'active'
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
className='bg-white border'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className='w-[200px]'>
|
||||||
|
<Select
|
||||||
|
label={t('ads.status')}
|
||||||
|
items={[
|
||||||
|
{
|
||||||
|
label: 'فعال',
|
||||||
|
value: 'active'
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
className='bg-white border'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className='w-[200px]'>
|
||||||
|
<DatePickerComponent
|
||||||
|
label={t('ads.date')}
|
||||||
|
onChange={() => { }}
|
||||||
|
placeholder=''
|
||||||
|
defaulValue='1400-01-01'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div className='xl:w-[300px] w-full'>
|
||||||
|
<Input
|
||||||
|
variant='search'
|
||||||
|
placeholder={t('ads.search')}
|
||||||
|
className='bg-white w-full'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div className='relative overflow-x-auto rounded-3xl mt-9 w-full'>
|
||||||
|
<table className='w-full text-sm '>
|
||||||
|
<thead className='thead'>
|
||||||
|
<tr>
|
||||||
|
<Td text={t('blog.number')} />
|
||||||
|
<Td text={t('blog.blog_title')} />
|
||||||
|
<Td text={t('blog.blog_Summary')} />
|
||||||
|
<Td text={t('blog.category')} />
|
||||||
|
<Td text={t('blog.shareDate')} />
|
||||||
|
<Td text={t('blog.status')} />
|
||||||
|
<Td text={''} />
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr className='tr'>
|
||||||
|
<Td text={t('blog.number')} />
|
||||||
|
<Td text={t('blog.blog_title')} />
|
||||||
|
<Td text={t('blog.blog_Summary')} />
|
||||||
|
<Td text={t('blog.category')} />
|
||||||
|
<Td text={t('blog.shareDate')} />
|
||||||
|
<Td text={t('')}>
|
||||||
|
<SwitchComponent
|
||||||
|
active={true}
|
||||||
|
onChange={() => { }}
|
||||||
|
/>
|
||||||
|
</Td>
|
||||||
|
<Td text={''}>
|
||||||
|
<Link to={Pages.ticket.detail + '1'}>
|
||||||
|
<Eye size={20} color='#8C90A3' />
|
||||||
|
</Link>
|
||||||
|
</Td>
|
||||||
|
</tr>
|
||||||
|
<tr className='tr'>
|
||||||
|
<Td text={t('blog.number')} />
|
||||||
|
<Td text={t('blog.blog_title')} />
|
||||||
|
<Td text={t('blog.blog_Summary')} />
|
||||||
|
<Td text={t('blog.category')} />
|
||||||
|
<Td text={t('blog.shareDate')} />
|
||||||
|
<Td text={t('')}>
|
||||||
|
<SwitchComponent
|
||||||
|
active={true}
|
||||||
|
onChange={() => { }}
|
||||||
|
/>
|
||||||
|
</Td>
|
||||||
|
<Td text={''}>
|
||||||
|
<Link to={Pages.discount + '1'}>
|
||||||
|
<Eye size={20} color='#8C90A3' />
|
||||||
|
</Link>
|
||||||
|
</Td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BlogList
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
|
||||||
|
import { FC, useEffect } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import Input from '../../components/Input'
|
||||||
|
import Button from '../../components/Button'
|
||||||
|
import SwitchComponent from '../../components/Switch'
|
||||||
|
import { TickCircle, TickSquare, Link2 } from 'iconsax-react'
|
||||||
|
import DatePickerComponent from '../../components/DatePicker'
|
||||||
|
import ImageUploader from './components/ImageUploader'
|
||||||
|
import "quill/dist/quill.snow.css";
|
||||||
|
import Quill from 'quill';
|
||||||
|
const CreateTicket: FC = () => {
|
||||||
|
const { t } = useTranslation('global')
|
||||||
|
useEffect(() => {
|
||||||
|
const quill = new Quill('#editor', {
|
||||||
|
theme: 'snow',
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
return (
|
||||||
|
<div className='mt-4'>
|
||||||
|
<div className='flex justify-between items-center'>
|
||||||
|
<div>
|
||||||
|
{t('blog.add_blog')}
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
className='w-[172px]'
|
||||||
|
>
|
||||||
|
<div className='flex gap-2 items-center'>
|
||||||
|
<TickCircle size={20} color='white' />
|
||||||
|
<div>
|
||||||
|
{t('blog.submit')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className='flex gap-6 xl:mt-8 mt-4'>
|
||||||
|
<div className='flex-1 min-h-[calc(100vh-201px)] bg-white py-8 xl:px-10 px-4 rounded-3xl'>
|
||||||
|
<div className='mt-6'>
|
||||||
|
<Input
|
||||||
|
label={t('blog.blog_title')}
|
||||||
|
placeholder={t('blog.enter_your_title')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='mt-6'>
|
||||||
|
<div id='editor'></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div className='mt-6 rowTwoInput'>
|
||||||
|
<DatePickerComponent
|
||||||
|
label={t('ads.startDate')}
|
||||||
|
onChange={() => { }}
|
||||||
|
placeholder=''
|
||||||
|
defaulValue='1400-01-01'
|
||||||
|
/>
|
||||||
|
<DatePickerComponent
|
||||||
|
label={t('ads.endDate')}
|
||||||
|
onChange={() => { }}
|
||||||
|
placeholder=''
|
||||||
|
defaulValue='1400-01-01'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className='mt-6 relative'>
|
||||||
|
<Input
|
||||||
|
label={t('ads.link')}
|
||||||
|
placeholder={t('ads.enter_your_link')}
|
||||||
|
/>
|
||||||
|
<Link2 size={20} color='blue' className='absolute left-4 bottom-[10px]' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='min-h-[calc(100vh-201px)] bg-white w-sidebar xl:block hidden py-10 px-5 h-fit rounded-3xl'>
|
||||||
|
<div className='text-sm flex items-center justify-between'>
|
||||||
|
<p>
|
||||||
|
وضعیت تبلیغ
|
||||||
|
</p>
|
||||||
|
<div className='flex gap-1 text-xs items-center text-description'>
|
||||||
|
<div>
|
||||||
|
{t('ads.deactive')}
|
||||||
|
</div>
|
||||||
|
<SwitchComponent
|
||||||
|
active={false}
|
||||||
|
onChange={() => { }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className='mt-6 text-sm'>{t('ads.location')}</p>
|
||||||
|
<div className='p-2 border border-[##D0D0D0] rounded-lg mt-1'>
|
||||||
|
<div className='flex items-start gap-2 py-2'>
|
||||||
|
<div>
|
||||||
|
<TickSquare size={20} color='black' variant='Bold' />
|
||||||
|
</div>
|
||||||
|
<div className='text-description text-xs leading-5'>
|
||||||
|
لورم ایپسوم
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-start gap-2 py-2'>
|
||||||
|
<div>
|
||||||
|
<TickSquare size={20} color='black' variant='Bold' />
|
||||||
|
</div>
|
||||||
|
<div className='text-description text-xs leading-5'>
|
||||||
|
لورم ایپسوم
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-start gap-2 py-2'>
|
||||||
|
<div>
|
||||||
|
<TickSquare size={20} color='black' variant='Bold' />
|
||||||
|
</div>
|
||||||
|
<div className='text-description text-xs leading-5'>
|
||||||
|
لورم ایپسوم
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ImageUploader />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CreateTicket
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
|
||||||
|
import { FC, useCallback, useState } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { Image, DocumentUpload } from 'iconsax-react'
|
||||||
|
import { useDropzone } from 'react-dropzone'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const ImageUploader: FC = () => {
|
||||||
|
const { t } = useTranslation('global')
|
||||||
|
const [file, setFile] = useState<File>()
|
||||||
|
const onDrop = useCallback((acceptedFiles: File[]) => {
|
||||||
|
setFile(acceptedFiles[0])
|
||||||
|
}, [])
|
||||||
|
const { getRootProps, getInputProps } = useDropzone({ onDrop })
|
||||||
|
|
||||||
|
return(
|
||||||
|
<>
|
||||||
|
<p className='mt-6 text-sm'>{t('ads.upload_picture')}</p>
|
||||||
|
<div
|
||||||
|
{...getRootProps()}
|
||||||
|
className='py-12 border border-dashed border-[#8C90A3] rounded-lg mt-2 flex items-center justify-center'>
|
||||||
|
<div className='flex flex-col items-center space-y-4'>
|
||||||
|
<Image size={45} color='#8C90A3' variant="Bold" className='border-[3px] border-[#8C90A3] rounded-md'
|
||||||
|
/>
|
||||||
|
<p className='text-sm text-[#8C90A3]'>
|
||||||
|
{
|
||||||
|
file ?
|
||||||
|
file.name
|
||||||
|
:
|
||||||
|
t('ads.to_upload_message')
|
||||||
|
|
||||||
|
}
|
||||||
|
</p>
|
||||||
|
<div className='flex gap-1'>
|
||||||
|
<DocumentUpload
|
||||||
|
size={20}
|
||||||
|
color='black'
|
||||||
|
/>
|
||||||
|
<button className='text-sm'>
|
||||||
|
<input {...getInputProps()} />
|
||||||
|
{t('ads.upload')}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default ImageUploader
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
import { FC } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import Input from '../../components/Input'
|
||||||
|
import Button from '../../components/Button'
|
||||||
|
import SwitchComponent from '../../components/Switch'
|
||||||
|
import { TickCircle, TickSquare, Refresh } from 'iconsax-react'
|
||||||
|
import DatePickerComponent from '../../components/DatePicker'
|
||||||
|
import ImageUploader from './components/ImageUploader'
|
||||||
|
import RadioGroup from '../../components/RadioGroup'
|
||||||
|
const CreateTicket: FC = () => {
|
||||||
|
const { t } = useTranslation('global')
|
||||||
|
return (
|
||||||
|
<div className='mt-4'>
|
||||||
|
<div className='flex justify-between items-center'>
|
||||||
|
<div>
|
||||||
|
{t('discount.new_discount')}
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
className='w-[172px]'
|
||||||
|
>
|
||||||
|
<div className='flex gap-2 items-center'>
|
||||||
|
<TickCircle size={20} color='white' />
|
||||||
|
<div>
|
||||||
|
{t('discount.submit')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className='flex gap-6 xl:mt-8 mt-4'>
|
||||||
|
<div className='flex-1 min-h-[calc(100vh-201px)] bg-white py-8 xl:px-10 px-4 rounded-3xl'>
|
||||||
|
<div className='mt-6'>
|
||||||
|
{t('discount.type')}
|
||||||
|
<div className='rowTwoInput mt-2'>
|
||||||
|
<RadioGroup
|
||||||
|
items={[
|
||||||
|
{
|
||||||
|
label: t('discount.direct_discount'),
|
||||||
|
value: '3month'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('discount.discount_code'),
|
||||||
|
value: 'year'
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
onChange={''}
|
||||||
|
selected={''}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div className='mt-6 rowTwoInput'>
|
||||||
|
<Input
|
||||||
|
label={t('discount.title')}
|
||||||
|
placeholder={t('discount.enter_discount_description')}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className='w-full mt-7 flex items-center'>
|
||||||
|
<button className='text-xs border h-full w-[142px] border-black rounded-xl flex justify-center items-center gap-2'>
|
||||||
|
<Refresh
|
||||||
|
size={18} color='black'
|
||||||
|
/>
|
||||||
|
<p>
|
||||||
|
{t('discount.auto_generate_code')}
|
||||||
|
</p>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div className='mt-6 rowTwoInput'>
|
||||||
|
|
||||||
|
|
||||||
|
<div className='w-full'>
|
||||||
|
|
||||||
|
{t('discount.price')}
|
||||||
|
<div className='rowTwoInput mt-2'>
|
||||||
|
<RadioGroup
|
||||||
|
items={[
|
||||||
|
{
|
||||||
|
label: t('discount.fixed_amount'),
|
||||||
|
value: '3month'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('discount.percent'),
|
||||||
|
value: 'year'
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
onChange={''}
|
||||||
|
selected={''}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Input
|
||||||
|
label={t('discount.price_or_percent')}
|
||||||
|
placeholder={t('discount.enter_price_or_percent')}
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div className='mt-6 rowTwoInput'>
|
||||||
|
<DatePickerComponent
|
||||||
|
label={t('discount.startDate')}
|
||||||
|
onChange={() => { }}
|
||||||
|
placeholder=''
|
||||||
|
defaulValue='1400-01-01'
|
||||||
|
/>
|
||||||
|
<DatePickerComponent
|
||||||
|
label={t('discount.endDate')}
|
||||||
|
onChange={() => { }}
|
||||||
|
placeholder=''
|
||||||
|
defaulValue='1400-01-01'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='min-h-[calc(100vh-201px)] bg-white w-sidebar xl:block hidden py-10 px-5 h-fit rounded-3xl'>
|
||||||
|
<div className='text-sm flex items-center justify-between'>
|
||||||
|
<p>
|
||||||
|
{t('discount.service_status')}
|
||||||
|
</p>
|
||||||
|
<div className='flex gap-1 text-xs items-center text-description'>
|
||||||
|
<div>
|
||||||
|
{t('ads.deactive')}
|
||||||
|
</div>
|
||||||
|
<SwitchComponent
|
||||||
|
active={false}
|
||||||
|
onChange={() => { }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className='mt-6 text-sm'>{t('discount.availabe_service')}</p>
|
||||||
|
<div className='p-2 border border-[##D0D0D0] rounded-lg mt-2'>
|
||||||
|
|
||||||
|
<Input
|
||||||
|
variant='search'
|
||||||
|
placeholder={t('header.search')}
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div className='flex items-start gap-2 py-2'>
|
||||||
|
<div>
|
||||||
|
<TickSquare size={20} color='black' variant='Bold' />
|
||||||
|
</div>
|
||||||
|
<div className='text-xs leading-5'>
|
||||||
|
لورم ایپسوم
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-start gap-2 py-2'>
|
||||||
|
<div>
|
||||||
|
<TickSquare size={20} color='black' variant='Bold' />
|
||||||
|
</div>
|
||||||
|
<div className='text-xs leading-5'>
|
||||||
|
لورم ایپسوم
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-start gap-2 py-2'>
|
||||||
|
<div>
|
||||||
|
<TickSquare size={20} color='black' variant='Bold' />
|
||||||
|
</div>
|
||||||
|
<div className='text-xs leading-5'>
|
||||||
|
لورم ایپسوم
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CreateTicket
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
import { FC } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import Button from '../../components/Button'
|
||||||
|
import { Add, Eye } from 'iconsax-react'
|
||||||
|
import Td from '../../components/Td'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
import { Pages } from '../../config/Pages'
|
||||||
|
import SwitchComponent from '../../components/Switch'
|
||||||
|
import Input from '../../components/Input'
|
||||||
|
const TicketList: FC = () => {
|
||||||
|
const { t } = useTranslation('global')
|
||||||
|
return (
|
||||||
|
<div className='mt-4 min-h-[500px]'>
|
||||||
|
<div className='flex justify-between items-center'>
|
||||||
|
<div>
|
||||||
|
{t('discount.list')}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Link to={Pages.discount.create}>
|
||||||
|
<Button
|
||||||
|
className='w-[172px]'
|
||||||
|
>
|
||||||
|
<div className='flex gap-2 items-center'>
|
||||||
|
<Add size={20} color='white' />
|
||||||
|
<div>
|
||||||
|
{t('discount.add_new_discount')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div className='mt-4'>
|
||||||
|
<div className='flex justify-end items-center'>
|
||||||
|
|
||||||
|
<div className='xl:w-[300px] w-full'>
|
||||||
|
<Input
|
||||||
|
variant='search'
|
||||||
|
placeholder={t('ads.search')}
|
||||||
|
className='bg-white w-full'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div className='relative overflow-x-auto rounded-3xl mt-9 w-full'>
|
||||||
|
<table className='w-full text-sm '>
|
||||||
|
<thead className='thead'>
|
||||||
|
<tr>
|
||||||
|
<Td text={t('discount.number')} />
|
||||||
|
<Td text={t('discount.type')} />
|
||||||
|
<Td text={t('discount.code')} />
|
||||||
|
<Td text={t('discount.startDate')} />
|
||||||
|
<Td text={t('discount.endDate')} />
|
||||||
|
<Td text={t('discount.price_or_percent')} />
|
||||||
|
<Td text={t('discount.service')} />
|
||||||
|
<Td text={t('discount.status')} />
|
||||||
|
<Td text={''} />
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr className='tr'>
|
||||||
|
<Td text={t('discount.number')} />
|
||||||
|
<Td text={t('discount.type')} />
|
||||||
|
<Td text={t('discount.code')} />
|
||||||
|
<Td text={t('discount.startDate')} />
|
||||||
|
<Td text={t('discount.endDate')} />
|
||||||
|
<Td text={t('discount.price_or_percent')} />
|
||||||
|
<Td text={t('discount.service')} />
|
||||||
|
<Td text={t('')}>
|
||||||
|
<SwitchComponent
|
||||||
|
active={true}
|
||||||
|
onChange={() => { }}
|
||||||
|
/>
|
||||||
|
</Td>
|
||||||
|
<Td text={''}>
|
||||||
|
<Link to={Pages.ticket.detail + '1'}>
|
||||||
|
<Eye size={20} color='#8C90A3' />
|
||||||
|
</Link>
|
||||||
|
</Td>
|
||||||
|
</tr>
|
||||||
|
<tr className='tr'>
|
||||||
|
<Td text={t('discount.number')} />
|
||||||
|
<Td text={t('discount.type')} />
|
||||||
|
<Td text={t('discount.code')} />
|
||||||
|
<Td text={t('discount.startDate')} />
|
||||||
|
<Td text={t('discount.endDate')} />
|
||||||
|
<Td text={t('discount.price_or_percent')} />
|
||||||
|
<Td text={t('discount.service')} />
|
||||||
|
<Td text={t('')}>
|
||||||
|
<SwitchComponent
|
||||||
|
active={true}
|
||||||
|
onChange={() => { }}
|
||||||
|
/>
|
||||||
|
</Td>
|
||||||
|
<Td text={''}>
|
||||||
|
<Link to={Pages.discount + '1'}>
|
||||||
|
<Eye size={20} color='#8C90A3' />
|
||||||
|
</Link>
|
||||||
|
</Td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TicketList
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
|
||||||
|
import { FC, useCallback, useState } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { Image, DocumentUpload } from 'iconsax-react'
|
||||||
|
import { useDropzone } from 'react-dropzone'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const ImageUploader: FC = () => {
|
||||||
|
const { t } = useTranslation('global')
|
||||||
|
const [file, setFile] = useState<File>()
|
||||||
|
const onDrop = useCallback((acceptedFiles: File[]) => {
|
||||||
|
setFile(acceptedFiles[0])
|
||||||
|
}, [])
|
||||||
|
const { getRootProps, getInputProps } = useDropzone({ onDrop })
|
||||||
|
|
||||||
|
return(
|
||||||
|
<>
|
||||||
|
<p className='mt-6 text-sm'>{t('ads.upload_picture')}</p>
|
||||||
|
<div
|
||||||
|
{...getRootProps()}
|
||||||
|
className='py-12 border border-dashed border-[#8C90A3] rounded-lg mt-2 flex items-center justify-center'>
|
||||||
|
<div className='flex flex-col items-center space-y-4'>
|
||||||
|
<Image size={45} color='#8C90A3' variant="Bold" className='border-[3px] border-[#8C90A3] rounded-md'
|
||||||
|
/>
|
||||||
|
<p className='text-sm text-[#8C90A3]'>
|
||||||
|
{
|
||||||
|
file ?
|
||||||
|
file.name
|
||||||
|
:
|
||||||
|
t('ads.to_upload_message')
|
||||||
|
|
||||||
|
}
|
||||||
|
</p>
|
||||||
|
<div className='flex gap-1'>
|
||||||
|
<DocumentUpload
|
||||||
|
size={20}
|
||||||
|
color='black'
|
||||||
|
/>
|
||||||
|
<button className='text-sm'>
|
||||||
|
<input {...getInputProps()} />
|
||||||
|
{t('ads.upload')}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default ImageUploader
|
||||||
@@ -5,6 +5,12 @@ import { Route, Routes } from 'react-router-dom'
|
|||||||
import { Pages } from '../config/Pages'
|
import { Pages } from '../config/Pages'
|
||||||
import Home from '../pages/home/Home'
|
import Home from '../pages/home/Home'
|
||||||
import MyServices from '../pages/service/MyServices'
|
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 CreateAds from '../pages/ads/CreateAds'
|
||||||
import TicketList from '../pages/ticket/TicketList'
|
import TicketList from '../pages/ticket/TicketList'
|
||||||
import CreateTicket from '../pages/ticket/CreateTicket'
|
import CreateTicket from '../pages/ticket/CreateTicket'
|
||||||
import TicketDetail from '../pages/ticket/Detail'
|
import TicketDetail from '../pages/ticket/Detail'
|
||||||
@@ -38,6 +44,12 @@ const MainRouter: FC = () => {
|
|||||||
<Route path={Pages.ticket.list} element={<TicketList />} />
|
<Route path={Pages.ticket.list} element={<TicketList />} />
|
||||||
<Route path={Pages.ticket.create} element={<CreateTicket />} />
|
<Route path={Pages.ticket.create} element={<CreateTicket />} />
|
||||||
<Route path={Pages.ticket.detail + ':id'} element={<TicketDetail />} />
|
<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.discount.list} element={<DiscountsList />} />
|
||||||
|
<Route path={Pages.discount.create} element={<CreateDiscount />} />
|
||||||
|
<Route path={Pages.blog.list} element={<BlogList />} />
|
||||||
|
<Route path={Pages.blog.create} element={<CreateBlog />} />
|
||||||
<Route path={Pages.transactions} element={<TransactionList />} />
|
<Route path={Pages.transactions} element={<TransactionList />} />
|
||||||
<Route path={Pages.receipts.index} element={<ReceiptsList />} />
|
<Route path={Pages.receipts.index} element={<ReceiptsList />} />
|
||||||
<Route path={Pages.receipts.detail + ':id'} element={<ReceiptsDetail />} />
|
<Route path={Pages.receipts.detail + ':id'} element={<ReceiptsDetail />} />
|
||||||
|
|||||||
Reference in New Issue
Block a user