From 4edad3974957eec1c2bbf6633affacf169895d97 Mon Sep 17 00:00:00 2001 From: KarimAldeen Date: Mon, 26 Feb 2024 09:07:16 +0300 Subject: [PATCH] Done --- package-lock.json | 216 +++- package.json | 2 + public/Layout/De.svg | 1 + src/Components/Columns/ColumnsImage.tsx | 5 +- .../Karimalden/View/SearchField.tsx | 46 - src/Components/Ui/StaticsCard/StaticCard.tsx | 7 +- src/Components/Utils/Translate.tsx | 103 +- .../Ui/KarimSpinner.tsx | 0 .../ValidationField/Ui/SearchBar.scss | 48 + .../ValidationField/Ui/SearchBar.tsx | 35 + .../ValidationField.scss} | 2 +- .../ValidationField.tsx} | 14 +- .../View/CheckboxField.tsx | 2 +- .../View/DataRange.tsx | 27 +- .../View/Date.tsx | 2 +- .../View/Default.tsx | 7 +- .../View/File.tsx | 10 +- .../View/MaltyFile.tsx | 6 +- .../ValidationField/View/SearchField.tsx | 56 + .../View/SelectField.tsx | 2 +- .../View/Time.tsx | 2 +- .../View/index.tsx | 0 .../{Karimalden => ValidationField}/index.tsx | 0 .../{Karimalden => ValidationField}/types.ts | 37 +- src/Extensions/FileGenerator/generateForm.js | 18 +- src/Hooks/isEmpty.tsx | 3 + src/Hooks/useFormatToSelect.tsx | 14 + src/Hooks/usePagination.tsx | 18 +- src/Layout/app/Header.tsx | 2 +- src/Layout/app/SideBar.tsx | 2 +- src/Layout/app/Types.tsx | 2 +- src/Pages/Account/AddAccount/RegisterForm.tsx | 14 +- .../Account/viewAccount/FormViewAccount.tsx | 6 +- src/Pages/Auth/LoginForm.tsx | 8 +- src/Pages/Categories/Page.tsx | 4 +- src/Pages/Categories/View/AddForm.tsx | 38 +- src/Pages/Categories/View/AddPage.tsx | 44 +- src/Pages/Categories/View/Atteibute.tsx | 37 + src/Pages/Categories/View/EditForm.tsx | 48 +- src/Pages/Categories/View/EditPage.tsx | 25 +- .../View/Field/Object.tsx} | 64 +- src/Pages/Categories/formUtil.ts | 40 +- src/Pages/Categories/useTableColumns.tsx | 7 +- src/Pages/Coupon/FormProducts.tsx | 55 - src/Pages/Coupon/Page.tsx | 44 + src/Pages/Coupon/View/AddForm.tsx | 60 + src/Pages/Coupon/View/AddPage.tsx | 87 +- src/Pages/Coupon/View/BasicInfo.tsx | 47 - src/Pages/Coupon/View/BasicInfo2.tsx | 87 -- src/Pages/Coupon/View/EditForm.tsx | 60 + src/Pages/Coupon/View/EditPage.tsx | 89 ++ src/Pages/Coupon/formUtil.ts | 138 ++- src/Pages/Coupon/useTableColumns.tsx | 83 +- src/Pages/Coupon2/AddCouponModal.tsx | 43 - src/Pages/Coupon2/AddForm.tsx | 37 - src/Pages/Coupon2/CouponPage.tsx | 40 - src/Pages/Coupon2/EditCoupon/EditForm.tsx | 23 - src/Pages/Coupon2/EditCoupon/Page.tsx | 41 - src/Pages/Home/Chart.tsx | 53 + src/Pages/Home/HomePage.tsx | 124 +- .../Home/tables/LastOrder/useTableColumn.tsx | 12 +- .../LastUserTable.tsx} | 10 +- .../useTableColumn.tsx | 39 +- src/Pages/Products/ProductsPage.tsx | 15 +- src/Pages/Products/View/AddPage.tsx | 136 ++- src/Pages/Products/View/Atteibute.tsx | 37 + src/Pages/Products/View/BasicInfo.tsx | 40 +- src/Pages/Products/View/BasicInfo2.tsx | 32 - src/Pages/Products/View/Edit/BasicInfo.tsx | 45 + .../View/Edit/FormikTab/Field/Atteibute.tsx | 36 + .../View/Edit/FormikTab/Field/File.tsx | 64 + .../View/Edit/FormikTab/Field/FileImage.tsx | 50 + .../View/Edit/FormikTab/Field}/Object.tsx | 62 +- .../FormikTab/Field}/SearchTabs.tsx | 0 .../View/Edit/FormikTab/Field/Select.tsx | 41 + .../Products/View/Edit/FormikTab/FormItem.tsx | 20 + .../Products/View/Edit/FormikTab/TabItem.tsx | 13 + .../View/Edit/FormikTab/TabsContainer.tsx | 115 ++ .../View/Edit/FormikTab/VariableTabs.tsx | 71 ++ src/Pages/Products/View/Edit/VarianInfo.tsx | 13 + src/Pages/Products/View/EditPage.tsx | 137 +++ .../View/FormikTab/Field/Atteibute.tsx | 37 + .../Products/View/FormikTab/Field/File.tsx | 63 + .../View/FormikTab/Field/FileImage.tsx | 49 + .../Products/View/FormikTab/Field/Object.tsx | 116 ++ .../View/FormikTab/Field/SearchTabs.tsx | 60 + .../Products/View/FormikTab/Field/Select.tsx | 41 + .../Products/View/FormikTab/FormItem.tsx | 19 + src/Pages/Products/View/FormikTab/TabItem.tsx | 13 + .../Products/View/FormikTab/TabsContainer.tsx | 104 ++ .../Products/View/FormikTab/VariableTabs.tsx | 130 ++ src/Pages/Products/View/Page.tsx | 92 -- src/Pages/Products/View/VarianInfo.tsx | 4 +- src/Pages/Products/View/taps/File.tsx | 41 - src/Pages/Products/View/taps/FileImage.tsx | 39 - src/Pages/Products/View/taps/NewTabs.tsx | 14 - .../Products/View/taps/ResposiveTabs.tsx | 232 ---- src/Pages/Products/View/taps/VariableTabs.tsx | 9 - src/Pages/Products/View/varianForm.tsx | 26 - src/Pages/Products/formUtil.ts | 96 +- src/Pages/Products/useTableColumns.tsx | 37 +- .../ProductsPage.tsx => Slider/Page.tsx} | 16 +- src/Pages/Slider/View/AddForm.tsx | 34 + src/Pages/Slider/View/AddPage.tsx | 57 + src/Pages/Slider/View/EditForm.tsx | 34 + .../Page.tsx => Slider/View/EditPage.tsx} | 60 +- src/Pages/{Coupon2 => Slider}/formUtil.ts | 29 +- .../{Coupon2 => Slider}/useTableColumns.tsx | 51 +- src/Pages/appSetting/FormAppSetting.tsx | 8 +- src/Pages/order/Edit/EditForm.tsx | 41 + src/Pages/order/Edit/EditPage.tsx | 86 ++ src/Pages/order/Edit/formUtil.ts | 59 + src/Pages/order/OrderPage.tsx | 7 +- src/Pages/order/useTableColumns.tsx | 44 +- src/Pages/order/view-one/Order.js | 5 +- src/Routes.tsx | 108 +- src/Styles/Layout/Layout.scss | 95 +- src/Styles/Layout/SideBar.scss | 1 - src/Styles/Layout/Table.scss | 15 +- src/api/Categories.ts | 3 +- src/api/Coupon.ts | 4 +- src/api/Slider.ts | 2 +- src/api/attribute.ts | 28 + src/api/config.ts | 4 +- src/api/helper/useGetSingleQuery.ts | 38 + src/api/helper/useUpdateMutation.ts | 11 +- src/api/helper/useUpdateMutationPut.ts | 52 + src/api/product.ts | 18 +- src/lib/ToastProvider.tsx | 1 - src/lib/state mangment/AuthState.ts | 2 +- src/translate/ar.json | 1067 ++--------------- src/translate/de.json | 108 ++ src/translate/en.json | 974 ++------------- src/translate/text | 0 src/utils/Array/ArrayToObjectFormik.ts | 26 + src/utils/Array/changeShapeInfo.tsx | 14 + src/utils/Array/getInfoKeyAndDescriptions.ts | 12 + 137 files changed, 3903 insertions(+), 3556 deletions(-) create mode 100644 public/Layout/De.svg delete mode 100644 src/Components/Karimalden/View/SearchField.tsx rename src/Components/{Karimalden => ValidationField}/Ui/KarimSpinner.tsx (100%) create mode 100644 src/Components/ValidationField/Ui/SearchBar.scss create mode 100644 src/Components/ValidationField/Ui/SearchBar.tsx rename src/Components/{Karimalden/KarimField.scss => ValidationField/ValidationField.scss} (98%) rename src/Components/{Karimalden/KarimField.tsx => ValidationField/ValidationField.tsx} (62%) rename src/Components/{Karimalden => ValidationField}/View/CheckboxField.tsx (95%) rename src/Components/{Karimalden => ValidationField}/View/DataRange.tsx (54%) rename src/Components/{Karimalden => ValidationField}/View/Date.tsx (96%) rename src/Components/{Karimalden => ValidationField}/View/Default.tsx (89%) rename src/Components/{Karimalden => ValidationField}/View/File.tsx (81%) rename src/Components/{Karimalden => ValidationField}/View/MaltyFile.tsx (87%) create mode 100644 src/Components/ValidationField/View/SearchField.tsx rename src/Components/{Karimalden => ValidationField}/View/SelectField.tsx (96%) rename src/Components/{Karimalden => ValidationField}/View/Time.tsx (96%) rename src/Components/{Karimalden => ValidationField}/View/index.tsx (100%) rename src/Components/{Karimalden => ValidationField}/index.tsx (100%) rename src/Components/{Karimalden => ValidationField}/types.ts (67%) create mode 100644 src/Hooks/isEmpty.tsx create mode 100644 src/Hooks/useFormatToSelect.tsx create mode 100644 src/Pages/Categories/View/Atteibute.tsx rename src/Pages/{Products/View/ObjectField.tsx => Categories/View/Field/Object.tsx} (73%) delete mode 100644 src/Pages/Coupon/FormProducts.tsx create mode 100644 src/Pages/Coupon/Page.tsx create mode 100644 src/Pages/Coupon/View/AddForm.tsx delete mode 100644 src/Pages/Coupon/View/BasicInfo.tsx delete mode 100644 src/Pages/Coupon/View/BasicInfo2.tsx create mode 100644 src/Pages/Coupon/View/EditForm.tsx create mode 100644 src/Pages/Coupon/View/EditPage.tsx delete mode 100644 src/Pages/Coupon2/AddCouponModal.tsx delete mode 100644 src/Pages/Coupon2/AddForm.tsx delete mode 100644 src/Pages/Coupon2/CouponPage.tsx delete mode 100644 src/Pages/Coupon2/EditCoupon/EditForm.tsx delete mode 100644 src/Pages/Coupon2/EditCoupon/Page.tsx create mode 100644 src/Pages/Home/Chart.tsx rename src/Pages/Home/tables/{HighDriverRate/HighDriverRateTable.tsx => LastUser/LastUserTable.tsx} (78%) rename src/Pages/Home/tables/{HighDriverRate => LastUser}/useTableColumn.tsx (51%) create mode 100644 src/Pages/Products/View/Atteibute.tsx delete mode 100644 src/Pages/Products/View/BasicInfo2.tsx create mode 100644 src/Pages/Products/View/Edit/BasicInfo.tsx create mode 100644 src/Pages/Products/View/Edit/FormikTab/Field/Atteibute.tsx create mode 100644 src/Pages/Products/View/Edit/FormikTab/Field/File.tsx create mode 100644 src/Pages/Products/View/Edit/FormikTab/Field/FileImage.tsx rename src/{Components/Karimalden/View => Pages/Products/View/Edit/FormikTab/Field}/Object.tsx (72%) rename src/Pages/Products/View/{taps => Edit/FormikTab/Field}/SearchTabs.tsx (100%) create mode 100644 src/Pages/Products/View/Edit/FormikTab/Field/Select.tsx create mode 100644 src/Pages/Products/View/Edit/FormikTab/FormItem.tsx create mode 100644 src/Pages/Products/View/Edit/FormikTab/TabItem.tsx create mode 100644 src/Pages/Products/View/Edit/FormikTab/TabsContainer.tsx create mode 100644 src/Pages/Products/View/Edit/FormikTab/VariableTabs.tsx create mode 100644 src/Pages/Products/View/Edit/VarianInfo.tsx create mode 100644 src/Pages/Products/View/EditPage.tsx create mode 100644 src/Pages/Products/View/FormikTab/Field/Atteibute.tsx create mode 100644 src/Pages/Products/View/FormikTab/Field/File.tsx create mode 100644 src/Pages/Products/View/FormikTab/Field/FileImage.tsx create mode 100644 src/Pages/Products/View/FormikTab/Field/Object.tsx create mode 100644 src/Pages/Products/View/FormikTab/Field/SearchTabs.tsx create mode 100644 src/Pages/Products/View/FormikTab/Field/Select.tsx create mode 100644 src/Pages/Products/View/FormikTab/FormItem.tsx create mode 100644 src/Pages/Products/View/FormikTab/TabItem.tsx create mode 100644 src/Pages/Products/View/FormikTab/TabsContainer.tsx create mode 100644 src/Pages/Products/View/FormikTab/VariableTabs.tsx delete mode 100644 src/Pages/Products/View/Page.tsx delete mode 100644 src/Pages/Products/View/taps/File.tsx delete mode 100644 src/Pages/Products/View/taps/FileImage.tsx delete mode 100644 src/Pages/Products/View/taps/NewTabs.tsx delete mode 100644 src/Pages/Products/View/taps/ResposiveTabs.tsx delete mode 100644 src/Pages/Products/View/taps/VariableTabs.tsx delete mode 100644 src/Pages/Products/View/varianForm.tsx rename src/Pages/{Coupon/ProductsPage.tsx => Slider/Page.tsx} (70%) create mode 100644 src/Pages/Slider/View/AddForm.tsx create mode 100644 src/Pages/Slider/View/AddPage.tsx create mode 100644 src/Pages/Slider/View/EditForm.tsx rename src/Pages/{Coupon/View/Page.tsx => Slider/View/EditPage.tsx} (52%) rename src/Pages/{Coupon2 => Slider}/formUtil.ts (50%) rename src/Pages/{Coupon2 => Slider}/useTableColumns.tsx (59%) create mode 100644 src/Pages/order/Edit/EditForm.tsx create mode 100644 src/Pages/order/Edit/EditPage.tsx create mode 100644 src/Pages/order/Edit/formUtil.ts create mode 100644 src/api/attribute.ts create mode 100644 src/api/helper/useGetSingleQuery.ts create mode 100644 src/api/helper/useUpdateMutationPut.ts create mode 100644 src/translate/de.json create mode 100644 src/translate/text create mode 100644 src/utils/Array/ArrayToObjectFormik.ts create mode 100644 src/utils/Array/changeShapeInfo.tsx create mode 100644 src/utils/Array/getInfoKeyAndDescriptions.ts diff --git a/package-lock.json b/package-lock.json index 59b9e5d..f10b8e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.14.19", + "@mui/x-charts": "^6.19.4", "@react-google-maps/api": "^2.19.2", "@szhsin/react-menu": "github:szhsin/react-menu", "@testing-library/jest-dom": "^5.17.0", @@ -33,6 +34,7 @@ "i18next": "^23.6.0", "i18next-browser-languagedetector": "^7.1.0", "json-server": "^0.17.4", + "moment": "^2.30.1", "react": "^18.2.0", "react-apexcharts": "^1.4.1", "react-bootstrap": "^2.9.1", @@ -2895,7 +2897,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.4.tgz", "integrity": "sha512-CF8k2rgKeh/49UrnIBs4BdxPUV6vize/Db1d/YbCLyp9GiVZ0BEwf5AiDSxJRCr6yOkGqTFHtmrULxkEfYZ7dQ==", - "peer": true, "dependencies": { "@floating-ui/dom": "^1.5.1" }, @@ -3394,7 +3395,6 @@ "version": "5.0.0-beta.26", "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.26.tgz", "integrity": "sha512-gPMRKC84VRw+tjqYoyBzyrBUqHQucMXdlBpYazHa5rCXrb91fYEQk5SqQ2U5kjxx9QxZxTBvWAmZ6DblIgaGhQ==", - "peer": true, "dependencies": { "@babel/runtime": "^7.23.4", "@floating-ui/react-dom": "^2.0.4", @@ -3605,7 +3605,6 @@ "version": "7.2.10", "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.10.tgz", "integrity": "sha512-wX1vbDC+lzF7FlhT6A3ffRZgEoKWPF8VqRoTu4lZwouFX2t90KyCMsgepMw5DxLak1BSp/KP86CmtZttikb/gQ==", - "peer": true, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0" }, @@ -3619,7 +3618,6 @@ "version": "5.14.20", "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.20.tgz", "integrity": "sha512-Y6yL5MoFmtQml20DZnaaK1znrCEwG6/vRSzW8PKOTrzhyqKIql0FazZRUR7sA5EPASgiyKZfq0FPwISRXm5NdA==", - "peer": true, "dependencies": { "@babel/runtime": "^7.23.4", "@types/prop-types": "^15.7.11", @@ -3643,6 +3641,41 @@ } } }, + "node_modules/@mui/x-charts": { + "version": "6.19.4", + "resolved": "https://registry.npmjs.org/@mui/x-charts/-/x-charts-6.19.4.tgz", + "integrity": "sha512-0kNg/6jVuG4GoZbV6qb9pYmL8Bhor1m55VIuVlu3p9WdsZFLUyksS4r08viII3YMxosl6MJdFnEfMjWJDAswXw==", + "dependencies": { + "@babel/runtime": "^7.23.2", + "@mui/base": "^5.0.0-beta.22", + "@react-spring/rafz": "^9.7.3", + "@react-spring/web": "^9.7.3", + "clsx": "^2.0.0", + "d3-color": "^3.1.0", + "d3-scale": "^4.0.2", + "d3-shape": "^3.2.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.4.1", + "@mui/system": "^5.4.1", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", @@ -3922,6 +3955,71 @@ "resolved": "https://registry.npmjs.org/@react-google-maps/marker-clusterer/-/marker-clusterer-2.19.2.tgz", "integrity": "sha512-x9ibmsP0ZVqzyCo1Pitbw+4b6iEXRw/r1TCy3vOUR3eKrzWLnHYZMR325BkZW2r8fnuWE/V3Fp4QZOP9qYORCw==" }, + "node_modules/@react-spring/animated": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.3.tgz", + "integrity": "sha512-5CWeNJt9pNgyvuSzQH+uy2pvTg8Y4/OisoscZIR8/ZNLIOI+CatFBhGZpDGTF/OzdNFsAoGk3wiUYTwoJ0YIvw==", + "dependencies": { + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/core": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.3.tgz", + "integrity": "sha512-IqFdPVf3ZOC1Cx7+M0cXf4odNLxDC+n7IN3MDcVCTIOSBfqEcBebSv+vlY5AhM0zw05PDbjKrNmBpzv/AqpjnQ==", + "dependencies": { + "@react-spring/animated": "~9.7.3", + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-spring/donate" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/rafz": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.7.3.tgz", + "integrity": "sha512-9vzW1zJPcC4nS3aCV+GgcsK/WLaB520Iyvm55ARHfM5AuyBqycjvh1wbmWmgCyJuX4VPoWigzemq1CaaeRSHhQ==" + }, + "node_modules/@react-spring/shared": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.3.tgz", + "integrity": "sha512-NEopD+9S5xYyQ0pGtioacLhL2luflh6HACSSDUZOwLHoxA5eku1UPuqcJqjwSD6luKjjLfiLOspxo43FUHKKSA==", + "dependencies": { + "@react-spring/types": "~9.7.3" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/types": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.3.tgz", + "integrity": "sha512-Kpx/fQ/ZFX31OtlqVEFfgaD1ACzul4NksrvIgYfIFq9JpDHFwQkMVZ10tbo0FU/grje4rcL4EIrjekl3kYwgWw==" + }, + "node_modules/@react-spring/web": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.3.tgz", + "integrity": "sha512-BXt6BpS9aJL/QdVqEIX9YoUy8CE6TJrU0mNCqSoxdXlIeNcEBWOfIyE6B14ENNsyQKS3wOWkiJfco0tCr/9tUg==", + "dependencies": { + "@react-spring/animated": "~9.7.3", + "@react-spring/core": "~9.7.3", + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/@remix-run/router": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.13.1.tgz", @@ -7501,6 +7599,100 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -10317,6 +10509,14 @@ "node": ">= 0.4" } }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } + }, "node_modules/invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -12557,6 +12757,14 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "engines": { + "node": "*" + } + }, "node_modules/morgan": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", diff --git a/package.json b/package.json index 52a22a7..3f55348 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "dependencies": { "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.14.19", + "@mui/x-charts": "^6.19.4", "@react-google-maps/api": "^2.19.2", "@szhsin/react-menu": "github:szhsin/react-menu", "@testing-library/jest-dom": "^5.17.0", @@ -28,6 +29,7 @@ "i18next": "^23.6.0", "i18next-browser-languagedetector": "^7.1.0", "json-server": "^0.17.4", + "moment": "^2.30.1", "react": "^18.2.0", "react-apexcharts": "^1.4.1", "react-bootstrap": "^2.9.1", diff --git a/public/Layout/De.svg b/public/Layout/De.svg new file mode 100644 index 0000000..543a1bc --- /dev/null +++ b/public/Layout/De.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/Components/Columns/ColumnsImage.tsx b/src/Components/Columns/ColumnsImage.tsx index 081aa1b..f5c45a4 100644 --- a/src/Components/Columns/ColumnsImage.tsx +++ b/src/Components/Columns/ColumnsImage.tsx @@ -14,8 +14,11 @@ import useImageError from '../../Hooks/useImageError'; const ColumnsImage= ({src}:any) => { const ErrorImage = "https://upload.wikimedia.org/wikipedia/commons/thumb/6/65/No-Image-Placeholder.svg/832px-No-Image-Placeholder.svg.png" - + console.log(ImageBaseURL + src,"ColumnsImage"); + const imageUrl = ImageBaseURL + src || ErrorImage; + console.log(imageUrl); + const handleError = useImageError; // or you can download flipped and rotated image // https://codesandbox.io/s/zi-ding-yi-gong-ju-lan-antd-5-7-0-forked-c9jvmp diff --git a/src/Components/Karimalden/View/SearchField.tsx b/src/Components/Karimalden/View/SearchField.tsx deleted file mode 100644 index bffbe3d..0000000 --- a/src/Components/Karimalden/View/SearchField.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { Input } from 'antd'; -import { SearchProps } from 'antd/es/input' -import { useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'; -const { Search } = Input; - -const SearchField = () => { - const navigate = useNavigate() - const [searchParams,] = useSearchParams(); - const location =useLocation() - const {t} = useTranslation(); - - const [searchValue, setSearchValue] = useState(searchParams.get('search')|| ""); - - - const onSearch: SearchProps['onSearch'] = (value, _e, info) => { - // console.log(value); - - navigate(`${location?.pathname}?search=${value}`, { replace: true }); - } - const onChange = (e :any) => { - setSearchValue(e.target.value); - - } - - - return ( -
- - -
- ) -} - -export default SearchField \ No newline at end of file diff --git a/src/Components/Ui/StaticsCard/StaticCard.tsx b/src/Components/Ui/StaticsCard/StaticCard.tsx index f82c1c4..362e20f 100644 --- a/src/Components/Ui/StaticsCard/StaticCard.tsx +++ b/src/Components/Ui/StaticsCard/StaticCard.tsx @@ -1,6 +1,5 @@ import React from "react"; import { Card, CardBody } from "reactstrap"; -import Chart from "react-apexcharts"; import { ChartTypeEnum } from "../../../enums/ChartTypeEnum"; import { history } from "../../../ProviderContainer"; import { useNavigate } from "react-router-dom"; @@ -33,7 +32,7 @@ const StatisticsCard = (props :StatisticsCardProps) => { } = props; return ( - navigate(pathWhenClick , {replace:true})}> + navigate(pathWhenClick , {replace:true})}> {
-

{CardTitle}

+ {/*

{CardTitle}

*/}
{icon}
-

{count}

+ {/*

{count}

*/}

{CardContent}

diff --git a/src/Components/Utils/Translate.tsx b/src/Components/Utils/Translate.tsx index f345457..6864551 100644 --- a/src/Components/Utils/Translate.tsx +++ b/src/Components/Utils/Translate.tsx @@ -1,8 +1,9 @@ import { Menu, MenuItem, MenuButton } from '@szhsin/react-menu'; import { useTranslation, initReactI18next } from 'react-i18next'; -import i18n from 'i18next'; // Make sure this import is correct +import i18n from 'i18next'; import translationEN from '../../translate/en.json'; import translationAR from '../../translate/ar.json'; +import translationDE from '../../translate/de.json'; i18n.use(initReactI18next).init({ resources: { @@ -11,6 +12,9 @@ i18n.use(initReactI18next).init({ }, ar: { translation: translationAR + }, + de: { + translation: translationDE } }, lng: 'en', @@ -18,60 +22,73 @@ i18n.use(initReactI18next).init({ escapeValue: false } }); -let What_the_language = localStorage.getItem('language') ?? "en"; + +let What_the_language = localStorage.getItem('language') ?? "en"; if (What_the_language === "en") { - i18n.changeLanguage('en'); - document.body.setAttribute('dir', 'ltr'); document.body.classList.add('en')} - else{ - i18n.changeLanguage('ar'); - document.body.setAttribute('dir', 'rtl'); document.body.classList.add('ar'); + document.body.setAttribute('dir', 'ltr'); + document.body.classList.add('en'); +} else if (What_the_language === "ar") { + i18n.changeLanguage('ar'); + document.body.setAttribute('dir', 'rtl'); + document.body.classList.add('ar'); +} else if (What_the_language === "de") { + i18n.changeLanguage('de'); + document.body.setAttribute('dir', 'ltr'); + document.body.classList.add('de'); } - export default function Translate() { const { t, i18n } = useTranslation(); - - const changeLanguage = (newLanguage : any) => { + const changeLanguage = (newLanguage : string) => { i18n.changeLanguage(newLanguage); - if(newLanguage === "Ar"){ - i18n.changeLanguage('ar'); - document.body.setAttribute('dir', 'rtl'); document.body.classList.add('ar');localStorage.setItem("language", "ar"); - What_the_language = "ar" - } - else if(newLanguage === "En"){ - i18n.changeLanguage('en'); - document.body.setAttribute('dir', 'ltr'); document.body.classList.remove('ar');localStorage.setItem("language", "en"); - What_the_language = "en" - + localStorage.setItem("language", newLanguage); + What_the_language = newLanguage; + if (newLanguage === "ar") { + document.body.setAttribute('dir', 'rtl'); + document.body.classList.remove('de'); + document.body.classList.add('ar'); + } else if (newLanguage === "en") { + document.body.setAttribute('dir', 'ltr'); + document.body.classList.remove('ar', 'de'); + document.body.classList.add('en'); + } else if (newLanguage === "de") { + document.body.setAttribute('dir', 'ltr'); + document.body.classList.remove('ar'); + document.body.classList.add('de'); } }; return ( -
- - {What_the_language === "ar" ? - <> - {t("Arabic")} - - - : - <> - {t("English")} - - - } - } transition> - changeLanguage('Ar')}> - {t("Arabic")} - - changeLanguage('En')}> - {t("English")} - - - -
+
+ + {What_the_language === "ar" ? + <> + {t("Arabic")} + + : + What_the_language === "de" ? + <> + {t("German")} + + : + <> + {t("English")} + + } + } transition> + changeLanguage('ar')}> + {t("Arabic")} + + changeLanguage('en')}> + {t("English")} + + changeLanguage('de')}> + {t("German")} + + +
); } diff --git a/src/Components/Karimalden/Ui/KarimSpinner.tsx b/src/Components/ValidationField/Ui/KarimSpinner.tsx similarity index 100% rename from src/Components/Karimalden/Ui/KarimSpinner.tsx rename to src/Components/ValidationField/Ui/KarimSpinner.tsx diff --git a/src/Components/ValidationField/Ui/SearchBar.scss b/src/Components/ValidationField/Ui/SearchBar.scss new file mode 100644 index 0000000..2ddadd9 --- /dev/null +++ b/src/Components/ValidationField/Ui/SearchBar.scss @@ -0,0 +1,48 @@ +.SearchBar{ + // margin-top: 20px; + .group { + display: flex; + align-items: center; + position: relative; + max-width: 350px; + width: 350px; + + } + + .input { + width: 100%; + height: 40px; + padding: 0 1rem; + padding-left: 2.5rem; + border-radius: 8px; + outline: none; + font-weight: 500; + background: var(--bg); + color: var(--text); + border: none; + box-shadow: 2px 2px 7px 0 var(--bg); + + } + + .input::placeholder { + color: var(--subtext); + opacity: .4; + + } + + + + .icon { + position: absolute; + left: 1rem; + fill: var(--subtext); + width: 1rem; + height: 1rem; + } + + + + + + +} \ No newline at end of file diff --git a/src/Components/ValidationField/Ui/SearchBar.tsx b/src/Components/ValidationField/Ui/SearchBar.tsx new file mode 100644 index 0000000..76c855c --- /dev/null +++ b/src/Components/ValidationField/Ui/SearchBar.tsx @@ -0,0 +1,35 @@ +import React, { useState } from 'react' +import './SearchBar.scss' +import { useNavigate, useSearchParams } from 'react-router-dom'; +const SearchBar = () => { + const [searchQuery, setSearchQuery] = useState(''); + const [searchParams] = useSearchParams() + const navigate = useNavigate(); + + const handleChange = (event:any) => { + const { value } = event.target; + setSearchQuery(value); + updateUrlParams(value); + }; + + const updateUrlParams = (value:any) => { + navigate(`?search=${value}`, { replace: true }); + + + }; + + return ( +
+
+ + +
+
+ ) +} + +export default SearchBar \ No newline at end of file diff --git a/src/Components/Karimalden/KarimField.scss b/src/Components/ValidationField/ValidationField.scss similarity index 98% rename from src/Components/Karimalden/KarimField.scss rename to src/Components/ValidationField/ValidationField.scss index 864c255..97e9f5e 100644 --- a/src/Components/Karimalden/KarimField.scss +++ b/src/Components/ValidationField/ValidationField.scss @@ -1,4 +1,4 @@ -.KarimField{ +.ValidationField{ >*{ width: 100%; } diff --git a/src/Components/Karimalden/KarimField.tsx b/src/Components/ValidationField/ValidationField.tsx similarity index 62% rename from src/Components/Karimalden/KarimField.tsx rename to src/Components/ValidationField/ValidationField.tsx index 2ecdc51..722bc5a 100644 --- a/src/Components/Karimalden/KarimField.tsx +++ b/src/Components/ValidationField/ValidationField.tsx @@ -1,13 +1,17 @@ import React from "react"; -import "./KarimField.scss"; +import "./ValidationField.scss"; import { Date, Time, File, DataRange, SelectField, Default, CheckboxField } from './View'; -import { KarimFieldProps } from "./types"; +import { ValidationFieldProps } from "./types"; import MaltyFile from "./View/MaltyFile"; +import SearchField from "./View/SearchField"; -const KarimField: React.FC = ({type = "text", ...otherProps}) => { +const ValidationField: React.FC = ({type , ...otherProps}) => { + switch (type) { case 'Select': return ; + case 'Search': + return ; case "DataRange": return ; case "Date": @@ -21,8 +25,8 @@ const KarimField: React.FC = ({type = "text", ...otherProps}) = case "Checkbox": return ; default: - return ; + return ; } }; -export default React.memo(KarimField); +export default React.memo(ValidationField); diff --git a/src/Components/Karimalden/View/CheckboxField.tsx b/src/Components/ValidationField/View/CheckboxField.tsx similarity index 95% rename from src/Components/Karimalden/View/CheckboxField.tsx rename to src/Components/ValidationField/View/CheckboxField.tsx index 329bffd..21c419e 100644 --- a/src/Components/Karimalden/View/CheckboxField.tsx +++ b/src/Components/ValidationField/View/CheckboxField.tsx @@ -25,7 +25,7 @@ const CheckboxField = ({ name, label, isDisabled, onChange,Group,className, prop > - {t(label)} + {t(`${label ? label : name}`)} diff --git a/src/Components/Karimalden/View/DataRange.tsx b/src/Components/ValidationField/View/DataRange.tsx similarity index 54% rename from src/Components/Karimalden/View/DataRange.tsx rename to src/Components/ValidationField/View/DataRange.tsx index 6639e76..742e6b5 100644 --- a/src/Components/Karimalden/View/DataRange.tsx +++ b/src/Components/ValidationField/View/DataRange.tsx @@ -5,34 +5,35 @@ import useFormField from '../../../Hooks/useFormField'; const { RangePicker } = DatePicker; -const DataRange = ({ name, label,Format ,props ,onChange,isDisabled,placeholder,className}: any) => { +const DataRange = ({ name, label, Format, props, onChange, isDisabled, placeholder, className }: any) => { const { errorMsg, isError, t, formik } = useFormField(name, props) const onCalendarChange = (value: any) => { - + formik.setFieldValue(name, value) }; return ( -
+
- + diff --git a/src/Components/Karimalden/View/Date.tsx b/src/Components/ValidationField/View/Date.tsx similarity index 96% rename from src/Components/Karimalden/View/Date.tsx rename to src/Components/ValidationField/View/Date.tsx index 4f96987..dfb5757 100644 --- a/src/Components/Karimalden/View/Date.tsx +++ b/src/Components/ValidationField/View/Date.tsx @@ -13,7 +13,7 @@ const Date = ({ name, label,picker="date" ,isDisabled,props,onChange,placeholder }; return ( -
+
diff --git a/src/Components/Karimalden/View/Default.tsx b/src/Components/ValidationField/View/Default.tsx similarity index 89% rename from src/Components/Karimalden/View/Default.tsx rename to src/Components/ValidationField/View/Default.tsx index 6f960ab..62b7544 100644 --- a/src/Components/Karimalden/View/Default.tsx +++ b/src/Components/ValidationField/View/Default.tsx @@ -2,12 +2,11 @@ import { Form, Input } from 'antd' import React from 'react' import useFormField from '../../../Hooks/useFormField'; -const Default = ({ name, label, placeholder, isDisabled, onChange, props,type="text" }: any) => { +const Default = ({ name, label, placeholder, isDisabled, onChange, props,type }: any) => { const { Field, formik, isError, errorMsg, t } = useFormField(name, props); - return ( -
+
@@ -18,7 +17,7 @@ const Default = ({ name, label, placeholder, isDisabled, onChange, props,type="t > { const { formik, t ,isError} = useFormField(name, props) - const imageUrl = formik.values[name] ? ImageBaseURL + formik.values[name] : ''; + let FormikName = formik.values[name]; + const imageUrl = formik.values[name] ? ImageBaseURL + FormikName : ''; + const fileList: UploadFile[] = [ { uid: '-1', name: '', status: 'done', - url: imageUrl, - thumbUrl: imageUrl, + url: FormikName == ""? imageUrl : imageUrl?.replace("public", "/storage"), + thumbUrl: FormikName == ""? imageUrl : imageUrl?.replace("public", "/storage") } ]; const FilehandleChange = (value:any) => { @@ -27,7 +29,7 @@ const File = ({ name, label, onChange, isDisabled,placholder,className, props }: onSuccess(); }; return ( -
+
diff --git a/src/Components/Karimalden/View/MaltyFile.tsx b/src/Components/ValidationField/View/MaltyFile.tsx similarity index 87% rename from src/Components/Karimalden/View/MaltyFile.tsx rename to src/Components/ValidationField/View/MaltyFile.tsx index 7e953dd..c383aea 100644 --- a/src/Components/Karimalden/View/MaltyFile.tsx +++ b/src/Components/ValidationField/View/MaltyFile.tsx @@ -6,8 +6,8 @@ import useFormField from '../../../Hooks/useFormField'; const MaltyFile = ({ name, label, onChange, isDisabled, placholder, className, props }: any) => { const { formik, t, isError } = useFormField(name, props); - const imageUrl = formik.values[name] ? ImageBaseURL + formik.values[name] : ''; - const fileList = formik.values[name] ? formik.values[name].map((file: any, index: number) => ({ + const imageUrl = formik?.values[name] ? ImageBaseURL + formik.values[name] : ''; + const fileList = formik?.values[name] ? formik?.values[name]?.map((file: any, index: number) => ({ uid: index, name: file.name, status: 'done', @@ -25,7 +25,7 @@ const MaltyFile = ({ name, label, onChange, isDisabled, placholder, className, p }; return ( -
+
diff --git a/src/Components/ValidationField/View/SearchField.tsx b/src/Components/ValidationField/View/SearchField.tsx new file mode 100644 index 0000000..35bc235 --- /dev/null +++ b/src/Components/ValidationField/View/SearchField.tsx @@ -0,0 +1,56 @@ +import { Form, Select } from 'antd'; +import React, { useEffect, useState } from 'react'; +import useFormField from '../../../Hooks/useFormField'; +import { useNavigate } from 'react-router-dom'; + +const SearchField = ({ name, label, placeholder, isDisabled, searchBy, option, isMulti, onChange, className, props }: any) => { + const { errorMsg, isError, t, formik } = useFormField(name, props); + const [searchQuery, setSearchQuery] = useState(''); + const navigate = useNavigate() + useEffect(() => { + const searchParams = new URLSearchParams(window.location.search); + setSearchQuery(searchParams?.get('search') || ''); + }, []); + + + + const SelecthandleChange = (value: { value: string; label: React.ReactNode }) => { + formik.setFieldValue(name, value); + + }; + const SearchHandleChange = (value:any) => { + navigate(`${window?.location?.pathname}?${searchBy}=${value}`, { replace: true }); + + }; + + return ( +
+ + + { ))}
)} @@ -91,4 +111,4 @@ const ObjectField = () => { ); }; -export default ObjectField; +export default ObjectField \ No newline at end of file diff --git a/src/Pages/Categories/formUtil.ts b/src/Pages/Categories/formUtil.ts index b585f4a..67bf305 100644 --- a/src/Pages/Categories/formUtil.ts +++ b/src/Pages/Categories/formUtil.ts @@ -3,34 +3,49 @@ import * as Yup from "yup"; import { buildFormData } from "../../api/helper/buildFormData"; interface formUtilCommon { - number:number, - value:number + number: number, + value: number } interface ObjectToEdit extends formUtilCommon { - id?:number, + id?: number, } interface InitialValues extends ObjectToEdit { } -interface ValidateSchema extends formUtilCommon{ +interface ValidateSchema extends formUtilCommon { } export const getInitialValues = (objectToEdit: any | null = null): any => { - console.log(objectToEdit,"objectToEdit"); return { id: objectToEdit?.id ?? 0, - name:objectToEdit?.name ?? "", + name: objectToEdit?.name ?? "", name_ar: objectToEdit?.name?.ar ?? '', name_en: objectToEdit?.name?.en ?? '', name_de: objectToEdit?.name?.de ?? '', - parent_id: objectToEdit?.parent_id ?? 1, + parent_id: objectToEdit?.parent_id ?? "", photo: objectToEdit?.photo ?? '', + attribute: objectToEdit?.attribute ?? "", + new_attribute: objectToEdit?.attribute ?? "" + }; }; +export const getInitialValuesForAdd = (objectToEdit: any | null = null): any => { + return { + name_ar: '', + name_en: '', + name_de: '', + parent_id: "", + photo: '', + attribute: "", + new_attribute: "" + + }; +}; + export const getValidationSchema = (editMode: boolean = false): Yup.Schema => { @@ -41,6 +56,7 @@ export const getValidationSchema = (editMode: boolean = false): Yup.Schema name_de: Yup.string().required('Required'), parent_id: Yup.string().required('Required'), photo: Yup.string().required('Required'), + }); }; @@ -48,18 +64,18 @@ export const getValidationSchema = (editMode: boolean = false): Yup.Schema export const getDataToSend = (values: any): FormData => { const data = { ...values }; - - + + const formData = new FormData(); buildFormData(formData, data); return formData; }; -export const ChangeDataToPrint = (data:any)=>{ +export const ChangeDataToPrint = (data: any) => { let new_array = data - for(let i =0 ; i { name: t("image"), sortable: false, center: "true", - cell: (row:any) => + cell: (row:any) => { + let str = row?.photo; + str = str?.replace(`public`, "/storage") ?? ""; + return + } + }, { name: t("parent_id"), diff --git a/src/Pages/Coupon/FormProducts.tsx b/src/Pages/Coupon/FormProducts.tsx deleted file mode 100644 index 22cd08d..0000000 --- a/src/Pages/Coupon/FormProducts.tsx +++ /dev/null @@ -1,55 +0,0 @@ - -import React from 'react' -import { Col, Row } from 'reactstrap'; -import KarimField from '../../Components/Karimalden/KarimField'; -import { useFormikContext } from 'formik'; - -import { DatePicker } from 'antd'; -import { useTranslation } from 'react-i18next'; - -function FormProduct() { - const formik = useFormikContext(); - const [t] = useTranslation(); - - return ( - - - - - - - - - - - - - - - - - - ) -} - -export default FormProduct - - diff --git a/src/Pages/Coupon/Page.tsx b/src/Pages/Coupon/Page.tsx new file mode 100644 index 0000000..5de1d36 --- /dev/null +++ b/src/Pages/Coupon/Page.tsx @@ -0,0 +1,44 @@ + +import React from 'react' +import DashBody from '../../Layout/Dashboard/DashBody' +import DashHeader from '../../Layout/Dashboard/DashHeader' +import LyTable from '../../Layout/Dashboard/LyTable' +import useTableColumns from './useTableColumns' +import { QueryStatusEnum } from '../../config/QueryStatus' +import { useGetProduct } from '../../api/product' +import { Button } from 'antd' +import { useTranslation } from 'react-i18next' +import { useNavigate } from 'react-router-dom' +import AddButton from '../../Layout/Dashboard/AddButton/AddButton' +import { useGetCoupon } from '../../api/Coupon' + +function Page() { + + const column =useTableColumns() + const {data ,status } = useGetCoupon() + const [t] = useTranslation() + const navigate = useNavigate() + const totalRows = data?.meta?.total; + + return ( + // Pass Status to Layout + + + navigate('/coupon/add')}> + + + + + + + ) +} + +export default Page + diff --git a/src/Pages/Coupon/View/AddForm.tsx b/src/Pages/Coupon/View/AddForm.tsx new file mode 100644 index 0000000..48294bf --- /dev/null +++ b/src/Pages/Coupon/View/AddForm.tsx @@ -0,0 +1,60 @@ + +import React from 'react' +import { Col, Row } from 'reactstrap'; +import ValidationField from '../../../Components/ValidationField/ValidationField'; +import { useFormikContext } from 'formik'; + +import { DatePicker } from 'antd'; +import { useTranslation } from 'react-i18next'; +import { isEmpty } from '../../../Hooks/isEmpty'; +import { useGetCategories } from '../../../api/Categories'; +import useFormatToSelect from '../../../Hooks/useFormatToSelect'; +import { useGetProduct } from '../../../api/product'; + +function Form() { + const { values } = useFormikContext(); + const [t] = useTranslation(); // FLAT coupn not be spacified && flate + const coupon_type = [{ lable: "general", value: "general" },{ lable: "specified", value: "specified" }] + const coupon_type_discount_flat = [{ lable: "general", value: "general" }] + + const discount_type = [{ lable: "percentage", value: "percentage" },{ lable: "flat", value: "flat" }] + const { data: CategoriesData } = useGetCategories() + const { data: ProductData } = useGetProduct() + + const SelectCategoriesData = useFormatToSelect(CategoriesData?.categories) + const SelectProductData = useFormatToSelect(ProductData?.BaseProducts) + return ( + + + + + + + + + + + + + + + + {/* */} + + + + + + + + + + + ) +} + +export default Form + + + + diff --git a/src/Pages/Coupon/View/AddPage.tsx b/src/Pages/Coupon/View/AddPage.tsx index 6247fe6..b5cdadd 100644 --- a/src/Pages/Coupon/View/AddPage.tsx +++ b/src/Pages/Coupon/View/AddPage.tsx @@ -3,65 +3,68 @@ import { getInitialValues, getValidationSchema, getDataToSend } from '../formUti import { Tab, TabList, TabPanel as TabBody, Tabs } from 'react-tabs' import 'react-tabs/style/react-tabs.css'; import { MdLanguage } from 'react-icons/md' -import { FaSadCry } from 'react-icons/fa' import ViewPage from '../../../Layout/Dashboard/ViewPage'; -import { Rate } from 'antd'; -import BasicInfo from './BasicInfo'; -import { usePageState } from '../../../lib/state mangment/LayoutPagestate'; -import { useParams } from 'react-router-dom'; -import LoadingPage from '../../../Layout/app/LoadingPage'; import { useTranslation } from 'react-i18next'; -import { BsInfoCircle } from 'react-icons/bs'; -import BasicInfo2 from './BasicInfo2'; import useNavigateOnSuccess from '../../../Hooks/useNavigateOnSuccess'; -import { useAddProduct } from '../../../api/product'; +import { useAddCoupon } from '../../../api/Coupon'; +import Form from './AddForm'; + +const AddCouponPage = () => { + + + const { mutate, isLoading, isSuccess } = useAddCoupon() + const handleSubmit = (values: any) => { + + values.active_at = values.active[0].format('YYYY-MM-DD HH:mm:ss.SSS') + values.active_to = values.active[1].format('YYYY-MM-DD HH:mm:ss.SSS') + values.status = values.active ? "active" : "inactive" + -const AddProductPage = () => { - const {mutate , isLoading , isSuccess} = useAddProduct() - const [BarStatus, setBarStatus] = useState({ value: 0, isLoading: false, isError: false, isSuccess: false }) - const handleSubmit = (values:any)=>{ +const products = values?.product_attr?.map((item: any) => { + return { "itemable_type": "product", "itemable_id": item }; +})?.filter((item: any) => item.itemable_id !== "")|| []; - console.log(values); +const category = values?.category_attr?.map((item: any) => { + return { "itemable_type": "category", "itemable_id": item }; +})?.filter((item: any) => item.itemable_id !== "") || []; - const formToSend = getDataToSend(values) +values['items'] = [...products, ...category]; + +console.log(values, "values"); + +mutate(values) + + }; + + const { t } = useTranslation(); + + useNavigateOnSuccess(isSuccess, '/Coupon') - mutate(formToSend); - - } - const {t} = useTranslation(); - useNavigateOnSuccess(isSuccess , '/products' ) - - - - const ViewProps = { getInitialValues, getValidationSchema, getDataToSend, handleSubmit, BarStatus }; + const ViewProps = { getInitialValues, getValidationSchema, getDataToSend, handleSubmit }; return (
- - - - -
{t("BasicInfo")}
-
{t("BasicInfo2")}
+ + + +
{t("BasicInfo")}
-
- -
-
- -
-
- -
-
- + +
+ +
+
+ +
+
+
@@ -69,4 +72,4 @@ const AddProductPage = () => { } -export default AddProductPage \ No newline at end of file +export default AddCouponPage \ No newline at end of file diff --git a/src/Pages/Coupon/View/BasicInfo.tsx b/src/Pages/Coupon/View/BasicInfo.tsx deleted file mode 100644 index 1ba9e67..0000000 --- a/src/Pages/Coupon/View/BasicInfo.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import React from 'react' -import { Col, Row } from 'reactstrap' -import KarimField from '../../../Components/Karimalden/KarimField' -import { useTranslation } from 'react-i18next'; - -const BasicInfo = () => { - const [t] = useTranslation(); - - return ( - - - - - - - - - - - - - - - - - ) -} - -export default BasicInfo \ No newline at end of file diff --git a/src/Pages/Coupon/View/BasicInfo2.tsx b/src/Pages/Coupon/View/BasicInfo2.tsx deleted file mode 100644 index 378d320..0000000 --- a/src/Pages/Coupon/View/BasicInfo2.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import React from 'react' -import { Col, Row } from 'reactstrap' -import KarimField from '../../../Components/Karimalden/KarimField' -import { useTranslation } from 'react-i18next'; - -const BasicInfo2 = () => { - const [t] = useTranslation(); - - const categoryOption = [] as any - - - - return ( - - - - - - - - - {/* */} - - - - - - -{/* - - */} - - - - - - - - - - - ) -} - -export default BasicInfo2 \ No newline at end of file diff --git a/src/Pages/Coupon/View/EditForm.tsx b/src/Pages/Coupon/View/EditForm.tsx new file mode 100644 index 0000000..48294bf --- /dev/null +++ b/src/Pages/Coupon/View/EditForm.tsx @@ -0,0 +1,60 @@ + +import React from 'react' +import { Col, Row } from 'reactstrap'; +import ValidationField from '../../../Components/ValidationField/ValidationField'; +import { useFormikContext } from 'formik'; + +import { DatePicker } from 'antd'; +import { useTranslation } from 'react-i18next'; +import { isEmpty } from '../../../Hooks/isEmpty'; +import { useGetCategories } from '../../../api/Categories'; +import useFormatToSelect from '../../../Hooks/useFormatToSelect'; +import { useGetProduct } from '../../../api/product'; + +function Form() { + const { values } = useFormikContext(); + const [t] = useTranslation(); // FLAT coupn not be spacified && flate + const coupon_type = [{ lable: "general", value: "general" },{ lable: "specified", value: "specified" }] + const coupon_type_discount_flat = [{ lable: "general", value: "general" }] + + const discount_type = [{ lable: "percentage", value: "percentage" },{ lable: "flat", value: "flat" }] + const { data: CategoriesData } = useGetCategories() + const { data: ProductData } = useGetProduct() + + const SelectCategoriesData = useFormatToSelect(CategoriesData?.categories) + const SelectProductData = useFormatToSelect(ProductData?.BaseProducts) + return ( + + + + + + + + + + + + + + + + {/* */} + + + + + + + + + + + ) +} + +export default Form + + + + diff --git a/src/Pages/Coupon/View/EditPage.tsx b/src/Pages/Coupon/View/EditPage.tsx new file mode 100644 index 0000000..5094d0c --- /dev/null +++ b/src/Pages/Coupon/View/EditPage.tsx @@ -0,0 +1,89 @@ +import React, { useEffect, useState } from 'react' +import {getInitialValuesForAdd as getInitialValues, getDataToSend } from '../formUtil' +import { Tab, TabList, TabPanel as TabBody, Tabs } from 'react-tabs' +import 'react-tabs/style/react-tabs.css'; +import { MdLanguage } from 'react-icons/md' +import { FaSadCry } from 'react-icons/fa' +import ViewPage from '../../../Layout/Dashboard/ViewPage'; +import { Rate } from 'antd'; +import { usePageState } from '../../../lib/state mangment/LayoutPagestate'; +import { useParams } from 'react-router-dom'; +import LoadingPage from '../../../Layout/app/LoadingPage'; +import { useTranslation } from 'react-i18next'; +import { BsInfoCircle } from 'react-icons/bs'; +import { useGetOneCoupon, useUpdateCoupon } from '../../../api/Coupon'; +import useNavigateOnSuccess from '../../../Hooks/useNavigateOnSuccess'; +import Form from './EditForm'; + +const EditPage = () => { + const { setObjectToEdit, objectToEdit } = usePageState() + const { t } = useTranslation(); + const { data } = useGetOneCoupon() + const { mutate, isSuccess } = useUpdateCoupon("put") + const FormatedData = data?.coupon; + const handleSubmit = (values: any) => { + + + values.active_at = values.active[0].format('YYYY-MM-DD HH:mm:ss.SSS') + values.active_to = values.active[1].format('YYYY-MM-DD HH:mm:ss.SSS') + values.status = values.active ? "active" : "inactive" + + + const products = values?.product_attr?.map((item: any) => { + return { "itemable_type": "product", "itemable_id": item }; + })?.filter((item: any) => item.itemable_id !== "") || []; + + const category = values?.category_attr?.map((item: any) => { + return { "itemable_type": "category", "itemable_id": item }; + })?.filter((item: any) => item.itemable_id !== "") || []; + + values['items'] = [...products, ...category]; + + console.log(values, "values"); + + mutate(values) + } + + useNavigateOnSuccess(isSuccess, '/Coupon') + + + useEffect(() => { + + setObjectToEdit(data?.coupon); + + }, [data]); + + + const getValidationSchema = () => { + return null + }; + + + const ViewProps = { getInitialValues, getValidationSchema, getDataToSend, handleSubmit }; + + + return ( +
+ {objectToEdit && data ? + + + +
{t("BasicInfo")}
+ +
+ +
+
+ + +
+
+ : } + + +
+ ) + +} + +export default EditPage \ No newline at end of file diff --git a/src/Pages/Coupon/formUtil.ts b/src/Pages/Coupon/formUtil.ts index fd6fa77..5d34ed5 100644 --- a/src/Pages/Coupon/formUtil.ts +++ b/src/Pages/Coupon/formUtil.ts @@ -1,70 +1,118 @@ import * as Yup from "yup"; import { buildFormData } from "../../api/helper/buildFormData"; -import { mapTranslatedProperties } from "../../utils/language/mapTranslatedProperties"; +import moment from 'moment'; +import * as dayjs from 'dayjs' +interface formUtilCommon { + number: number, + value: number +} +interface ObjectToEdit extends formUtilCommon { -export const getInitialValues = (objectToEdit: any | null = null) => { - - // console.log(objectToEdit); - + id?: number, + +} + +interface InitialValues extends ObjectToEdit { + +} +interface ValidateSchema extends formUtilCommon { + +} + +export const getInitialValues = (objectToEdit: any | null = null): any => { + //@ts-ignore + + const products = [] as any; + const categories = [] as any; + + // Map over the items array and push items into the appropriate array + objectToEdit?.items?.forEach((item: any) => { + if (item?.itemable_type === "product") { + products.push({ value: item?.itemable?.name, label: item?.itemable?.name }); + } else if (item?.itemable_type === "category") { + categories.push({ value: item?.itemable?.name, label: item?.itemable?.name }); + } + }); return { - product_price:objectToEdit?.product_price??0, - product_quantity:objectToEdit?.product_quantity??0, - product_main_image:objectToEdit?.product_main_image??'', - translated_fields: { - 1: { - product_name: mapTranslatedProperties(objectToEdit?.product_translations ,'name', 1) ??'', - product_description: mapTranslatedProperties(objectToEdit?.product_translations ,'description', 1) ?? '', + id: objectToEdit?.id ?? 0, + name: objectToEdit?.name ?? "", + code: objectToEdit?.code ?? "", + //@ts-ignore + active: objectToEdit?.active_to ? [dayjs(objectToEdit?.active_from), dayjs(objectToEdit?.active_to)] : "", + minimum_total_to_order: objectToEdit?.minimum_total_to_order ?? "", + maximum_number_of_uses_per_user: objectToEdit?.maximum_number_of_uses_per_user ?? "", + maximum_number_of_uses: objectToEdit?.maximum_number_of_uses ?? "", - }, - 2: { - product_name: mapTranslatedProperties(objectToEdit?.product_translations ,'name', 2) ?? '', - product_description: mapTranslatedProperties(objectToEdit?.product_translations ,'description', 2) ?? '', - }, - }, - category_id:objectToEdit?.category_id ?? null, - is_highlight:objectToEdit?.is_highlight??false, - is_most_purchase:objectToEdit?.is_most_purchase??false, - is_cheapest:objectToEdit?.is_cheapest??false - } + coupon_value: objectToEdit?.coupon_value ?? "", + coupon_type: objectToEdit?.coupon_type ?? "", + discount_type: objectToEdit?.discount_type ?? "", + product_attr: products ?? "", + category_attr: categories ?? "", + status: objectToEdit?.status ?? 0, + + + }; }; -export const getValidationSchema = (editMode: boolean = false) => { - // validate input +export const getInitialValuesForAdd = (objectToEdit: any | null = null): any => { + return { + id: '', + name: '', + code: '', + active: '', + minimum_total_to_order: '', + maximum_number_of_uses_per_user: '', + maximum_number_of_uses: '', + coupon_value: '', + coupon_type: '', + discount_type: '', + product_attr: '', + category_attr: '', + status: '', + + + + }; +}; + +export const getValidationSchema = (editMode: boolean = false): Yup.Schema => { + // Validate input return Yup.object().shape({ - translated_fields : Yup.object().shape({ - 1: Yup.object().shape({ - product_name :Yup.string().required("required"), - product_description :Yup.string().required("required") - }), - 2: Yup.object().shape({ - product_name :Yup.string().required("required"), - product_description :Yup.string().required("required") + name: Yup.string().required('Required'), + code: Yup.string().required('Required'), + coupon_value: Yup.string().required('Required'), + status: Yup.string().required('Required'), + active: Yup.mixed().required('Required'), + discount_type: Yup.string().required('Required'), - }) - }), - category_id :Yup.string().required("required"), + coupon_type: Yup.string().required('Required'), + minimum_total_to_order: Yup.number().required('Required'), + maximum_number_of_uses: Yup.number().required('Required'), + maximum_number_of_uses_per_user: Yup.number().required('Required'), - ...(!editMode && { - product_main_image: Yup.mixed().required('required'), - }), }); }; + + export const getDataToSend = (values: any): FormData => { const data = { ...values }; - // console.log(data); - if(typeof data['product_main_image'] == 'string') delete data['product_main_image'] - data['en_product_name'] = values['translated_fields']['1']['product_name'] -data['ar_product_name'] =values['translated_fields']['2']['product_name'] -data['ar_product_description'] =values['translated_fields']['2']['product_description'] -data['en_product_description'] =values['translated_fields']['1']['product_description'] const formData = new FormData(); buildFormData(formData, data); return formData; }; +export const ChangeDataToPrint = (data: any) => { + + let new_array = data + for (let i = 0; i < data.length; i++) { + new_array[i]['status'] = !data[i]['deleted_at'] ? 'available' : 'unavailable' + delete new_array[i]['deleted_at'] + } + return new_array +} \ No newline at end of file diff --git a/src/Pages/Coupon/useTableColumns.tsx b/src/Pages/Coupon/useTableColumns.tsx index c827704..e5a93cd 100644 --- a/src/Pages/Coupon/useTableColumns.tsx +++ b/src/Pages/Coupon/useTableColumns.tsx @@ -2,87 +2,64 @@ import React, { useMemo } from "react"; import { useTranslation } from "react-i18next"; import Actions from "../../Components/Ui/tables/Actions"; -import { HovarableImage } from "../../Components/Ui"; -import { BaseURL } from "../../api/config"; -import { ToggleStatus } from "../../Components/Ui/ToggleStatus"; import ColumnsImage from "../../Components/Columns/ColumnsImage"; -import LoadingSpinner from "../../Components/Ui/LoadingSpinner"; -import { Switch } from "antd"; -import { mapTranslatedProperties } from "../../utils/language/mapTranslatedProperties"; -// import { useDeleteProduct, useUpdateProductStatus } from "../../api/owner_products"; import { useNavigate } from "react-router-dom"; -import { useDeleteProduct, useUpdateProductStatus } from "../../api/product"; +import { useDeleteCoupon } from "../../api/Coupon"; +function fnDelete(props :any ){} const useTableColumns :any = () => { const [t] = useTranslation(); - const toggleMutation = useUpdateProductStatus(); - const deleteMutation = useDeleteProduct(); - - const navigate = useNavigate() - const handleChange = (row:any)=> { - const status = row?.favorite ; - toggleMutation.mutate({id:row?.id,new_status:status}) - - } - + const deleteMutation = useDeleteCoupon() + const navigate = useNavigate() return useMemo( () => [ - { - name: t("image"), - center: "true", - cell: (row: any) => { - return ( - - ) - } - }, { name: t("name"), sortable: false, - center: true, - selector:(row:any) => row?.name, - + center: "true", + cell: (row:any) => row?.name }, { - name: t("price"), + name: t("discount_type"), sortable: false, - center: true, - selector:(row:any) => row?.price, - + center: "true", + cell: (row:any) => row?.discount_type }, { - name: t("description"), + name: t("coupon_type"), sortable: false, - center: true, - cell: (row:any) => ( - row?.description - ), + center: "true", + cell: (row:any) => row?.coupon_type }, - { - name: t("favorite"), + name: t("code"), sortable: false, - center: true, - cell: (row:any) => ( - - ), + center: "true", + cell: (row:any) => row?.code + }, + { + name: t("coupon_value"), + sortable: false, + center: "true", + cell: (row:any) => row?.coupon_value }, { name: "#", sortable: false, - center: "true", + center: true, cell: (row:any) => ( - navigate('/products/'+row.id)} - objectToEdit={row} - showEdit={true} - showView={false} - onDelete={() => deleteMutation.mutate({ product_id: row.id })} - /> + navigate(`/coupon/${row.id}`) } + showView={false} + onDelete={() => deleteMutation.mutate({ id: row.id })} + /> ), }, + ], [t] ); diff --git a/src/Pages/Coupon2/AddCouponModal.tsx b/src/Pages/Coupon2/AddCouponModal.tsx deleted file mode 100644 index 1e8662c..0000000 --- a/src/Pages/Coupon2/AddCouponModal.tsx +++ /dev/null @@ -1,43 +0,0 @@ - - -import React from 'react' -import LayoutModal from '../../Layout/Dashboard/LayoutModal' -import AddForm from './AddForm' -import { useAddCoupon } from '../../api/Coupon' -import { getDataToSend, getInitialValues, getValidationSchema } from './formUtil' -import { QueryStatusEnum } from '../../config/QueryStatus' -import { useTranslation } from 'react-i18next' - -function AddCouponModal() { - - - const [t] = useTranslation() - const {mutate , status} = useAddCoupon() - const handelSubmit = (values:any )=>{ - values['name'] = { - "en" : values.name_en, - "ar" : values.name_ar, - "de" : values.name_de, - } - console.log(values); - mutate(values) - - } - return ( - - - - - ) -} - -export default AddCouponModal - diff --git a/src/Pages/Coupon2/AddForm.tsx b/src/Pages/Coupon2/AddForm.tsx deleted file mode 100644 index 2556b20..0000000 --- a/src/Pages/Coupon2/AddForm.tsx +++ /dev/null @@ -1,37 +0,0 @@ - -import React from 'react' -import { Col, Row } from 'reactstrap'; -import KarimField from '../../Components/Karimalden/KarimField'; -import { FakeSelectData } from '../../Layout/app/Const'; -import { useFormikContext } from 'formik'; - -import { DatePicker } from 'antd'; -import { useGetSlider } from '../../api/Slider'; - -function AddForm() { - const formik = useFormikContext(); - const {data } = useGetSlider() - - - return ( - - - - - - - - - - - - - - - - ) -} - -export default AddForm - - diff --git a/src/Pages/Coupon2/CouponPage.tsx b/src/Pages/Coupon2/CouponPage.tsx deleted file mode 100644 index cffad89..0000000 --- a/src/Pages/Coupon2/CouponPage.tsx +++ /dev/null @@ -1,40 +0,0 @@ - -import React from 'react' -import DashBody from '../../Layout/Dashboard/DashBody' -import DashHeader from '../../Layout/Dashboard/DashHeader' -import LyTable from '../../Layout/Dashboard/LyTable' -import useTableColumns from './useTableColumns' -import { useGetCoupon} from '../../api/Coupon' - -import { useTranslation } from 'react-i18next' -import AddCouponModal from './AddCouponModal' -import { QueryStatusEnum } from '../../config/QueryStatus' -// import * as XLSX from 'ts-xlsx'; - -function CouponPage() { - - const column =useTableColumns() - const {data ,status } = useGetCoupon() - const {t} = useTranslation(); - - - return ( - - - - - - - - ) -} - -export default CouponPage - diff --git a/src/Pages/Coupon2/EditCoupon/EditForm.tsx b/src/Pages/Coupon2/EditCoupon/EditForm.tsx deleted file mode 100644 index 690cbe2..0000000 --- a/src/Pages/Coupon2/EditCoupon/EditForm.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from 'react' -import { Col, Row } from "reactstrap"; -import KarimField from '../../../Components/Karimalden/KarimField'; - -const CreateForm = () => { - - - return ( - - - - - - - - - - - - ) -} - -export default CreateForm \ No newline at end of file diff --git a/src/Pages/Coupon2/EditCoupon/Page.tsx b/src/Pages/Coupon2/EditCoupon/Page.tsx deleted file mode 100644 index 9d2ac65..0000000 --- a/src/Pages/Coupon2/EditCoupon/Page.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import React from 'react'; -import FormPage from '../../../Layout/Dashboard/FormPage'; -import EditForm from './EditForm'; -import { getInitialValues, getValidationSchema } from '../formUtil'; -import { useParams } from 'react-router-dom'; -import KarimSpinner from '../../../Components/Karimalden/Ui/KarimSpinner'; -import { useAddCoupon, useGetOneCoupon } from '../../../api/Coupon'; - -const EditPage = () => { - - const { id } = useParams() - const { data,isLoading } = useGetOneCoupon({id}) - const {mutate} = useAddCoupon() - const handleSubmit = (values: any) => { - const newdata = {} as any; - - for (const key in data) { - if (values[key] !== data[key]) { - newdata[key] = values[key]; - } - } - - return mutate(newdata); - }; - - return ( - - handleSubmit(values)} - initialValues={getInitialValues(data?.coupons)} - validationSchema={getValidationSchema} - title='Edit Coupon' - > - - - - - ); -}; - -export default EditPage; diff --git a/src/Pages/Home/Chart.tsx b/src/Pages/Home/Chart.tsx new file mode 100644 index 0000000..d9b8545 --- /dev/null +++ b/src/Pages/Home/Chart.tsx @@ -0,0 +1,53 @@ +import * as React from 'react'; +//@ts-ignore +import { BarChart } from '@mui/x-charts/BarChart'; +import { axisClasses } from '@mui/x-charts'; +import { useTranslation } from 'react-i18next'; + +const chartSetting = { + yAxis: [ + { + label: 'rainfall (mm)', + }, + ], + sx: { + [`.${axisClasses.left} .${axisClasses.label}`]: { + transform: 'translate(-20px, 0)', + }, + }, +}; + + +const BarsDataset = () => { + const [t] = useTranslation() + const dataset = [ + {london: 59, paris: 57, newYork: 86, seoul: 21, month: t('January')}, + {london: 59, paris: 57, newYork: 86, seoul: 21, month: t('February')}, + {london: 59, paris: 57, newYork: 86, seoul: 21, month: t('March')}, + {london: 59, paris: 57, newYork: 86, seoul: 21, month: t('April')}, + + ]; + + const series = [ + { dataKey: 'london', label: t('London'), valueFormatter: (value: number) => `${value}mm` }, + { dataKey: 'paris', label: t('Paris'), valueFormatter: (value: number) => `${value}mm` }, + { dataKey: 'newYork', label: t('New York'), valueFormatter: (value: number) => `${value}mm` }, + { dataKey: 'seoul', label: t('Seoul'), valueFormatter: (value: number) => `${value}mm` }, + ]; + + const months = dataset.map(data => data.month); + + return ( +
+ + +
+ ); +}; + +export default BarsDataset; diff --git a/src/Pages/Home/HomePage.tsx b/src/Pages/Home/HomePage.tsx index 4c20a2b..c0d3ba3 100644 --- a/src/Pages/Home/HomePage.tsx +++ b/src/Pages/Home/HomePage.tsx @@ -1,87 +1,59 @@ import React from "react"; -// import StatisticsCard from "../../Components/Ui/StaticsCard/StaticCard"; +import StatisticsCard from "../../Components/Ui/StaticsCard/StaticCard"; import { FaRedRiver } from "react-icons/fa"; import { useTranslation } from "react-i18next"; -// import { ChartTypeEnum } from "../../enums/ChartTypeEnum"; -// import { Card, Col, Row } from "reactstrap"; -// import { AiOutlineUser } from 'react-icons/ai'; -// import { useGetStatistics } from "../../api/statistics"; -// import { BsCart3 } from "react-icons/bs"; -// import YearChart from "./YearChart"; -// import HighDriverRateTable from "./tables/HighDriverRate/HighDriverRateTable"; -// import LastOrderTable from "./tables/LastOrder/LastOrderTable"; -// import LoadingSpinner from "../../Components/Ui/LoadingSpinner"; -// import LoadingPage from "../../Layout/app/LoadingPage"; +import { Card, Col, Row } from "reactstrap"; +import { AiOutlineUser } from 'react-icons/ai'; +import { BsCart3 } from "react-icons/bs"; +import Chart from "./Chart"; export default function HomePage() { - - const { t } = useTranslation() - - // const { data: statistics, isLoading } = useGetStatistics({ - // order_daily_date: null - // }); - - // if(isLoading){ - // return - - // } + const { t } = useTranslation(); + const cardsData = [ + { + icon: , + count: 20, // Example count + pathWhenClick: "products", + titleKey: "products", + contentKey: "Product_in_your_Application" + }, + { + icon: , + count: 20, // Example count + pathWhenClick: "categories", + titleKey: "categories", + contentKey: "categories_in_your_Application" + }, + { + icon: , + count: 20, // Example count + pathWhenClick: "order", + titleKey: "order", + contentKey: "Order_in_your_Application" + } + ]; return ( <> - -Home Page - {/* - -
- } - count={`${(statistics?.drivers_count) ?? 1}`} - CardContent={t(`You_have`) + " " + ((statistics?.drivers_count) ?? 1) + " " + t(`Driver_in_your_Application`)} - CardTitle={t("drivers")} - /> -
- - -
- - } - count={`${(statistics?.users_count) ?? 1}`} - CardContent={t(`You_have`) + " " + ((statistics?.users_count) ?? 1) + " " + t(`User_in_your_Application`)} - - pathWhenClick="customers" - CardTitle={t("users")} - /> -
- - - -
- - } - count={`${(statistics?.orders_count) ?? 1}`} - CardContent={t(`You_have`) + " " + ((statistics?.orders_count) ?? 1) + " " + t(`Order_in_your_Application`)} - pathWhenClick="order" - CardTitle={t('order')} - - /> -
- + + {cardsData.map((card, index) => ( + +
+ +
+ + ))}
- - - - - - - - - */} - {/* - - */} - + + + + + ); } diff --git a/src/Pages/Home/tables/LastOrder/useTableColumn.tsx b/src/Pages/Home/tables/LastOrder/useTableColumn.tsx index a65833d..044beea 100644 --- a/src/Pages/Home/tables/LastOrder/useTableColumn.tsx +++ b/src/Pages/Home/tables/LastOrder/useTableColumn.tsx @@ -12,12 +12,13 @@ const useTableColumns = () => { () => [ { - name: t("driver_name"), + name: t("order_code"), sortable: false, center: true, cell:(row:any)=>{ - - return (row?.driver?.full_name) + console.log(row); + + return (row?.order_code) } }, @@ -26,15 +27,14 @@ const useTableColumns = () => { name: t("order_total"), sortable: true, center: true, - selector:"average_cost" + cell:(row)=>row["order_total"] }, { name: t("order_status"), sortable: false, center: true, cell:(row:any)=>{t(row.status)} + padding:8, color:'black',borderRadius:10,fontSize:10}}>{t(row.order_status)} }, { diff --git a/src/Pages/Home/tables/HighDriverRate/HighDriverRateTable.tsx b/src/Pages/Home/tables/LastUser/LastUserTable.tsx similarity index 78% rename from src/Pages/Home/tables/HighDriverRate/HighDriverRateTable.tsx rename to src/Pages/Home/tables/LastUser/LastUserTable.tsx index 2f2634a..ce889a2 100644 --- a/src/Pages/Home/tables/HighDriverRate/HighDriverRateTable.tsx +++ b/src/Pages/Home/tables/LastUser/LastUserTable.tsx @@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next'; import { LoadingButton } from '../../../../Components/Ui/LoadingButton'; import { useNavigate } from 'react-router-dom'; - export default function HighDriverRateTable({ most_driver_rate }:any) { + export default function LastUserTable({ most_driver_rate }:any) { const columns = useTableColumns(); const {t} = useTranslation(); const navigate = useNavigate() @@ -16,11 +16,11 @@ import { useNavigate } from 'react-router-dom'; return (
- {t("high_drivers_rate")} + {t("last_users")} - navigate("/Drivers" , {replace:true})}> - {t("show_all_driver")} - + {/* navigate("/user" , {replace:true})}> + {t("show_all_users")} + */}
diff --git a/src/Pages/Home/tables/HighDriverRate/useTableColumn.tsx b/src/Pages/Home/tables/LastUser/useTableColumn.tsx similarity index 51% rename from src/Pages/Home/tables/HighDriverRate/useTableColumn.tsx rename to src/Pages/Home/tables/LastUser/useTableColumn.tsx index 35e1775..8613a6b 100644 --- a/src/Pages/Home/tables/HighDriverRate/useTableColumn.tsx +++ b/src/Pages/Home/tables/LastUser/useTableColumn.tsx @@ -7,9 +7,10 @@ import { Rating } from "react-simple-star-rating"; interface RowData { - driver_name: string; - rate: number; - driver_id: string; + name:string , + phone:string , + email:string , + id:number } const useTableColumns = () => { @@ -22,29 +23,33 @@ const useTableColumns = () => { name: t("full_name"), sortable: false, center: true, - cell: (row: RowData) => row?.driver_name, + cell: (row: RowData) => row?.name, }, { - name: t("rate"), + name: t("email"), sortable: false, center: true, - cell: (row: RowData) => ( - - ), + cell: (row: RowData) => row?.email, }, { - name: "#", - selector: "action", + name: t("phone"), sortable: false, center: true, - cell: (row: RowData) => ( - navigate(`/information/driver/${row?.driver_id}`, {replace:true})} - size={22} - style={{ cursor: "pointer" }} - /> - ), + cell: (row: RowData) => row?.phone, }, + // { + // name: "#", + // selector: "action", + // sortable: false, + // center: true, + // cell: (row: RowData) => ( + // navigate(`/user/${row?.id}`, {replace:true})} + // size={22} + // style={{ cursor: "pointer" }} + // /> + // ), + // }, ]; return columns; diff --git a/src/Pages/Products/ProductsPage.tsx b/src/Pages/Products/ProductsPage.tsx index b615214..0d111f6 100644 --- a/src/Pages/Products/ProductsPage.tsx +++ b/src/Pages/Products/ProductsPage.tsx @@ -14,21 +14,22 @@ function ProductsPage() { const column =useTableColumns() const {data ,status } = useGetProduct() - console.log(data); const [t] = useTranslation() const navigate = useNavigate() - + const totalRows = data?.meta?.total; + return ( - // Pass Status to Layout - - navigate('/products/add')}> - + + navigate('/products/add')}> + diff --git a/src/Pages/Products/View/AddPage.tsx b/src/Pages/Products/View/AddPage.tsx index e409562..599dd79 100644 --- a/src/Pages/Products/View/AddPage.tsx +++ b/src/Pages/Products/View/AddPage.tsx @@ -1,62 +1,102 @@ -import React, { useEffect, useState } from 'react' -import { getInitialValues, getValidationSchema, getDataToSend } from '../formUtil' +import React, { useEffect, useState } from 'react' +import {getInitialValuesAdd as getInitialValues, getValidationSchema, getDataToSend } from '../formUtil' import { Tab, TabList, TabPanel as TabBody, Tabs } from 'react-tabs' import 'react-tabs/style/react-tabs.css'; import { MdLanguage } from 'react-icons/md' -import { FaCheck, FaSadCry } from 'react-icons/fa' import ViewPage from '../../../Layout/Dashboard/ViewPage'; -import { Rate } from 'antd'; import BasicInfo from './BasicInfo'; -import { usePageState } from '../../../lib/state mangment/LayoutPagestate'; -import { useParams } from 'react-router-dom'; -import LoadingPage from '../../../Layout/app/LoadingPage'; import { useTranslation } from 'react-i18next'; import { BsInfoCircle } from 'react-icons/bs'; -import BasicInfo2 from './BasicInfo2'; import useNavigateOnSuccess from '../../../Hooks/useNavigateOnSuccess'; -import { useAddProduct } from '../../../api/product'; +import { useAddProduct, useAddProductVariation } from '../../../api/product'; import VarianInfo from './VarianInfo'; +import { usePageState } from '../../../lib/state mangment/LayoutPagestate'; const AddProductPage = () => { - const { mutate, isLoading, isSuccess } = useAddProduct() - const [BarStatus, setBarStatus] = useState({ value: 0, isLoading: false, isError: false, isSuccess: false }) - const [IsValed, setIsValed] = useState(1) + const { mutate, isLoading , data, isSuccess } = useAddProduct() + const { mutate:AddVariation, isSuccess:SuccessVariation } = useAddProductVariation() + + const [IsValed, setIsValed] = useState(false) + const [infotaps , setInfoTaps] = useState([]) + + const [Varibletaps , setVaribleTaps] = useState([]) + const handleSubmit = (values: any) => { - - values['name'] = { - "en" : values.name_en, - "ar" : values.name_ar, - "de" : values.name_de, - } - values['description'] = { - "en" : values.description_en, - "ar" : values.description_ar, - "de" : values.description_de, - } - - - const infoArray = Object.entries(values.info).map(([key, value]: [string, any]) => ({ - [key.split('.')[1]]: value - })); - values["info"]= infoArray - - console.log(infoArray); - - // mutate(values); - // console.log(values); + setInfoTaps(values?.info?.slice(1)?.map((taps:any) => { + return (changeShapeInfo(taps)); + + })); + + setVaribleTaps(values?.variable?.slice(1)) + mutate({ + name:{ + en:values?.name_en, + ar:values?.name_ar, + de:values?.name_de + }, + category_id:1 + }) } + useEffect(()=>{ + + if(isSuccess){ + const baseProductId = (data as any )?.id ; + console.log(infotaps); + console.log(Varibletaps); + + Varibletaps?.map((dataToSend:any , index:number)=>{ + + const varible = dataToSend + const info = infotaps[index] + const jsonString = JSON.stringify(info); + + const Newproduct = { + name:{ + en:varible?.name_en, + ar:varible?.name_ar, + de:varible?.name_de + }, + description:{ + en:varible?.description_en, + ar:varible?.description_ar, + de:varible?.description_de + }, + quantity:varible?.quantity, + main_photo:varible?.main_photo, + images:varible?.images, + info : jsonString, + product_attributes:[ + {attribute_value_id: 1, attribute_id: 1} + ], + base_product_id:baseProductId + } + console.log(Newproduct); + + AddVariation(Newproduct) + }) + + } + },[isSuccess]) + + + const { setObjectToEdit, objectToEdit } = usePageState() + + useEffect(() => { + setObjectToEdit([]); + }, []); + const { t } = useTranslation(); - useNavigateOnSuccess(isSuccess, '/products') + useNavigateOnSuccess(SuccessVariation, '/products') - const ViewProps = { getInitialValues, getValidationSchema, getDataToSend, handleSubmit, BarStatus }; + const ViewProps = { getInitialValues, getValidationSchema, getDataToSend, handleSubmit }; return ( @@ -65,14 +105,14 @@ const AddProductPage = () => { -
{t("Base_info")} {IsValed ? : "" }
+
{t("Base_info")}
-
{t("VarianInfo")}
+
{t("VarianInfo")}
-
+
@@ -88,4 +128,20 @@ const AddProductPage = () => { } -export default AddProductPage \ No newline at end of file +export default AddProductPage + + +function changeShapeInfo(originalObject:any){ + const transformedObject:any = {}; + +for (const key in originalObject) { + if (originalObject.hasOwnProperty(key)) { + const index = key.split('.')[0]; // Extract index from key + const attribute = key.split('.')[1]; // Extract attribute from key + + transformedObject[originalObject[`${index}.key`]] = originalObject[`${index}.Description`]; + } +} + +return transformedObject +} \ No newline at end of file diff --git a/src/Pages/Products/View/Atteibute.tsx b/src/Pages/Products/View/Atteibute.tsx new file mode 100644 index 0000000..853615e --- /dev/null +++ b/src/Pages/Products/View/Atteibute.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { useFormikContext } from 'formik'; +import ValidationField from '../../../Components/ValidationField/ValidationField'; +import { useGetSingleAttribute } from '../../../api/attribute'; + +const Attribute = () => { + const { values, setFieldValue } = useFormikContext(); + + const { data: attributeData } = useGetSingleAttribute({ name: "product_id", id: values?.id }); + + const handleAttributeChange = (name: string, value: any) => { + setFieldValue(`attribute[${name}]`, value); + }; + + return ( + attributeData?.data?.map((item: any) => { + const options = item?.attribute_value?.map((attr: any) => ({ + label: attr?.value, + value: attr?.attribute_id + })); + + return ( + handleAttributeChange(item?.name, value)} + /> + ); + }) + ); +}; + +export default Attribute; diff --git a/src/Pages/Products/View/BasicInfo.tsx b/src/Pages/Products/View/BasicInfo.tsx index 346f7f3..48d7d66 100644 --- a/src/Pages/Products/View/BasicInfo.tsx +++ b/src/Pages/Products/View/BasicInfo.tsx @@ -1,35 +1,41 @@ import React, { useEffect, useState } from 'react' import { Col, Row } from 'reactstrap' -import KarimField from '../../../Components/Karimalden/KarimField' +import ValidationField from '../../../Components/ValidationField/ValidationField' import { useTranslation } from 'react-i18next'; import { useFormikContext } from 'formik'; +import { toast } from 'react-toastify'; +import { useGetCategories } from '../../../api/Categories'; +import useFormatToSelect from '../../../Hooks/useFormatToSelect'; -const BasicInfo = ({setIsValed}:any) => { +const BasicInfo = ({ setIsValed, IsValed }: any) => { const [t] = useTranslation(); const formikContext = useFormikContext(); - const { values, submitForm,isValid } = formikContext; + const { values, isValid } = formikContext; + const { data } = useGetCategories() + const SelectData = useFormatToSelect(data?.categories) useEffect(() => { - //@ts-ignore - if (values.name_ar !== "" && values.name_en !== "" && values.name_de !== "" && values.main_photo !== "" && values.category_id !== "" ) { - setIsValed(1); - console.log(isValid, 'isValid'); - } else { - console.log(values); - } - }, [isValid,values]); - + const { name_ar, name_en, name_de, main_photo, category_id } = values as any; + if (name_ar && name_en && name_de && main_photo && category_id && IsValed === false) { + toast.success(t("view_information_filed_fill_sucsessfully")); + setIsValed(true) + } else { + // console.log(isValid, "isValid"); + } + }, [values]); + + return ( - - - + + - - + + {/* */} + diff --git a/src/Pages/Products/View/BasicInfo2.tsx b/src/Pages/Products/View/BasicInfo2.tsx deleted file mode 100644 index 30b91f9..0000000 --- a/src/Pages/Products/View/BasicInfo2.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React from 'react' -import { Col, Row } from 'reactstrap' -import KarimField from '../../../Components/Karimalden/KarimField' -import { useTranslation } from 'react-i18next'; -import ObjectField from './ObjectField'; - -const BasicInfo2 = () => { - const [t] = useTranslation(); - - const categoryOption = [] as any - - - - return ( - - - {/* */} - - - - {/* */} - {/* */} - {/* */} - - - - - - ) -} - -export default BasicInfo2 \ No newline at end of file diff --git a/src/Pages/Products/View/Edit/BasicInfo.tsx b/src/Pages/Products/View/Edit/BasicInfo.tsx new file mode 100644 index 0000000..8844ddc --- /dev/null +++ b/src/Pages/Products/View/Edit/BasicInfo.tsx @@ -0,0 +1,45 @@ +import React, { useEffect, useState } from 'react' +import { Col, Row } from 'reactstrap' +import ValidationField from '../../../../Components/ValidationField/ValidationField' +import { useTranslation } from 'react-i18next'; +import { useFormikContext } from 'formik'; +import { toast } from 'react-toastify'; +import { useGetCategories } from '../../../../api/Categories'; +import useFormatToSelect from '../../../../Hooks/useFormatToSelect'; + +const BasicInfo = ({ setIsValed, IsValed }: any) => { + const [t] = useTranslation(); + const formikContext = useFormikContext(); + const { values, isValid } = formikContext; + const { data } = useGetCategories() + const SelectData = useFormatToSelect(data?.categories) + + useEffect(() => { + const { name_ar, name_en, name_de, main_photo, category_id } = values as any; + + if (name_ar && name_en && name_de && main_photo && category_id && IsValed === false) { + toast.success(t("view_information_filed_fill_sucsessfully")); + setIsValed(true) + } else { + // console.log(isValid, "isValid"); + } + }, [values]); + + + return ( + + + + + + + + + + + + + ) +} + +export default BasicInfo \ No newline at end of file diff --git a/src/Pages/Products/View/Edit/FormikTab/Field/Atteibute.tsx b/src/Pages/Products/View/Edit/FormikTab/Field/Atteibute.tsx new file mode 100644 index 0000000..4c3812d --- /dev/null +++ b/src/Pages/Products/View/Edit/FormikTab/Field/Atteibute.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { useFormikContext } from 'formik'; +import ValidationField from '../../../../../../Components/ValidationField/ValidationField'; +import { useGetSingleAttribute } from '../../../../../../api/attribute'; + +const Attribute = ({data,tabKey}:any) => { + const { values, setFieldValue } = useFormikContext(); + + + const handleAttributeChange = (name: string, value: any) => { + setFieldValue(`variable.${tabKey}.attribute"[${name}]`, value); + }; + + return ( + data?.map((item: any) => { + const options = item?.attribute_value?.map((attr: any) => ({ + label: attr?.value, + value: attr?.attribute_id + })); + + return ( + handleAttributeChange(item?.name, value)} + /> + ); + }) + ); +}; + +export default Attribute; diff --git a/src/Pages/Products/View/Edit/FormikTab/Field/File.tsx b/src/Pages/Products/View/Edit/FormikTab/Field/File.tsx new file mode 100644 index 0000000..6b4f943 --- /dev/null +++ b/src/Pages/Products/View/Edit/FormikTab/Field/File.tsx @@ -0,0 +1,64 @@ + + + +import { Button, Upload, UploadFile } from 'antd' +import { UploadOutlined } from '@ant-design/icons'; +import { useTranslation } from 'react-i18next'; +import { useFormikContext } from 'formik'; +import { ImageBaseURL } from '../../../../../../api/config'; + + +const File = ({ tabKey}:any) => { + const { t } = useTranslation(); + const formik = useFormikContext(); + const name = `variable[${tabKey}].${"main_photo"}`; + const imageUrl = formik?.values?.variable[tabKey]?.main_photo ? ImageBaseURL + formik?.values?.variable[tabKey]?.main_photo : "" ; + console.log(imageUrl); + + const fileList: UploadFile[] = [ + + { + uid: '-1', + name: formik?.values?.variable[tabKey]?.main_photo?.name ?? "", + status: 'done', + url: imageUrl , + thumbUrl: imageUrl , + } + ]; + const FilehandleChange = (value:any) => { + + formik.setFieldValue(name, value.file.originFileObj) + + }; + const customRequest = async ({ onSuccess}: any) => { + onSuccess(); + }; + return ( +
+ + + + + + + + +
+ ) +} + +export default File \ No newline at end of file diff --git a/src/Pages/Products/View/Edit/FormikTab/Field/FileImage.tsx b/src/Pages/Products/View/Edit/FormikTab/Field/FileImage.tsx new file mode 100644 index 0000000..d214314 --- /dev/null +++ b/src/Pages/Products/View/Edit/FormikTab/Field/FileImage.tsx @@ -0,0 +1,50 @@ +import { Button, Upload, UploadFile } from 'antd'; +import { UploadOutlined } from '@ant-design/icons'; +import { useTranslation } from 'react-i18next'; +import { useFormikContext } from 'formik'; +import { BaseURL_IMAGE } from '../../../../../../api/config'; + +const MaltyFile = ({ tabKey }: any) => { + const { t } = useTranslation(); + const formik = useFormikContext(); + const name = `variable[${tabKey}].Images`; + + const imageFiles = formik.values?.variable?.[tabKey]?.Images || []; + const defaultFileList = imageFiles?.map((file: any, index: number) => ({ + uid: `-${index}`, + name: file?.name, // Use a default name if file.name is undefined + status: 'done', + url: file ? URL.createObjectURL(file) : BaseURL_IMAGE + file?.path?.replace("public", "/storage"), + thumbUrl: file ?URL.createObjectURL(file):"", + })); + + const FilehandleChange = ({ fileList }: { fileList: any }) => { + formik.setFieldValue(name, fileList.map((file: any) => file?.originFileObj)); + }; + + const customRequest = async ({ onSuccess }: any) => { + onSuccess(); + }; + + return ( +
+ + + + +
+ ); +} + +export default MaltyFile; diff --git a/src/Components/Karimalden/View/Object.tsx b/src/Pages/Products/View/Edit/FormikTab/Field/Object.tsx similarity index 72% rename from src/Components/Karimalden/View/Object.tsx rename to src/Pages/Products/View/Edit/FormikTab/Field/Object.tsx index 82f2f77..b82983e 100644 --- a/src/Components/Karimalden/View/Object.tsx +++ b/src/Pages/Products/View/Edit/FormikTab/Field/Object.tsx @@ -2,27 +2,51 @@ import React, { useEffect, useState } from 'react'; import { CloseOutlined } from '@ant-design/icons'; import { Button, Card, Form, Input, Space, Typography } from 'antd'; import { useFormikContext } from 'formik'; +import { objectToArray } from '../../../../../../utils/Array/ArrayToObjectFormik'; +import { useTranslation } from 'react-i18next'; -const ObjectField = ({value , onChange}:any) => { +const ObjectField = ({tabKey}:any) => { const [form] = Form.useForm(); const formik = useFormikContext(); - const [FieldItems, setFieldItems] = useState([]) + const [FieldItems, setFieldItems] = useState(formik?.values?.info[tabKey]) + const [t] = useTranslation() const handleChange = (e: React.ChangeEvent) => { const { name, value } = e.target; - setFieldItems((prevState:any) => ({ - ...prevState, - [name]: value - })); - formik.setFieldValue("info", FieldItems) + setFieldItems((prevState:any) =>{ + + formik.setFieldValue(`info.${tabKey}`, { + ...prevState, + [name]: value + }); + + return ({ + ...prevState, + [name]: value + }) + } ) + }; + useEffect(() => { - form.setFieldsValue({ - items: [{ list: [{ Attribute: '', Description: '' }] }] - }); - - }, []); + + if (formik?.values?.info[tabKey]) { + const defaultValues = formik.values.info[tabKey]; + + console.log(objectToArray( formik?.values?.info[tabKey])); + + form.setFieldsValue({ + items: [{ list:objectToArray( formik?.values?.info[tabKey])}] + + }); + } + else { + form.setFieldsValue({ + items: [{ list: [{ key: '', Description: '' }] },], }); + } + }, []); // Update when tabKey or info[tabKey] changes + return ( { {fields.map((field, index) => (
- Information + {t("Information")} {/* Nested Form.List for sub-items */} @@ -49,17 +73,17 @@ const ObjectField = ({value , onChange}:any) => {
{subFields.map((subField) => ( - + { ))}
)} @@ -89,4 +113,4 @@ const ObjectField = ({value , onChange}:any) => { ); }; -export default ObjectField; +export default ObjectField \ No newline at end of file diff --git a/src/Pages/Products/View/taps/SearchTabs.tsx b/src/Pages/Products/View/Edit/FormikTab/Field/SearchTabs.tsx similarity index 100% rename from src/Pages/Products/View/taps/SearchTabs.tsx rename to src/Pages/Products/View/Edit/FormikTab/Field/SearchTabs.tsx diff --git a/src/Pages/Products/View/Edit/FormikTab/Field/Select.tsx b/src/Pages/Products/View/Edit/FormikTab/Field/Select.tsx new file mode 100644 index 0000000..b782ea1 --- /dev/null +++ b/src/Pages/Products/View/Edit/FormikTab/Field/Select.tsx @@ -0,0 +1,41 @@ +import { Form, Select } from 'antd' +import { useFormikContext } from 'formik'; +import React from 'react' +import { useTranslation } from 'react-i18next'; + +const SelectField = ({tabKey,option,name,id,label}: any) => { + const { t } = useTranslation(); + const formik = useFormikContext(); + const Formikname = `variable[${tabKey}].${name}`; + const FormikValue = formik?.values?.variable[tabKey]?.[name]; + const onChange = (value:any) => { + formik.setFieldValue(Formikname,[ { + attribute_value_id:value, + attribute_id:id + }]) + console.log(value); + + }; + return ( +
+ + + + + ); +}; diff --git a/src/Pages/Products/View/Edit/FormikTab/TabItem.tsx b/src/Pages/Products/View/Edit/FormikTab/TabItem.tsx new file mode 100644 index 0000000..4b02d7e --- /dev/null +++ b/src/Pages/Products/View/Edit/FormikTab/TabItem.tsx @@ -0,0 +1,13 @@ +// TabItem.tsx +import React from 'react'; +import { VariableTabs } from './VariableTabs'; + +interface TabItemProps { + UKey: any; +} + +export const TabItem: React.FC = ({ UKey }) => { + return ( + + ); +}; diff --git a/src/Pages/Products/View/Edit/FormikTab/TabsContainer.tsx b/src/Pages/Products/View/Edit/FormikTab/TabsContainer.tsx new file mode 100644 index 0000000..1073551 --- /dev/null +++ b/src/Pages/Products/View/Edit/FormikTab/TabsContainer.tsx @@ -0,0 +1,115 @@ +// TabsContainer.tsx +import React, { useEffect, useState } from 'react'; +import { Tabs, Space } from 'antd'; +import { CopyOutlined } from '@ant-design/icons'; +import { TabItem } from './TabItem'; +import { toast } from 'react-toastify'; +import { FormikContext, FormikValues, useFormikContext } from 'formik'; +import { useTranslation } from 'react-i18next'; + +const { TabPane } = Tabs; + +const initialItemShape: any = { + label: 'variable 1', + key: '1', + closable: true, + }; +export const TabsContainer: React.FC = () => { + const [activeKey, setActiveKey] = useState('1'); +// const [items, setItems] = useState([]); +const [t] = useTranslation() + + const { setFieldValue } = useFormikContext(); + const formikContext = useFormikContext(); + const { values, handleChange } = formikContext; + const [width, setWidth] = useState(window.innerWidth); + const varianCount = values?.variable?.slice(1).map((item:any,index:any)=>{ + return { + label: `${t(`variable`)}`+ `${index+1}`, + key: index+1, + closable: true, + } + }) + + + const [items, setItems] = useState(varianCount); + + const handleAdd = () => { + const newKey = `${items.length + 1}`; + setItems([...items, { key: newKey, label: `variable ${newKey}`, closable: true }]); + setActiveKey(newKey); + }; + + const handleDuplicate = (targetKey: string) => { + const targetItem = items.find((item:any) => item.key === targetKey); + if (targetItem) { + const newKey = `${items.length + 1}`; + const newItem = { ...targetItem, key: newKey, label: `variable ${newKey}` }; + setItems([...items, newItem]); + setActiveKey(newKey); + + const originalValues = values?.variable?.[targetKey]; + setFieldValue(`variable.${newKey}`, originalValues); + + const originalInfo = values?.info?.[targetKey]; + console.log(originalInfo); + + setFieldValue(`info.${newKey}`, originalInfo); + } + }; + + + const handleRemove = (targetKey: string) => { + const newItems = items.filter((item:any) => item.key !== targetKey); + if (newItems.length > 0) { + const newActiveKey = newItems.length ? newItems[newItems.length - 1].key : '1'; + setItems(newItems); + setActiveKey(newActiveKey); + } else { + toast.error("Cannot close the last tab"); + + } +}; + +useEffect(() => { + const handleResize = () => { + setWidth(window.innerWidth); + }; + + window.addEventListener('resize', handleResize); + + return () => { + window.removeEventListener('resize', handleResize); + }; +}, []); +const tabPosition = width > 1000 ? 'left' : 'top'; + + return ( + (action === 'add' ? handleAdd() : handleRemove(targetKey))} + tabPosition={tabPosition} + + > + {items.map((item :any) =>{ + return ( + + + {t(`${item.label}`)} + handleDuplicate(item.key)} /> + + } + closable={item.closable} + > + + + ) + })} + + ); +}; diff --git a/src/Pages/Products/View/Edit/FormikTab/VariableTabs.tsx b/src/Pages/Products/View/Edit/FormikTab/VariableTabs.tsx new file mode 100644 index 0000000..4af887a --- /dev/null +++ b/src/Pages/Products/View/Edit/FormikTab/VariableTabs.tsx @@ -0,0 +1,71 @@ +// VariableTabs.tsx +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { Col, Row } from 'reactstrap'; +import { FormItem } from './FormItem'; +import { useFormikContext, FormikValues } from 'formik'; +import File from './Field/File'; +import MaltyFile from './Field/FileImage'; +import Select from './Field/Select'; +import ObjectField from './Field/Object'; +import Atteibute from './Field/Atteibute'; + +interface VariableTabsProps { + tabKey: string; +} + +export const VariableTabs: React.FC = ({ tabKey }) => { + const { t } = useTranslation(); + const formikContext = useFormikContext(); + const { values, handleChange } = formikContext; + + const handleFieldChange = (fieldName: string) => ( + e: React.ChangeEvent | any + ) => { + handleChange(`variable.${tabKey}.${fieldName}`)(e); // Prepend "variable" + }; + const FormikName = (FormikFieldname: any) => values?.variable?.[tabKey]?.[FormikFieldname]; + + + + + return ( + <> +
variables {tabKey}
+ + + + + + + + + {values?.other_attributes && + + } + + + + + + + + + + + + ); +}; diff --git a/src/Pages/Products/View/Edit/VarianInfo.tsx b/src/Pages/Products/View/Edit/VarianInfo.tsx new file mode 100644 index 0000000..25449c7 --- /dev/null +++ b/src/Pages/Products/View/Edit/VarianInfo.tsx @@ -0,0 +1,13 @@ +import React, { useState } from 'react' +import { TabsContainer } from './FormikTab/TabsContainer' + +const VarianInfo = () => { + + return ( +
+ +
+ ) +} + +export default VarianInfo \ No newline at end of file diff --git a/src/Pages/Products/View/EditPage.tsx b/src/Pages/Products/View/EditPage.tsx new file mode 100644 index 0000000..6c1339f --- /dev/null +++ b/src/Pages/Products/View/EditPage.tsx @@ -0,0 +1,137 @@ +import React, { useEffect, useState } from 'react' +import { getInitialValues, getDataToSend } from '../formUtil' +import { Tab, TabList, TabPanel as TabBody, Tabs } from 'react-tabs' +import 'react-tabs/style/react-tabs.css'; +import { MdLanguage } from 'react-icons/md' +import ViewPage from '../../../Layout/Dashboard/ViewPage'; +import BasicInfo from './Edit/BasicInfo'; +import { usePageState } from '../../../lib/state mangment/LayoutPagestate'; +import { useParams } from 'react-router-dom'; +import LoadingPage from '../../../Layout/app/LoadingPage'; +import { useTranslation } from 'react-i18next'; +import { BsInfoCircle } from 'react-icons/bs'; +import { useGetOneProduct, useUpdateProduct, useUpdateProductVariation } from '../../../api/product'; +import useNavigateOnSuccess from '../../../Hooks/useNavigateOnSuccess'; +import VarianInfo from './Edit/VarianInfo'; +import { changeShapeInfo } from '../../../utils/Array/changeShapeInfo'; +import { Spin } from 'antd'; + +const ViewProduct = () => { + const { setObjectToEdit, objectToEdit } = usePageState() + const { t } = useTranslation(); + const { id } = useParams() + const { data , isLoading,isRefetching} = useGetOneProduct({ id: id }) + const [Data, setData] = useState([]) + const { mutate, isSuccess } = useUpdateProduct() + const { mutate: AddVariation, isSuccess: SuccessVariation } = useUpdateProductVariation() + const [infotaps, setInfoTaps] = useState([]) + + const [Varibletaps, setVaribleTaps] = useState([]) + const handleSubmit = (values: any) => { + + + + setInfoTaps(values?.info?.slice(1)?.map((taps: any) => { + return (changeShapeInfo(taps)); + + })); + + + setVaribleTaps(values?.variable?.slice(1)) + mutate({ + name: values?.name, + category_id: 1 + }) + + + } + + useEffect(() => { + if (isSuccess) { + const baseProductId = (data as any)?.id; + console.log(infotaps); + console.log(Varibletaps); + + Varibletaps?.map((dataToSend: any, index: number) => { + + const varible = dataToSend + const info = infotaps[index] + const jsonString = JSON.stringify(info); + + const Newproduct : any = { + name: varible?.name, + description: varible?.description, + quantity: varible?.quantity, + info: jsonString, + product_attributes: [ + { attribute_value_id: 1, attribute_id: 1 } + ], + base_product_id: baseProductId + } + if (data?.product?.images !== varible?.images) { + Newproduct.images = varible?.images ; + } + if (data?.product?.main_photo?.replace("public", "/storage") !== varible?.main_photo) { + Newproduct.main_photo = varible?.main_photo ; + console.log(data?.product?.main_photo?.replace("public", "/storage")); + + } + + AddVariation(Newproduct) + }) + + } + }, [isSuccess]) + + + + useNavigateOnSuccess(isSuccess, '/products') + + + useEffect(() => { + // refetch() + setObjectToEdit(data?.data); + }, [data,id,isRefetching]); + + const getValidationSchema = () => { + return null + }; + if(isRefetching){ + return + } + + const ViewProps = { getInitialValues, getValidationSchema, getDataToSend, handleSubmit }; + + + return ( +
+ {objectToEdit && data ? + + + +
{t("Base_info")}
+ +
{t("VarianInfo")}
+ + +
+ +
+
+ +
{isLoading ? : }
+
+ +
+
+ : } + + +
+ ) + +} + +export default ViewProduct + + diff --git a/src/Pages/Products/View/FormikTab/Field/Atteibute.tsx b/src/Pages/Products/View/FormikTab/Field/Atteibute.tsx new file mode 100644 index 0000000..4eb8481 --- /dev/null +++ b/src/Pages/Products/View/FormikTab/Field/Atteibute.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { useFormikContext } from 'formik'; +import ValidationField from '../../../../../Components/ValidationField/ValidationField'; +import { useGetSingleAttribute } from '../../../../../api/attribute'; + +const Attribute = ({tabKey}:any) => { + const { values, setFieldValue } = useFormikContext(); + + const { data: attributeData } = useGetSingleAttribute({ name: "category_id", id: values?.category_id }); + + const handleAttributeChange = (name: string, value: any) => { + setFieldValue(`variable.${tabKey}.attribute"[${name}]`, value); + }; + + return ( + attributeData?.data?.map((item: any) => { + const options = item?.attribute_value?.map((attr: any) => ({ + label: attr?.value, + value: attr?.attribute_id + })); + + return ( + handleAttributeChange(item?.name, value)} + /> + ); + }) + ); +}; + +export default Attribute; diff --git a/src/Pages/Products/View/FormikTab/Field/File.tsx b/src/Pages/Products/View/FormikTab/Field/File.tsx new file mode 100644 index 0000000..f797cc4 --- /dev/null +++ b/src/Pages/Products/View/FormikTab/Field/File.tsx @@ -0,0 +1,63 @@ + + + +import { Button, Upload, UploadFile } from 'antd' +import { UploadOutlined } from '@ant-design/icons'; +import { useTranslation } from 'react-i18next'; +import { useFormikContext } from 'formik'; +import { ImageBaseURL } from '../../../../../api/config'; + + +const File = ({ tabKey}:any) => { + const { t } = useTranslation(); + const formik = useFormikContext(); + const name = `variable[${tabKey}].${"main_photo"}`; + const imageUrl = formik?.values?.variable[tabKey]?.main_photo ? URL.createObjectURL(formik?.values?.variable[tabKey]?.main_photo) : "" ; + + const fileList: UploadFile[] = [ + + { + uid: '-1', + name: formik?.values?.variable[tabKey]?.main_photo?.name ?? "", + status: 'done', + url: imageUrl , + thumbUrl: imageUrl , + } + ]; + const FilehandleChange = (value:any) => { + + formik.setFieldValue(name, value.file.originFileObj) + + }; + const customRequest = async ({ onSuccess}: any) => { + onSuccess(); + }; + return ( +
+ + + + + + + + +
+ ) +} + +export default File \ No newline at end of file diff --git a/src/Pages/Products/View/FormikTab/Field/FileImage.tsx b/src/Pages/Products/View/FormikTab/Field/FileImage.tsx new file mode 100644 index 0000000..24c4c5a --- /dev/null +++ b/src/Pages/Products/View/FormikTab/Field/FileImage.tsx @@ -0,0 +1,49 @@ +import { Button, Upload, UploadFile } from 'antd'; +import { UploadOutlined } from '@ant-design/icons'; +import { useTranslation } from 'react-i18next'; +import { useFormikContext } from 'formik'; + +const MaltyFile = ({ tabKey }: any) => { + const { t } = useTranslation(); + const formik = useFormikContext(); + const name = `variable[${tabKey}].images`; + + const imageFiles = formik.values?.variable?.[tabKey]?.images || []; + const defaultFileList = imageFiles?.map((file: any, index: number) => ({ + uid: `-${index}`, + name: file?.name, // Use a default name if file.name is undefined + status: 'done', + url: file ? URL?.createObjectURL(file) : "", + thumbUrl: file ?URL?.createObjectURL(file):"", + })); + + const FilehandleChange = ({ fileList }: { fileList: any }) => { + formik.setFieldValue(name, fileList.map((file: any) => file?.originFileObj)); + }; + + const customRequest = async ({ onSuccess }: any) => { + onSuccess(); + }; + + return ( +
+ + + + +
+ ); +} + +export default MaltyFile; diff --git a/src/Pages/Products/View/FormikTab/Field/Object.tsx b/src/Pages/Products/View/FormikTab/Field/Object.tsx new file mode 100644 index 0000000..8c721da --- /dev/null +++ b/src/Pages/Products/View/FormikTab/Field/Object.tsx @@ -0,0 +1,116 @@ +import React, { useEffect, useState } from 'react'; +import { CloseOutlined } from '@ant-design/icons'; +import { Button, Card, Form, Input, Space, Typography } from 'antd'; +import { useFormikContext } from 'formik'; +import { objectToArray } from '../../../../../utils/Array/ArrayToObjectFormik'; +import { useTranslation } from 'react-i18next'; + +const ObjectField = ({tabKey}:any) => { + const [form] = Form.useForm(); + const formik = useFormikContext(); + const [FieldItems, setFieldItems] = useState(formik?.values?.info[tabKey]) + const [t] = useTranslation() + const handleChange = (e: React.ChangeEvent) => { + const { name, value } = e.target; + + setFieldItems((prevState:any) =>{ + + formik.setFieldValue(`info.${tabKey}`, { + ...prevState, + [name]: value + }); + + return ({ + ...prevState, + [name]: value + }) + } ) + + }; + + + useEffect(() => { + + if (formik?.values?.info[tabKey]) { + const defaultValues = formik.values.info[tabKey]; + + console.log(objectToArray( formik?.values?.info[tabKey])); + + form.setFieldsValue({ + items: [{ list:objectToArray( formik?.values?.info[tabKey])}] + + }); + } + else { + form.setFieldsValue({ + items: [{ list: [{ key: '', Description: '' }] },], }); + } + }, []); // Update when tabKey or info[tabKey] changes + + + return ( + + + {(fields, { add, remove }) => ( +
+ {fields.map((field, index) => ( +
+ + {t("Information")} + + + {/* Nested Form.List for sub-items */} + + + {(subFields, subOpt) => ( +
+ {subFields.map((subField) => ( + + + + + + + + + { + subOpt.remove(subField.name); + }} + /> + + ))} + +
+ )} +
+
+
+ ))} +
+ )} +
+ + ); +}; + +export default ObjectField \ No newline at end of file diff --git a/src/Pages/Products/View/FormikTab/Field/SearchTabs.tsx b/src/Pages/Products/View/FormikTab/Field/SearchTabs.tsx new file mode 100644 index 0000000..37a0b16 --- /dev/null +++ b/src/Pages/Products/View/FormikTab/Field/SearchTabs.tsx @@ -0,0 +1,60 @@ +import React from 'react'; +import { Select } from 'antd'; +import { useTranslation } from 'react-i18next'; + +interface SearchTabsProps { + value: string; + onChange:any + name:any +} + +const SearchTabs: React.FC = ({ value, onChange ,name}) =>{ + const [t] = useTranslation() + + return ( +
+ + + +
+ ) +} + +export default React.memo(SelectField); diff --git a/src/Pages/Products/View/FormikTab/FormItem.tsx b/src/Pages/Products/View/FormikTab/FormItem.tsx new file mode 100644 index 0000000..91b4c0b --- /dev/null +++ b/src/Pages/Products/View/FormikTab/FormItem.tsx @@ -0,0 +1,19 @@ +// FormItem.tsx +import React from 'react'; +import { Input, Label } from 'reactstrap'; + +interface FormItemProps { + label: string; + value: string; + onChange: (e: React.ChangeEvent) => void; + type?: any +} + +export const FormItem: React.FC = ({ label, value, onChange ,type = "text"}) => { + return ( + <> + + + + ); +}; diff --git a/src/Pages/Products/View/FormikTab/TabItem.tsx b/src/Pages/Products/View/FormikTab/TabItem.tsx new file mode 100644 index 0000000..4b02d7e --- /dev/null +++ b/src/Pages/Products/View/FormikTab/TabItem.tsx @@ -0,0 +1,13 @@ +// TabItem.tsx +import React from 'react'; +import { VariableTabs } from './VariableTabs'; + +interface TabItemProps { + UKey: any; +} + +export const TabItem: React.FC = ({ UKey }) => { + return ( + + ); +}; diff --git a/src/Pages/Products/View/FormikTab/TabsContainer.tsx b/src/Pages/Products/View/FormikTab/TabsContainer.tsx new file mode 100644 index 0000000..062a131 --- /dev/null +++ b/src/Pages/Products/View/FormikTab/TabsContainer.tsx @@ -0,0 +1,104 @@ +// TabsContainer.tsx +import React, { useEffect, useState } from 'react'; +import { Tabs, Space } from 'antd'; +import { CopyOutlined } from '@ant-design/icons'; +import { TabItem } from './TabItem'; +import { toast } from 'react-toastify'; +import { FormikContext, FormikValues, useFormikContext } from 'formik'; +import { useTranslation } from 'react-i18next'; + +const { TabPane } = Tabs; + +const initialItemShape: any = { + label: 'variable 1', + key: '1', + closable: true, + }; +export const TabsContainer: React.FC = () => { + const [activeKey, setActiveKey] = useState('1'); +// const [items, setItems] = useState([]); + const [items, setItems] = useState([initialItemShape]); + const { setFieldValue } = useFormikContext(); + const formikContext = useFormikContext(); + const { values, handleChange } = formikContext; + const [width, setWidth] = useState(window.innerWidth); + const [t] = useTranslation() + const handleAdd = () => { + const newKey = `${items.length + 1}`; + setItems([...items, { key: newKey, label: `variable ${newKey}`, closable: true }]); + setActiveKey(newKey); + }; + + const handleDuplicate = (targetKey: string) => { + const targetItem = items.find((item) => item.key === targetKey); + if (targetItem) { + const newKey = `${items.length + 1}`; + const newItem = { ...targetItem, key: newKey, label: `variable ${newKey}` }; + setItems([...items, newItem]); + setActiveKey(newKey); + + const originalValues = values?.variable?.[targetKey]; + setFieldValue(`variable.${newKey}`, originalValues); + + const originalInfo = values?.info?.[targetKey]; + console.log(originalInfo); + + setFieldValue(`info.${newKey}`, originalInfo); + } + }; + + + const handleRemove = (targetKey: string) => { + const newItems = items.filter((item) => item.key !== targetKey); + if (newItems.length > 0) { + const newActiveKey = newItems.length ? newItems[newItems.length - 1].key : '1'; + setItems(newItems); + setActiveKey(newActiveKey); + } else { + toast.error("Cannot close the last tab"); + + } +}; + +useEffect(() => { + const handleResize = () => { + setWidth(window.innerWidth); + }; + + window.addEventListener('resize', handleResize); + + return () => { + window.removeEventListener('resize', handleResize); + }; +}, []); +const tabPosition = width > 1000 ? 'left' : 'top'; + + return ( + (action === 'add' ? handleAdd() : handleRemove(targetKey))} + tabPosition={tabPosition} + + > + {items.map((item :any) =>{ + return ( + + + {t(`${item.label}`)} + handleDuplicate(item.key)} /> + + } + closable={item.closable} + > + + + ) + })} + + ); +}; diff --git a/src/Pages/Products/View/FormikTab/VariableTabs.tsx b/src/Pages/Products/View/FormikTab/VariableTabs.tsx new file mode 100644 index 0000000..ddecc9f --- /dev/null +++ b/src/Pages/Products/View/FormikTab/VariableTabs.tsx @@ -0,0 +1,130 @@ +// VariableTabs.tsx +import React from 'react'; +import { Col, Row } from 'reactstrap'; +import { FormItem } from './FormItem'; +import { useFormikContext, FormikValues } from 'formik'; +import File from './Field/File'; +import MaltyFile from './Field/FileImage'; +import Select from './Field/Select'; +import ObjectField from './Field/Object'; +import Atteibute from './Field/Atteibute'; +import { useTranslation } from 'react-i18next'; + +interface VariableTabsProps { + tabKey: string; +} + +export const VariableTabs: React.FC = ({ tabKey }) => { + const { t } = useTranslation(); + const formikContext = useFormikContext(); + const { values, handleChange } = formikContext; + + const handleFieldChange = (fieldName: string) => ( + e: React.ChangeEvent | any + ) => { + handleChange(`variable.${tabKey}.${fieldName}`)(e); // Prepend "variable" + }; + const FormikName = (FormikFieldname: any) => values?.variable?.[tabKey]?.[FormikFieldname]; + const SelectedCategoriesAttribute = [ + { + name: "color", + id: 1, + data: [ + { + value: 1, + label: "red" + }, + { + value: 2, + label: "green" + }, + { + value: 3, + label: "blue" + } + ] + }, + { + name: "size", + id: 1, + data: [ + { + value: 1, + label: "xs" + }, + { + value: 2, + label: "sm" + }, + { + value: 3, + label: "lg" + } + ] + } + ] + + + return ( + <> +
{t("variables")} {tabKey}
+ + + + + + + + + {values?.category_id && + + } + + + + + + + + + + + + + ); +}; diff --git a/src/Pages/Products/View/Page.tsx b/src/Pages/Products/View/Page.tsx deleted file mode 100644 index 95d9b89..0000000 --- a/src/Pages/Products/View/Page.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import React, { useEffect, useState } from 'react' -import { getInitialValues, getValidationSchema, getDataToSend } from '../formUtil' -import { Tab, TabList, TabPanel as TabBody, Tabs } from 'react-tabs' -import 'react-tabs/style/react-tabs.css'; -import { MdLanguage } from 'react-icons/md' -import { FaSadCry } from 'react-icons/fa' -import ViewPage from '../../../Layout/Dashboard/ViewPage'; -import { Rate } from 'antd'; -import BasicInfo from './BasicInfo'; -import { usePageState } from '../../../lib/state mangment/LayoutPagestate'; -import { useParams } from 'react-router-dom'; -import LoadingPage from '../../../Layout/app/LoadingPage'; -import { useTranslation } from 'react-i18next'; -import { BsInfoCircle } from 'react-icons/bs'; -import { useGetOneProduct, useUpdateProduct } from '../../../api/product'; -import BasicInfo2 from './BasicInfo2'; -import useNavigateOnSuccess from '../../../Hooks/useNavigateOnSuccess'; -import VarianInfo from './VarianInfo'; - -const ViewProduct = () => { - const { setObjectToEdit, objectToEdit } = usePageState() - const {t} = useTranslation(); - const { id } = useParams() - const { data } = useGetOneProduct({id:id}) - const [BarStatus, setBarStatus] = useState({ value: 0, isLoading: false, isError: false, isSuccess: false }) - const {mutate ,isSuccess} = useUpdateProduct() - const handleSubmit = (values:any)=>{ - - values['product_id'] = id - - values['is_highlight'] =values['is_highlight'] == true ?1 :0 - values['is_most_purchase'] =values['is_most_purchase'] == true ?1 :0 - - const formToSend = getDataToSend(values) - - mutate(formToSend) - } - - useNavigateOnSuccess(isSuccess , '/products') - - - useEffect(() => { - console.log(data); - - setObjectToEdit(data); - - - - }, [data]); - - useEffect(()=>{ - - - return ()=>{ - setObjectToEdit(null) - - } - },[]) - - const ViewProps = { getInitialValues, getValidationSchema, getDataToSend, handleSubmit, BarStatus }; - - - return ( -
- {objectToEdit && data ? - - - -
{t("Base_info")}
- -
{t("VarianInfo")}
- - -
- -
-
- -
-
- -
-
- : } - - -
- ) - -} - -export default ViewProduct \ No newline at end of file diff --git a/src/Pages/Products/View/VarianInfo.tsx b/src/Pages/Products/View/VarianInfo.tsx index a26110d..25449c7 100644 --- a/src/Pages/Products/View/VarianInfo.tsx +++ b/src/Pages/Products/View/VarianInfo.tsx @@ -1,11 +1,11 @@ import React, { useState } from 'react' -import ResposiveTabs from './taps/ResposiveTabs' +import { TabsContainer } from './FormikTab/TabsContainer' const VarianInfo = () => { return (
- +
) } diff --git a/src/Pages/Products/View/taps/File.tsx b/src/Pages/Products/View/taps/File.tsx deleted file mode 100644 index 7c39e43..0000000 --- a/src/Pages/Products/View/taps/File.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import React from 'react'; -import { UploadOutlined } from '@ant-design/icons'; -import { Button, Upload } from 'antd'; -import type { UploadFile } from 'antd'; - -const fileList: UploadFile[] = [ - -]; - - -const App = ({value, onChange}:any) => { - - const FilehandleChange = (data:any) => { - - console.log('===================================='); - console.log(data?.fileList); - console.log('===================================='); - }; - const customRequest = async ({ onSuccess}: any) => { - onSuccess(); - }; - return( - - <> - onChange(data?.fileList)} - customRequest={customRequest} - > - - - - - ); -} - -export default App; \ No newline at end of file diff --git a/src/Pages/Products/View/taps/FileImage.tsx b/src/Pages/Products/View/taps/FileImage.tsx deleted file mode 100644 index 8cc8cb7..0000000 --- a/src/Pages/Products/View/taps/FileImage.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React from 'react'; -import { UploadOutlined } from '@ant-design/icons'; -import { Button, Upload } from 'antd'; -import type { UploadFile } from 'antd'; - -const fileList: UploadFile[] = [ - -]; - - -const App = ({value, onChange}:any) => { - - const FilehandleChange = (data:any) => { - - console.log('===================================='); - console.log(data?.fileList); - console.log('===================================='); - }; - const customRequest = async ({ onSuccess}: any) => { - onSuccess(); - }; - return( - - <> - onChange(data?.fileList)} - customRequest={customRequest} - > - - - - ); -} - -export default App; \ No newline at end of file diff --git a/src/Pages/Products/View/taps/NewTabs.tsx b/src/Pages/Products/View/taps/NewTabs.tsx deleted file mode 100644 index 548973c..0000000 --- a/src/Pages/Products/View/taps/NewTabs.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react' - -const NewTabs = () => { - function handelClick(){ - - } - return ( -
- -
- ) -} - -export default NewTabs \ No newline at end of file diff --git a/src/Pages/Products/View/taps/ResposiveTabs.tsx b/src/Pages/Products/View/taps/ResposiveTabs.tsx deleted file mode 100644 index 1433e7f..0000000 --- a/src/Pages/Products/View/taps/ResposiveTabs.tsx +++ /dev/null @@ -1,232 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import { Tabs, Space, Input } from 'antd'; -import { CopyOutlined } from '@ant-design/icons'; -import { useTranslation } from 'react-i18next'; -import { Col, Row } from 'reactstrap'; -import FileImage from './FileImage'; -import SearchTabs from './SearchTabs'; -import ObjectField from '../ObjectField'; -import { useFormikContext } from 'formik'; - -const { TabPane } = Tabs; - -interface TabItem { - label: string; - children: string; - key: string; - closable: boolean; -} - -const initialItemShape: TabItem = { - label: 'variable 1', - children: 'Content of Tab 1', - key: '1', - closable: false, -}; - -const App: React.FC = () => { - const [activeKey, setActiveKey] = useState(initialItemShape.key); - const [items, setItems] = useState([initialItemShape]); - const [inputValues, setInputValues] = useState<{ [key: string]: string[] }>({}); - const onChange = (newActiveKey: string) => { - setActiveKey(newActiveKey); - }; - useEffect(() => { -console.log(inputValues); - }, [inputValues]) - - -const formikContext = useFormikContext(); -const { values } :any = formikContext; - - - -useEffect(() => { - setInputValues((prevInputValues:any) => ({ - ...prevInputValues, - [14]: values?.info, - })); -}, [values?.info]) - - const add = () => { - const newActiveKey = `${items.length + 1}`; - const newItem: TabItem = { - ...initialItemShape, - key: newActiveKey, - label: `variable ${newActiveKey}`, - }; - const newPanes = [...items, newItem]; - setItems(newPanes); - setActiveKey(newActiveKey); - }; - - const duplicate = (targetKey: string) => { - const targetItem = items.find((item) => item.key === targetKey); - if (targetItem) { - const newActiveKey = `${items.length + 1}`; - const newItem: TabItem = { - ...targetItem, - key: newActiveKey, - label: `variable ${newActiveKey}`, - }; - - // Get the values of the original tab - const originalValues = inputValues[targetKey] || ['', '', '', '']; - - const newPanes = [...items, newItem]; - setItems(newPanes); - setActiveKey(newActiveKey); - - // Update the inputValues state with the original values for the new tab - setInputValues((prevInputValues) => ({ - ...prevInputValues, - [newActiveKey]: originalValues, - })); - } - }; - - - - const remove = (targetKey: string) => { - let newActiveKey = activeKey; - let lastIndex = -1; - items.forEach((item, i) => { - if (item.key === targetKey) { - lastIndex = i - 1; - } - }); - const newPanes = items.filter((item) => item.key !== targetKey); - if (newPanes.length && newActiveKey === targetKey) { - if (lastIndex >= 0) { - newActiveKey = newPanes[lastIndex].key; - } else { - newActiveKey = newPanes[0].key; - } - } - setItems(newPanes); - setActiveKey(newActiveKey); - }; - - const handleInputChange = (key: string, values: string[]) => { - setInputValues((prevInputValues) => ({ - ...prevInputValues, - [key]: values, - })); - console.log(inputValues); - }; - - const onEdit = ( - targetKey: string | React.MouseEvent | React.KeyboardEvent, - action: 'add' | 'remove' - ) => { - if (action === 'add') { - add(); - } else { - remove(targetKey as string); - } - }; - - return ( - - {items.map((item) => ( - - {item.label} - duplicate(item.key)} /> - - } - closable={item.closable} - > - handleInputChange(item.key, values)} - /> - - ))} - - ); -}; - -interface VariableTabsProps { - value: string[]; - onChange: (value: string[]) => void; -} - - -const VariableTabs: React.FC = ({ value, onChange } ) => { - const handleInputChange = (index: number) => (e: React.ChangeEvent) => { - const newValues = [...value]; - newValues[index] = e.target.value; - onChange(newValues); - }; - //@ts-ignore - const SelecthandleChange = (index: number) => (Selectvalue:any) => { - const newValues = [...value]; - newValues[index] = Selectvalue; - onChange(newValues); - }; - const FilehandleChange = (index: number) => (data:any) => { - const newValues = [...value]; - newValues[index] = data; - onChange(newValues); -}; - - const [t] = useTranslation(); - - return ( - <> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ); -}; - -export default App; diff --git a/src/Pages/Products/View/taps/VariableTabs.tsx b/src/Pages/Products/View/taps/VariableTabs.tsx deleted file mode 100644 index 55ef0aa..0000000 --- a/src/Pages/Products/View/taps/VariableTabs.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react' - -const VariableTabs = () => { - return ( -
VariableTabs
- ) -} - -export default VariableTabs \ No newline at end of file diff --git a/src/Pages/Products/View/varianForm.tsx b/src/Pages/Products/View/varianForm.tsx deleted file mode 100644 index 5505375..0000000 --- a/src/Pages/Products/View/varianForm.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' -import { Col, Row } from 'reactstrap' -import KarimField from '../../../Components/Karimalden/KarimField' -import { useTranslation } from 'react-i18next'; - -const varianForm = () => { - const [t] = useTranslation(); - - return ( - - - - - - - {/* */} - {/* */} - - - - - - ) -} - -export default varianForm \ No newline at end of file diff --git a/src/Pages/Products/formUtil.ts b/src/Pages/Products/formUtil.ts index bb8df19..d8e8092 100644 --- a/src/Pages/Products/formUtil.ts +++ b/src/Pages/Products/formUtil.ts @@ -1,62 +1,86 @@ import * as Yup from "yup"; -import { buildFormData } from "../../api/helper/buildFormData"; -import { mapTranslatedProperties } from "../../utils/language/mapTranslatedProperties"; export const getInitialValues = (objectToEdit: any | null = null) => { - - // console.log(objectToEdit); - + const product = Array.isArray(objectToEdit?.product) ? objectToEdit?.product.map((item: any) => ({ + name: item?.name, + description: item?.description, + images: item?.images, + main_photo: item?.main_photo, + price: item?.price, + quantity: item?.quantity, + product_attributes: item?.product_attributes, + })) : ( + { + ...objectToEdit?.product, + main_photo: objectToEdit?.product?.main_photo?.replace("public", "/storage"), + + } + ); + console.log(product, "product"); + + + const productInfo = objectToEdit?.product?.info || {}; // Ensure product.info exists and initialize as an empty object if it doesn't + const formattedData = Object.entries(productInfo).map(([key, value], index) => ({ + [`${index}.Description`]: key, + [`${index}.key`]: value, + })); + + const info = [undefined, ...formattedData]; + + + return { id: objectToEdit?.id ?? 0, - name:objectToEdit?.name ?? "", + name: objectToEdit?.name ?? "", name_ar: objectToEdit?.name?.ar ?? '', name_en: objectToEdit?.name?.en ?? '', name_de: objectToEdit?.name?.de ?? '', description: objectToEdit?.description ?? '', - price:objectToEdit?.price??"", - main_photo:objectToEdit?.main_photo??"", - images:objectToEdit?.images??"", - category_id:objectToEdit?.category_id??1, - variable:[], - info : [] - + price: objectToEdit?.price ?? "", + images: objectToEdit?.images ?? "", + attribute: objectToEdit?.attribute ?? "", + category_id: objectToEdit?.category?.id ?? "", + variable: [{}, product ?? {}], + info: [undefined, ...formattedData] ?? [], + } +}; + +export const getInitialValuesAdd = (objectToEdit: any | null = null) => { + + return { + id: "", + name: "", + name_ar:'', + name_en: '', + name_de: '', + description: '', + price: "", + images: "", + attribute: "", + category_id: "", + variable: [], + info: [], } }; export const getValidationSchema = (editMode: boolean = false) => { - // validate input + // validate input return Yup.object().shape({ - // name_ar: Yup.string().required('Required'), - // name_en: Yup.string().required('Required'), - // name_de: Yup.string().required('Required'), - // description_ar: Yup.string().required('Required'), - // description_en: Yup.string().required('Required'), - // description_de: Yup.string().required('Required'), - // price: Yup.number().required('Required'), - // // info: Yup.string().required('Required'), - // main_photo: Yup.string().required('Required'), - // // images: Yup.string().required('Required'), - // category_id: Yup.string().required('Required'), - // quantity: Yup.number().required('Required'), + name_ar: Yup.string().required('Required'), + name_en: Yup.string().required('Required'), + name_de: Yup.string().required('Required'), + category_id: Yup.string().required('Required'), + }); }; export const getDataToSend = (values: any): FormData => { const data = { ...values }; - // console.log(data); - if(typeof data['product_main_image'] == 'string') delete data['product_main_image'] - - data['en_product_name'] = values['translated_fields']['1']['product_name'] -data['ar_product_name'] =values['translated_fields']['2']['product_name'] -data['ar_product_description'] =values['translated_fields']['2']['product_description'] -data['en_product_description'] =values['translated_fields']['1']['product_description'] - const formData = new FormData(); - buildFormData(formData, data); - return formData; + return data; }; diff --git a/src/Pages/Products/useTableColumns.tsx b/src/Pages/Products/useTableColumns.tsx index c827704..d239c44 100644 --- a/src/Pages/Products/useTableColumns.tsx +++ b/src/Pages/Products/useTableColumns.tsx @@ -28,16 +28,6 @@ const useTableColumns :any = () => { return useMemo( () => [ - - { - name: t("image"), - center: "true", - cell: (row: any) => { - return ( - - ) - } - }, { name: t("name"), sortable: false, @@ -46,29 +36,30 @@ const useTableColumns :any = () => { }, { - name: t("price"), + name: t("product_count"), sortable: false, center: true, - selector:(row:any) => row?.price, + selector:(row:any) => row?.product_count, }, + { - name: t("description"), + name: t("category"), sortable: false, center: true, cell: (row:any) => ( - row?.description + row?.category?.name ), }, - { - name: t("favorite"), - sortable: false, - center: true, - cell: (row:any) => ( - - ), - }, + // { + // name: t("favorite"), + // sortable: false, + // center: true, + // cell: (row:any) => ( + // + // ), + // }, { name: "#", sortable: false, @@ -79,7 +70,7 @@ const useTableColumns :any = () => { objectToEdit={row} showEdit={true} showView={false} - onDelete={() => deleteMutation.mutate({ product_id: row.id })} + onDelete={() => deleteMutation.mutate({ id: row.id })} /> ), }, diff --git a/src/Pages/Coupon/ProductsPage.tsx b/src/Pages/Slider/Page.tsx similarity index 70% rename from src/Pages/Coupon/ProductsPage.tsx rename to src/Pages/Slider/Page.tsx index 29a62f2..75eae40 100644 --- a/src/Pages/Coupon/ProductsPage.tsx +++ b/src/Pages/Slider/Page.tsx @@ -10,26 +10,30 @@ import { Button } from 'antd' import { useTranslation } from 'react-i18next' import { useNavigate } from 'react-router-dom' import AddButton from '../../Layout/Dashboard/AddButton/AddButton' +import { useGetSlider } from '../../api/Slider' -function ProductsPage() { +function Page() { const column =useTableColumns() - const {data ,status } = useGetProduct("") + const {data ,status } = useGetSlider() console.log(data); const [t] = useTranslation() const navigate = useNavigate() + const totalRows = data?.meta?.total; return ( // Pass Status to Layout - - navigate('/products/add')}> + + navigate('/slider/add')}> @@ -37,5 +41,5 @@ function ProductsPage() { ) } -export default ProductsPage +export default Page diff --git a/src/Pages/Slider/View/AddForm.tsx b/src/Pages/Slider/View/AddForm.tsx new file mode 100644 index 0000000..ed9bf4e --- /dev/null +++ b/src/Pages/Slider/View/AddForm.tsx @@ -0,0 +1,34 @@ + +import React from 'react' +import { Col, Row } from 'reactstrap'; +import ValidationField from '../../../Components/ValidationField/ValidationField'; +import { useFormikContext } from 'formik'; + +import { DatePicker } from 'antd'; +import { useTranslation } from 'react-i18next'; + +function Form() { + const formik = useFormikContext(); + const [t] = useTranslation(); + + return ( + + + + + + + + + + + + + + + ) +} + +export default Form + + diff --git a/src/Pages/Slider/View/AddPage.tsx b/src/Pages/Slider/View/AddPage.tsx new file mode 100644 index 0000000..08d3d1b --- /dev/null +++ b/src/Pages/Slider/View/AddPage.tsx @@ -0,0 +1,57 @@ +import React, { useEffect, useState } from 'react' +import { getInitialValues, getValidationSchema, getDataToSend } from '../formUtil' +import { Tab, TabList, TabPanel as TabBody, Tabs } from 'react-tabs' +import 'react-tabs/style/react-tabs.css'; +import { MdLanguage } from 'react-icons/md' +import ViewPage from '../../../Layout/Dashboard/ViewPage'; +import { useTranslation } from 'react-i18next'; +import { BsInfoCircle } from 'react-icons/bs'; +import useNavigateOnSuccess from '../../../Hooks/useNavigateOnSuccess'; +import { useAddSlider } from '../../../api/Slider'; +import Form from './AddForm'; + +const AddSliderPage = () => { + + + const {mutate , isLoading , isSuccess} = useAddSlider() + const handleSubmit = (values:any)=>{ + + mutate(values) + + + } + const {t} = useTranslation(); + + useNavigateOnSuccess(isSuccess , '/Slider' ) + + + + const ViewProps = { getInitialValues, getValidationSchema, getDataToSend, handleSubmit }; + + + return ( +
+ + + + +
{t("BasicInfo")}
+ + + +
+ +
+
+ +
+
+ + + +
+ ) + +} + +export default AddSliderPage \ No newline at end of file diff --git a/src/Pages/Slider/View/EditForm.tsx b/src/Pages/Slider/View/EditForm.tsx new file mode 100644 index 0000000..95bc0f8 --- /dev/null +++ b/src/Pages/Slider/View/EditForm.tsx @@ -0,0 +1,34 @@ + +import React from 'react' +import { Col, Row } from 'reactstrap'; +import ValidationField from '../../../Components/ValidationField/ValidationField'; +import { useFormikContext } from 'formik'; + +import { DatePicker } from 'antd'; +import { useTranslation } from 'react-i18next'; +import { useGetCategories } from '../../../api/Categories'; + +function Form() { + const formik = useFormikContext(); + const [t] = useTranslation() + const {data} = useGetCategories() + + return ( + + + + + + + + + + + + + ) +} + +export default Form + + diff --git a/src/Pages/Coupon/View/Page.tsx b/src/Pages/Slider/View/EditPage.tsx similarity index 52% rename from src/Pages/Coupon/View/Page.tsx rename to src/Pages/Slider/View/EditPage.tsx index 6fa9f43..bfdd36a 100644 --- a/src/Pages/Coupon/View/Page.tsx +++ b/src/Pages/Slider/View/EditPage.tsx @@ -1,62 +1,57 @@ import React, { useEffect, useState } from 'react' -import { getInitialValues, getValidationSchema, getDataToSend } from '../formUtil' +import { getInitialValues, getDataToSend } from '../formUtil' import { Tab, TabList, TabPanel as TabBody, Tabs } from 'react-tabs' import 'react-tabs/style/react-tabs.css'; import { MdLanguage } from 'react-icons/md' import { FaSadCry } from 'react-icons/fa' import ViewPage from '../../../Layout/Dashboard/ViewPage'; import { Rate } from 'antd'; -import BasicInfo from './BasicInfo'; import { usePageState } from '../../../lib/state mangment/LayoutPagestate'; import { useParams } from 'react-router-dom'; import LoadingPage from '../../../Layout/app/LoadingPage'; import { useTranslation } from 'react-i18next'; import { BsInfoCircle } from 'react-icons/bs'; -import { useGetOneProduct, useUpdateProduct } from '../../../api/product'; -import BasicInfo2 from './BasicInfo2'; +import { useGetOneSlider, useUpdateSlider } from '../../../api/Slider'; import useNavigateOnSuccess from '../../../Hooks/useNavigateOnSuccess'; +import Form from './EditForm'; -const ViewProduct = () => { +const EditPage = () => { const { setObjectToEdit, objectToEdit } = usePageState() const {t} = useTranslation(); - const { id } = useParams() - const { data } = useGetOneProduct({id:id}) - const [BarStatus, setBarStatus] = useState({ value: 0, isLoading: false, isError: false, isSuccess: false }) - const {mutate ,isSuccess} = useUpdateProduct() + const { data } = useGetOneSlider() + const {mutate ,isSuccess} = useUpdateSlider() + const FormatedData = data?.data ; const handleSubmit = (values:any)=>{ + + const newData = {} as any; - values['product_id'] = id + for (const key in FormatedData) { + if (values[key] !== FormatedData[key]) { + newData[key] = values[key]; + } - values['is_highlight'] =values['is_highlight'] == true ?1 :0 - values['is_most_purchase'] =values['is_most_purchase'] == true ?1 :0 + } - const formToSend = getDataToSend(values) - - mutate(formToSend) + return mutate(newData); } - useNavigateOnSuccess(isSuccess , '/products') + useNavigateOnSuccess(isSuccess , '/Slider') useEffect(() => { console.log(data); - setObjectToEdit(data); - - + setObjectToEdit(data?.category); }, [data]); - useEffect(()=>{ + + const getValidationSchema = () => { + return null + }; - return ()=>{ - setObjectToEdit(null) - - } - },[]) - - const ViewProps = { getInitialValues, getValidationSchema, getDataToSend, handleSubmit, BarStatus }; + const ViewProps = { getInitialValues, getValidationSchema, getDataToSend, handleSubmit }; return ( @@ -67,16 +62,11 @@ const ViewProduct = () => {
{t("BasicInfo")}
-
{t("BasicInfo2")}
- -
-
-
- -
+
+ @@ -88,4 +78,4 @@ const ViewProduct = () => { } -export default ViewProduct \ No newline at end of file +export default EditPage \ No newline at end of file diff --git a/src/Pages/Coupon2/formUtil.ts b/src/Pages/Slider/formUtil.ts similarity index 50% rename from src/Pages/Coupon2/formUtil.ts rename to src/Pages/Slider/formUtil.ts index 1c5bf86..012e3ad 100644 --- a/src/Pages/Coupon2/formUtil.ts +++ b/src/Pages/Slider/formUtil.ts @@ -19,21 +19,13 @@ interface InitialValues extends ObjectToEdit { interface ValidateSchema extends formUtilCommon{ } - export const getInitialValues = (objectToEdit: any | null = null): any => { + console.log(objectToEdit,"objectToEdit"); return { id: objectToEdit?.id ?? 0, - name: objectToEdit?.name??"", - code: objectToEdit?.code??"", - coupon_value: objectToEdit?.coupon_value??"", - status: objectToEdit?.status??"", - active_to: objectToEdit?.active_to??"", - discount_type: objectToEdit?.discount_type??"", - coupon_type: objectToEdit?.coupon_type??"", - minimum_total_to_order: objectToEdit?.minimum_total_to_order??"", - maximum_number_of_uses: objectToEdit?.maximum_number_of_uses??"", - useable_by_guest: objectToEdit?.useable_by_guest??"", - + title:objectToEdit?.title ?? "", + image: objectToEdit?.image ?? '', + }; }; @@ -41,21 +33,14 @@ export const getInitialValues = (objectToEdit: any | null = null): any => { export const getValidationSchema = (editMode: boolean = false): Yup.Schema => { // Validate input return Yup.object().shape({ - name : Yup.string().required('Required'), - code : Yup.number().required('Required'), - coupon_value : Yup.number().required('Required'), - status : Yup.string().required('Required'), - active_to : Yup.string().required('Required'), - discount_type : Yup.string().required('Required'), - coupon_type : Yup.string().required('Required'), - minimum_total_to_order : Yup.number().required('Required'), - maximum_number_of_uses : Yup.number().required('Required'), - useable_by_guest : Yup.string().required('Required'), + title: Yup.string().required('Required'), + image: Yup.string().required('Required'), }); }; + export const getDataToSend = (values: any): FormData => { const data = { ...values }; diff --git a/src/Pages/Coupon2/useTableColumns.tsx b/src/Pages/Slider/useTableColumns.tsx similarity index 59% rename from src/Pages/Coupon2/useTableColumns.tsx rename to src/Pages/Slider/useTableColumns.tsx index bda23da..29854c4 100644 --- a/src/Pages/Coupon2/useTableColumns.tsx +++ b/src/Pages/Slider/useTableColumns.tsx @@ -3,60 +3,36 @@ import React, { useMemo } from "react"; import { useTranslation } from "react-i18next"; import Actions from "../../Components/Ui/tables/Actions"; import ColumnsImage from "../../Components/Columns/ColumnsImage"; -import { useDeleteCoupon } from "../../api/Coupon"; +import { useDeleteCategories } from "../../api/Categories"; import { useNavigate } from "react-router-dom"; -import { Button } from "antd"; +import { useDeleteSlider } from "../../api/Slider"; function fnDelete(props :any ){} const useTableColumns :any = () => { const [t] = useTranslation(); - const deleteMutation = useDeleteCoupon() + const deleteMutation = useDeleteSlider() const navigate = useNavigate() return useMemo( () => [ { - name: t("name"), + name: t("title"), sortable: false, center: "true", - cell: (row:any) => row?.name - }, - - { - name: t("code"), - sortable: false, - center: "true", - cell: (row:any) => row?.code + cell: (row:any) => row?.title }, { - name: t("coupon_value"), + name: t("image"), sortable: false, center: "true", - cell: (row:any) => row?.coupon_value - } - , - { - name: t("status"), - sortable: false, - center: true, - cell: (row:any) => { - return - + + cell: (row:any) => { + let str = row?.image; + str = str?.replace(`public`, "/storage") ?? ""; + return } }, - { - name: t("discount_type"), - sortable: false, - center: "true", - cell: (row:any) => row?.discount_type - }, - { - name: t("coupon_type"), - sortable: false, - center: "true", - cell: (row:any) => row?.coupon_type - }, { name: "#", sortable: false, @@ -64,9 +40,10 @@ const useTableColumns :any = () => { cell: (row:any) => ( navigate(`/Coupon/${row.id}`) } + + onEdit={()=> navigate(`/slider/${row.id}`) } showView={false} + showEdit={false} onDelete={() => deleteMutation.mutate({ id: row.id })} /> ), diff --git a/src/Pages/appSetting/FormAppSetting.tsx b/src/Pages/appSetting/FormAppSetting.tsx index 5c26f57..44e51d9 100644 --- a/src/Pages/appSetting/FormAppSetting.tsx +++ b/src/Pages/appSetting/FormAppSetting.tsx @@ -1,11 +1,9 @@ import React from 'react' import { Col, Row } from 'reactstrap'; -import KarimField from '../../Components/Karimalden/KarimField'; -import { FakeSelectData } from '../../Layout/app/Const'; +import ValidationField from '../../Components/ValidationField/ValidationField'; import { useFormikContext } from 'formik'; -import { DatePicker } from 'antd'; function FormAppSetting() { const formik = useFormikContext(); @@ -15,12 +13,12 @@ function FormAppSetting() { return ( - + - + diff --git a/src/Pages/order/Edit/EditForm.tsx b/src/Pages/order/Edit/EditForm.tsx new file mode 100644 index 0000000..ae92794 --- /dev/null +++ b/src/Pages/order/Edit/EditForm.tsx @@ -0,0 +1,41 @@ + +import React from 'react' +import { Col, Row } from 'reactstrap'; +import ValidationField from '../../../Components/ValidationField/ValidationField'; +import { useFormikContext } from 'formik'; + +import { useTranslation } from 'react-i18next'; + +function Form() { + const formik = useFormikContext(); + const [t] = useTranslation(); + + // 'pending_approve', 'approved', 'rejected', 'pending_cancellation', 'cancelled' + const stateSelect = [ + { label: "pending_approve", value: "pending_approve" }, { label: "approved", value: "approved" }, + { label: "rejected", value: "rejected" }, { label: "pending_cancellation", value: "pending_cancellation" }] + + + return ( + + + + + + + + + + + + + + + + + ) +} + +export default Form + + diff --git a/src/Pages/order/Edit/EditPage.tsx b/src/Pages/order/Edit/EditPage.tsx new file mode 100644 index 0000000..9b0bd2c --- /dev/null +++ b/src/Pages/order/Edit/EditPage.tsx @@ -0,0 +1,86 @@ +import React, { useEffect, useState } from 'react' +import { getInitialValues, getDataToSend } from './formUtil' +import { Tab, TabList, TabPanel as TabBody, Tabs } from 'react-tabs' +import 'react-tabs/style/react-tabs.css'; +import { MdLanguage } from 'react-icons/md' +import { FaSadCry } from 'react-icons/fa' +import ViewPage from '../../../Layout/Dashboard/ViewPage'; +import { Rate } from 'antd'; +import { usePageState } from '../../../lib/state mangment/LayoutPagestate'; +import { useParams } from 'react-router-dom'; +import LoadingPage from '../../../Layout/app/LoadingPage'; +import { useTranslation } from 'react-i18next'; +import { BsInfoCircle } from 'react-icons/bs'; +import { useGetOneSlider, useUpdateSlider } from '../../../api/Slider'; +import useNavigateOnSuccess from '../../../Hooks/useNavigateOnSuccess'; +import Form from './EditForm'; +import { useGetOneOrder } from '../../../api/order'; + + + +const EditPage = () => { + const { setObjectToEdit, objectToEdit } = usePageState() + const {t} = useTranslation(); + const {mutate ,isSuccess} = useUpdateSlider() + const { id } = useParams(); + const { data, isLoading } = useGetOneOrder({id: id }) + const FormatedData = data?.data ; + + const handleSubmit = (values:any)=>{ + + const newData = {} as any; + + for (const key in FormatedData) { + if (values[key] !== FormatedData[key]) { + newData[key] = values[key]; + } + + } + + return mutate(newData); + } + + useNavigateOnSuccess(isSuccess , '/order') + + + useEffect(() => { + console.log(data); + + setObjectToEdit(data?.data); + + }, [data]); + + + const getValidationSchema = () => { + return null + }; + + + const ViewProps = { getInitialValues, getValidationSchema, getDataToSend, handleSubmit }; + + + return ( +
+ {objectToEdit && data?.data ? + + + +
{t("BasicInfo")}
+ +
+ +
+
+ + +
+
+ : } + + +
+ ) + +} + +export default EditPage \ No newline at end of file diff --git a/src/Pages/order/Edit/formUtil.ts b/src/Pages/order/Edit/formUtil.ts new file mode 100644 index 0000000..73a8729 --- /dev/null +++ b/src/Pages/order/Edit/formUtil.ts @@ -0,0 +1,59 @@ + +import * as Yup from "yup"; +import { buildFormData } from "../../../api/helper/buildFormData"; + +interface formUtilCommon { + number:number, + value:number +} + +interface ObjectToEdit extends formUtilCommon { + + id?:number, + +} + +interface InitialValues extends ObjectToEdit { + +} +interface ValidateSchema extends formUtilCommon{ + +} +export const getInitialValues = (objectToEdit: any | null = null): any => { + console.log(objectToEdit,"objectToEdit"); + return { + id: objectToEdit?.id ?? 0, + state:objectToEdit?.state ?? "", + admin_note: objectToEdit?.admin_note ?? '', + + }; +}; + + +export const getValidationSchema = (editMode: boolean = false): Yup.Schema => { + // Validate input + return Yup.object().shape({ + + }); +}; + + + +export const getDataToSend = (values: any): FormData => { + const data = { ...values }; + + + const formData = new FormData(); + buildFormData(formData, data); + return formData; +}; + +export const ChangeDataToPrint = (data:any)=>{ + + let new_array = data + for(let i =0 ; i { const [t] = useTranslation(); @@ -17,13 +17,8 @@ const OrderPage = () => { const filterIsApplied = search !== ""; - - - - //Table Content -- Data + Columns const { data, isLoading , status } = useGetOrder({search}); - console.log(data); const totalRows = data?.pagination?.total || 0; diff --git a/src/Pages/order/useTableColumns.tsx b/src/Pages/order/useTableColumns.tsx index 44eceff..7453b61 100644 --- a/src/Pages/order/useTableColumns.tsx +++ b/src/Pages/order/useTableColumns.tsx @@ -23,18 +23,17 @@ const useTableColumns = () => { center:true, selector:(row:any) => row?.id, }, - { - name: t("image"), - sortable: false, - center:true, - selector:(row:any) => { - const {avatar} = row.user - return( - - - ) - } - }, + // { + // name: t("image"), + // sortable: false, + // center:true, + // width : "100px", + // selector:(row:any) => { + // let str = row?.photo; + // str = str?.replace(`public`, "/storage") ?? ""; + // return + // } + // }, { name: t("name"), @@ -56,26 +55,19 @@ const useTableColumns = () => { cell:(row:any)=>{ - return row?.order_status; + return row?.state; // return } }, + { - name: t("payment_method"), - selector: "payment_method", - center: true, - cell:(row:any)=>{ - return t(row?.payment_method) - } - }, - { - name: t("price"), + name: t("total"), center: true, cell:(row:any)=>{ console.log(row); - return (row?.order_total) + return (row?.total) } }, { @@ -88,8 +80,10 @@ const useTableColumns = () => { showDelete={false} objectToEdit={row} onDelete={() => deleteMutation.mutate({order_id:row.id })} - showEdit={false} - onView={()=>navigate(`/order/${row?.id}` , {replace:true})} + showEdit={true} + onView={()=>navigate(`/order/view/${row?.id}` , {replace:true})} + onEdit={()=>navigate(`/order/${row?.id}` , {replace:true})} + /> diff --git a/src/Pages/order/view-one/Order.js b/src/Pages/order/view-one/Order.js index 959523b..3972fae 100644 --- a/src/Pages/order/view-one/Order.js +++ b/src/Pages/order/view-one/Order.js @@ -33,10 +33,7 @@ export default function Order() { const columns = useTableColumns(); const items = order?.products ; - console.log(items); - -console.log(order); - + if (isLoading) { return () } diff --git a/src/Routes.tsx b/src/Routes.tsx index 6b9424e..e6b7307 100644 --- a/src/Routes.tsx +++ b/src/Routes.tsx @@ -1,26 +1,36 @@ -import { ReactNode, lazy } from "react"; +import { ReactNode } from "react"; // Icons Import -import { FaCartArrowDown, FaImages } from "react-icons/fa"; - -import { FaUser, FaHome, FaSadCry } from "react-icons/fa" +import { FaCartArrowDown, FaHome, FaProductHunt, FaRegImages } from "react-icons/fa" import { BiSolidCategory } from "react-icons/bi"; import { BiSolidCoupon } from "react-icons/bi"; // Pages Import +import HomePage from "./Pages/Home/HomePage"; +import CategoriesPage from "./Pages/Categories/Page"; import AddCategoriesPage from "./Pages/Categories/View/AddPage"; import EditCategories from "./Pages/Categories/View/EditPage"; -import CategoriesPage from "./Pages/Categories/Page"; -import HomePage from "./Pages/Home/HomePage"; import ProductsPage from "./Pages/Products/ProductsPage"; import AddProductPage from "./Pages/Products/View/AddPage"; -import EditProduct from "./Pages/Products/View/Page"; +import EditProduct from "./Pages/Products/View/EditPage" +; import Order from "./Pages/order/view-one/Order"; import OrderPage from "./Pages/order/OrderPage"; +import EditOrder from "./Pages/order/Edit/EditPage"; + + +import CouponPage from "./Pages/Coupon/Page"; +import AddCouponPage from "./Pages/Coupon/View/AddPage"; +import EditCoupon from "./Pages/Coupon/View/EditPage"; + +import SliderPage from "./Pages/Slider/Page"; +import AddSliderPage from "./Pages/Slider/View/AddPage"; +import EditSlider from "./Pages/Slider/View/EditPage"; + interface RoutesLinksType { @@ -31,7 +41,6 @@ interface RoutesLinksType { Viewelement?: ReactNode, Viewhref?: string children?: any - // Hidden the route from the navigation sidebar hidden?: boolean } export const RoutesLinks: RoutesLinksType[] = [ @@ -50,28 +59,6 @@ export const RoutesLinks: RoutesLinksType[] = [ , href: "/categories", }, - - // { - // name: "Coupon", - // element: , - // icon: , - // href: "/Coupon", - // }, - { - name: "products", - element: , - icon: , - href: "/products", - }, - - { - name: "Order", - element: , - icon: , - href: "/order", - }, - - { href: "/categories/:id", element: , @@ -82,29 +69,82 @@ export const RoutesLinks: RoutesLinksType[] = [ element: , hidden:true }, - + + { + name: "Products", + element: , + icon: , + href: "/products", + }, { name: "add_products", element: , - // icon: , href: "/products/add", hidden:true }, { name: "edit_products", element: , - // icon: , href: "/products/:id", hidden:true + }, + + { + name: "Order", + element: , + icon: , + href: "/order", + }, + + { + name: "edit_order", + element: , + href: "/order/:id", + hidden:true + }, { name: "view_order", element: , - href: "/order/:id", + href: "/order/view/:id", hidden:true }, + { + name: "Coupon", + element: , + icon: , + href: "/coupon", + }, + { + href: "/coupon/:id", + element: , + hidden:true + }, + { + href: "/coupon/add", + element: , + hidden:true + }, + { + name: "Slider", + element: , + icon: , + href: "/slider", + }, + { + href: "/slider/:id", + element: , + hidden:true + }, + { + href: "/slider/add", + element: , + hidden:true + }, + + ] \ No newline at end of file diff --git a/src/Styles/Layout/Layout.scss b/src/Styles/Layout/Layout.scss index bbe2500..6266380 100644 --- a/src/Styles/Layout/Layout.scss +++ b/src/Styles/Layout/Layout.scss @@ -244,12 +244,12 @@ background: var(--bg); background-color:transparent; color:var(--text); } -.react-tabs__tab-panel--selected .KarimField .ant-input-affix-wrapper,.modal-body .KarimField .ant-input-affix-wrapper{ +.react-tabs__tab-panel--selected .ValidationField .ant-input-affix-wrapper,.modal-body .ValidationField .ant-input-affix-wrapper{ background-color:transparent; } /* Input */ -.react-tabs__tab-panel--selected .KarimField input[type=text],.modal-body .KarimField input{ +.react-tabs__tab-panel--selected .ValidationField input[type=text],.modal-body .ValidationField input{ background-color:transparent; color:var(--text)!important; &::placeholder{ @@ -295,7 +295,6 @@ background: var(--bg); border-top: none; border-left: none; border-right: none; border-bottom: 4px solid var(--primary); color: var(--primary); - z-index: 99999; background: var(--bg2); } @@ -389,7 +388,7 @@ padding: 10px 40px; } .VarianInfo{ - padding: 10px 70px; + padding: 10px 20px; } @@ -404,4 +403,90 @@ padding: 10px 40px; display: flex; flex-direction: column; width: 100%; - } \ No newline at end of file + } + .warning { + color: var(--primary) !important; + margin-bottom: 10px; + height: 4vw; + width: 4vw; + } + .css-1u0lry5-MuiChartsLegend-root { + direction: ltr; + } + + + ////// Tabs + .ant-tabs-nav-wrap .ant-tabs-nav-list .ant-tabs-tab{ + display:flex; + color:var(--subtext) !important; + } + + /* Ant tabs tab */ + .ant-tabs-nav-list .ant-tabs-tab .ant-tabs-tab-btn{ + color:var(--text) !important; + } + + /* Ant tabs tab remove */ + .ant-tabs-nav-list .ant-tabs-tab .ant-tabs-tab-remove{ + color:var(--subtext) !important; + } + /* Ant tabs nav add */ +.ant-tabs-nav-wrap .ant-tabs-nav-list .ant-tabs-nav-add{ + padding-top:5px; + padding-bottom:5px; + color:var(--primary) !important; + + } + + .ant-tabs-nav-wrap .ant-tabs-nav-list .ant-tabs-tab-active{ + +.ant-tabs-tab-btn{ + color:var(--text) !important; + font-weight: bold; + background: var(--bg); + +} +.ant-tabs-tab-remove{ + color:var(--text) !important; + } + } + + + .BarChart{ + width: 100%; + height: 30vw + ; + } + + @media (max-width: 800px) { + .BarChart{ + width: 100%; + height: 50vw + ; + } + /* Text */ +.MuiChartsLegend-root .MuiChartsLegend-series text{ + font-size:2vw !important; + } + .MuiChartsLegend-root .MuiChartsLegend-series .MuiChartsLegend-mark{ + width:2vw; + height:2vw; + } + #root .DashboardLayout .DashboardLayout_Cover #DashboardLayout_Body .Layout_Children .row-cols-1 .BarChart .css-l0h214-MuiResponsiveChart-container .css-bd9tpx-MuiChartsSurface-root .MuiChartsLegend-root .MuiChartsLegend-series text{ + transform: translatey(-2px) !important; + } + + + } + @media (max-width: 600px) { + .BarChart{ + display:none; + } + + + + } + + + + \ No newline at end of file diff --git a/src/Styles/Layout/SideBar.scss b/src/Styles/Layout/SideBar.scss index 5202996..ad617cc 100644 --- a/src/Styles/Layout/SideBar.scss +++ b/src/Styles/Layout/SideBar.scss @@ -1,7 +1,6 @@ .SideBar { - z-index: 9999; display: flex; flex-direction: column; width: 260px; diff --git a/src/Styles/Layout/Table.scss b/src/Styles/Layout/Table.scss index 689fd4f..a889fe5 100644 --- a/src/Styles/Layout/Table.scss +++ b/src/Styles/Layout/Table.scss @@ -77,4 +77,17 @@ #dynamic_form_complex div .ant-space-item{ min-width:47%; } - \ No newline at end of file + + + + + .ant-tabs-nav-wrap .ant-tabs-nav-list .ant-tabs-tab{ + direction: ltr; + } + + + .ar{ + .VarianInfo .ant-tabs-editable .ant-tabs-nav{ + margin-left:12px; + } + } \ No newline at end of file diff --git a/src/api/Categories.ts b/src/api/Categories.ts index 63183a3..9a7a9d8 100644 --- a/src/api/Categories.ts +++ b/src/api/Categories.ts @@ -5,6 +5,7 @@ import useDeleteMutation from "./helper/useDeleteMutation" import useGetOneQuery from "./helper/useGetOneQuery"; import useGetQuery from "./helper/useGetQuery" import useUpdateMutation from "./helper/useUpdateMutation"; +import useUpdateMutationPost from "./helper/useUpdateMutationPut"; const API = { ADD: `category`, @@ -20,6 +21,6 @@ export const useGetCategories = (params?:any) => useGetQueryPagination(KEY, API. export const useGetOneCategories = () => useGetOneQuery(KEY, API.GET_ALL); export const useAddCategories = () => useAddMutation(KEY, API.ADD); -export const useUpdateCategories = () => useUpdateMutation(KEY, API.UPDATE); +export const useUpdateCategories = (method?:any) => useUpdateMutationPost(KEY, API.UPDATE,method); export const useDeleteCategories = () =>useDeleteMutation(KEY, API.DELETE); diff --git a/src/api/Coupon.ts b/src/api/Coupon.ts index 1a070ce..ed81421 100644 --- a/src/api/Coupon.ts +++ b/src/api/Coupon.ts @@ -17,9 +17,9 @@ const KEY = "COUPON" export const useGetCoupon = (params?:any) => useGetQueryPagination(KEY, API.GET_ALL,params); -export const useGetOneCoupon = (params?:any) => useGetOneQuery(KEY, API.GET_ALL,params); +export const useGetOneCoupon = () => useGetOneQuery(KEY, API.GET_ALL); export const useAddCoupon = () => useAddMutation(KEY, API.ADD); -export const useUpdateCoupon = () => useUpdateMutation(KEY, API.UPDATE); +export const useUpdateCoupon = (method?:any) => useUpdateMutation(KEY, API.UPDATE,method); export const useDeleteCoupon = () =>useDeleteMutation(KEY, API.DELETE); diff --git a/src/api/Slider.ts b/src/api/Slider.ts index c9026cc..c2651e8 100644 --- a/src/api/Slider.ts +++ b/src/api/Slider.ts @@ -17,7 +17,7 @@ const KEY = "SLIDER" export const useGetSlider = (params?:any) => useGetQueryPagination(KEY, API.GET_ALL,params); -export const useGetOneSlider = (params?:any) => useGetOneQuery(KEY, API.GET_ALL,params); +export const useGetOneSlider = () => useGetOneQuery(KEY, API.GET_ALL); export const useAddSlider = () => useAddMutation(KEY, API.ADD); export const useUpdateSlider = () => useUpdateMutation(KEY, API.UPDATE); diff --git a/src/api/attribute.ts b/src/api/attribute.ts new file mode 100644 index 0000000..c166cd0 --- /dev/null +++ b/src/api/attribute.ts @@ -0,0 +1,28 @@ + +import useGetQueryPagination from "./helper/ueGetPagination"; +import useAddMutation from "./helper/useAddMutation" +import useDeleteMutation from "./helper/useDeleteMutation" +import useGetOneQuery from "./helper/useGetOneQuery"; +import useGetQuery from "./helper/useGetQuery" +import useGetSingleQuery from "./helper/useGetSingleQuery"; +import useUpdateMutation from "./helper/useUpdateMutation"; + +const API = { + ADD: `attribute`, + GET_ALL: `attribute`, + DELETE: `attribute`, + UPDATE: `attribute`, + +}; +const KEY = "ATTRIBUTE" + + +export const useGetAttribute = (params?:any) => useGetQueryPagination(KEY, API.GET_ALL,params); +export const useGetOneAttribute = (params?:any) => useGetOneQuery(KEY, API.GET_ALL,params); +export const useGetSingleAttribute = (params?:any) => useGetSingleQuery(KEY, API.GET_ALL,params); + +export const useAddAttribute = () => useAddMutation(KEY, API.ADD); +export const useUpdateAttribute = () => useUpdateMutation(KEY, API.UPDATE); +export const useUpdateAttributeStatus = () => useUpdateMutation(KEY, API.UPDATE); + +export const useDeleteAttribute = () =>useDeleteMutation(KEY, API.DELETE); diff --git a/src/api/config.ts b/src/api/config.ts index a671743..fdbc3ac 100644 --- a/src/api/config.ts +++ b/src/api/config.ts @@ -1,8 +1,8 @@ // export const BaseURL = `https://etaxiapi.rayantaxi.com/`; -// export const BaseURL = `https://etaxi.sdnone.net/`; +// export const BaseURL = `https://etaxi.Point.net/`; export const BaseURL = `https://hijabi-back-dev.point-dev.net/api/`; -export const ImageBaseURL = `https://hijabi-back-dev.point-dev.net/api/`; +export const ImageBaseURL = `https://hijabi-back-dev.point-dev.net`; // export const BaseURL = `http://192.168.1.14:8000/`; diff --git a/src/api/helper/useGetSingleQuery.ts b/src/api/helper/useGetSingleQuery.ts new file mode 100644 index 0000000..e930dc7 --- /dev/null +++ b/src/api/helper/useGetSingleQuery.ts @@ -0,0 +1,38 @@ +import { useQuery } from 'react-query'; +import useAxios from './useAxios'; +import useAuthState from '../../lib/state mangment/AuthState'; +import { useNavigate, useParams } from 'react-router-dom'; + +function useGetSingleQuery(key: string, url: string , params:any={},options:any={}) { + const axios = useAxios(); + const {logout} = useAuthState() + const language = localStorage.getItem("language") ?? "en" + const navigate = useNavigate() + const {id} = useParams() + + return useQuery( + [id, key,params?.id], + async () => { + const response = await axios.get(url+"?"+params?.name+"="+params?.id+`?lang=${language}`); + return response.data; + }, + + + { + onError: (error:any) => { + if(error.response.status == 401 || error.response.status == 403){ + logout() + navigate("/auth") + + } + + }, + refetchOnWindowFocus: false, + + ...options + + } + ); +} + +export default useGetSingleQuery; diff --git a/src/api/helper/useUpdateMutation.ts b/src/api/helper/useUpdateMutation.ts index 99ea8d7..04843c2 100644 --- a/src/api/helper/useUpdateMutation.ts +++ b/src/api/helper/useUpdateMutation.ts @@ -12,7 +12,8 @@ type AxiosResponse = { const useUpdateMutation = ( key: string, url: string, - toastMessage: boolean = true + toastMessage: boolean = true, + method?:string ): UseMutationResult => { const axios = useAxios(); const queryClient = useQueryClient(); @@ -21,8 +22,14 @@ const useUpdateMutation = ( return useMutation( async (dataToSend) => { - const { data } = await axios.post(url+"/"+id, dataToSend); + + const { data } = await axios.put(url+"/"+id, dataToSend,{ + headers: { + 'Content-Type': 'multipart/form-data' + } + }); return data; + }, { onSuccess: (data) => { diff --git a/src/api/helper/useUpdateMutationPut.ts b/src/api/helper/useUpdateMutationPut.ts new file mode 100644 index 0000000..bac1190 --- /dev/null +++ b/src/api/helper/useUpdateMutationPut.ts @@ -0,0 +1,52 @@ +import { useQueryClient, useMutation, UseMutationResult } from "react-query"; +import { toast } from "react-toastify"; +import useAxios from "./useAxios"; +import { useTranslation } from "react-i18next"; +import { useParams } from "react-router-dom"; + +type AxiosResponse = { + message: string; + // Add other properties as needed +}; + +const useUpdateMutationPost = ( + key: string, + url: string, + toastMessage: boolean = true, + method?:string +): UseMutationResult => { + const axios = useAxios(); + const queryClient = useQueryClient(); + const [t] = useTranslation(); + const {id}= useParams() + + return useMutation( + async (dataToSend) => { + + const { data } = await axios.post(url+"/"+id, dataToSend,{ + headers: { + 'Content-Type': 'multipart/form-data' + } + }); + return data; + + }, + { + onSuccess: (data) => { + if (toastMessage) { + toast.success(data.message || t("updated_successfully")); + } + queryClient.invalidateQueries([key]); + }, + onError: (err:any) => { + const message = err?.response?.data?.message || t("failed_to_update_data"); + toast.error(message); + + + // validateSession(err.response); + }, + } + ); +}; + +export default useUpdateMutationPost; diff --git a/src/api/product.ts b/src/api/product.ts index f8cf512..615970c 100644 --- a/src/api/product.ts +++ b/src/api/product.ts @@ -7,20 +7,28 @@ import useGetQuery from "./helper/useGetQuery" import useUpdateMutation from "./helper/useUpdateMutation"; const API = { - ADD: `product`, - GET_ALL: `product`, - DELETE: `product`, - UPDATE: `product`, + ADD: `baseProduct`, + GET_ALL: `baseProduct`, + DELETE: `baseProduct`, + UPDATE: `baseProduct`, + ADD_VAR:"product", + UPDATE_VAR:"product" + }; const KEY = "Product" +const ONEKEY = "OneProduct" export const useGetProduct = (params?:any) => useGetQueryPagination(KEY, API.GET_ALL,params); -export const useGetOneProduct = (params?:any) => useGetOneQuery(KEY, API.GET_ALL,params); +export const useGetOneProduct = (params?:any) => useGetOneQuery(ONEKEY, API.GET_ALL,params); export const useAddProduct = () => useAddMutation(KEY, API.ADD); +export const useAddProductVariation = () => useAddMutation(KEY, API.ADD_VAR); + export const useUpdateProduct = () => useUpdateMutation(KEY, API.UPDATE); +export const useUpdateProductVariation = () => useUpdateMutation(KEY, API.ADD_VAR); + export const useUpdateProductStatus = () => useUpdateMutation(KEY, API.UPDATE); export const useDeleteProduct = () =>useDeleteMutation(KEY, API.DELETE); diff --git a/src/lib/ToastProvider.tsx b/src/lib/ToastProvider.tsx index 7ae886b..b2e9c27 100644 --- a/src/lib/ToastProvider.tsx +++ b/src/lib/ToastProvider.tsx @@ -4,7 +4,6 @@ import 'react-toastify/dist/ReactToastify.css'; function ToastProvider({ children }: any) { let What_the_language = localStorage.getItem('language') ?? "en"; - console.log(What_the_language); return ( <> diff --git a/src/lib/state mangment/AuthState.ts b/src/lib/state mangment/AuthState.ts index 310a3ee..b2bd147 100644 --- a/src/lib/state mangment/AuthState.ts +++ b/src/lib/state mangment/AuthState.ts @@ -1,4 +1,4 @@ -import create from 'zustand'; +import {create} from 'zustand'; import { TOKEN_KEY, TOKEN_KEY_SOCKET, USER_KEY } from '../../config/AppKey'; interface LoginResponse { diff --git a/src/translate/ar.json b/src/translate/ar.json index e34e575..1876f3b 100644 --- a/src/translate/ar.json +++ b/src/translate/ar.json @@ -1,964 +1,113 @@ { "Ar": "عربي", "En": "انكليزي", - "Arabic":"عربي", -"English":"إنجليزي", -"Login":"تسجيل الدخول", -"Welcome back, please login to your account.":"مرحبًا بك مرة أخرى ، يرجى تسجيل الدخول إلى حسابك.", -"Username":"اسم المستخدم", -"Password":"كلمة المرور", -"Sign in":"تسجيل الدخول", -"SDNone © 2022 | All Rights Reserved":"SDNone © 2022 |كل الحقوق محفوظة", -"unknown":"مجهول", -"super admin":"مشرف سوبر", -"admin":"مسؤل", -"Home":"الصفحة الرئيسية", -"example":"مثال", -"Log Out" : "تسجيل خروج" , -"Example":"مثال", -"Add":"اضافة", -"username":"اسم ", -"password":"كلمة المرور ", -"name":"اسم", -"email":"الحساب", -"cancel":"الغاء", -"edit":"تعديل", -"light":"وضع النهاري", -"dark":"وضع اليلي", -"delete_are_you_sure":"هل انت متاكد تريد الحذف ", -"no_revert":"لايوجد عودة", -"yes_delete_it":"نعم احذفها", -"":"", -"brand_name": "السمكري", -"dashboard": "لوحة التحكم", -"accounts": "الحسابات", -"users": "المستخدمين", -"view_accounts": "عرض الحسابات", -"add_account": "إضافة حساب", -"edit_account": "تعديل الحساب", -"add": "إضافة", -"save": "حفظ", -"all": "الكل", -"viewer": "مشاهد", -"vendor": "وكيل", -"super-admin": "سوبر أدمن", -"client": "الزبون", -"full_name": "الاسم", -"role": "الدور", -"phone": "رقم الهاتف", -"optional": "اختياري", -"account_image": "صورة الحساب", -"image_preview": "عرض الصورة", -"confirm_password": "تأكيد كلمة المرور", -"permissions": "الصلاحيات", -"_permissions": { - "viewer": "صلاحيات المشاهد", - "vendor": "صلاحيات الوكيل", - "admin": "صلاحيات الأدمن", - "super-admin": "صلاحيات السوبر أدمن" -}, -"image": "الصورة", -"brands": "العلامات التجارية", -"sort": "الترتيب", -"brand_points": "نقاط العلامة التجارية", -"categories_count": "عدد الأقسام الرئيسية", -"status": "الحالة", -"active": "فعال", -"inactive": "غير فعال", -"brand_name_field": "اسم العلامة التجارية", -"en": "انجليزي", -"ar": "عربي", -"brand_sort": "ترتيب العلامة التجارية", -"brand_image": "صورة العلامة التجارية", -"deliver":"توصيل", - -"comming_soon":"قريباََ", - -"add_brand": "إضافة علامة تجارية", -"edit_brand": "تعديل علامة تجارية", -"categories": "الأقسام الرئيسية", -"brand": "العلامة التجارية", -"subcategories_count": "عدد الأقسام الفرعية", -"category_name": "اسم القسم الرئيسي", -"add_category": "إضافة قسم رئيسي", -"edit_category": "تعديل قسم رئيسي", -"subcategories": "الأقسام الفرعية", -"subsubcategories": "الأقسام الفرعية للأقسام الفرعية", -"category": "القسم الرئيسي", -"category_image": "صورة القسم الرئيسي", -"category_images": "صور القسم الرئيسي", -"category_main_image": "صورة القسم الرئيسي الاساسية", -"category_sub_image": "صورة القسم الرئيسي الفرعية", -"category_main_description": "وصف القسم الرئيسي الاساسة", -"category_sub_description": "وصف القسم الرئيسي الفرعة", -"category_main_title": "عنوان القسم الرئيسي الاساسة", -"category_sub_title": "عنوان القسم الرئيسي الفرعي", -"Category_is_required": "القسم الرئيسي مطلوب", -"view_category": "اظهار العنصر الرئيسي", -"products_count": "عدد المنتجات", -"add_subcategory": "إضافة قسم فرعي", -"edit_subcategory": "تعديل القسم الفرعي", -"subcategory_name": "اسم القسم الفرعي", -"subcategory_image": "صورة القسم الفرعي", -"add_subsubcategory": "إضافة قسم فرعي للقسم الفرعي", -"edit_subsubcategory": "تعديل القسم الفرعي للقسم الفرعي", -"subsubcategory_name": "اسم القسم الفرعي للقسم الفرعي", -"subsubcategory_image": "صورة القسم الفرعي للقسم الفرعي", -"settings": "الإعدادات", -"general_settings": "الإعدادات العامة", -"fax": "فاكس", -"office_hours": "ساعات العمل", -"address_1": "العنوان الأول", -"address_2": "العنوان الثاني", -"address_3": "العنوان الثالث", -"conditions": "الشروط والأحكام", -"privacy": "شروط الخصوصية", -"transactions": "الحوالات", -"send_points": "إرسال نقاط", -"select_recievers": "اختر المستقبلين", -"confirm_send_points": "تأكيد إرسال النقاط", -"amount": "الكمية", -"total_amount": "الكمية الكلية", -"number_of_recievers": "عدد المستقبلين", -"send": "إرسال", -"rows": "أسطر", -"view_transaction": "عرض حوالة", -"view_all": "عرض الكل", -"pending": "قيد الانتظار", -"pending_payment":"غير مدفوع", -"on_going":"جاري الان", -"rejected":"مرفوض", -"reject":"رفض", -"accepted":"مقبول", -"pend":"تعليق", -"done": "منتهي", -"canceled": "ملغي", -"delivered": "تم توصيل الطلب", -"delivering": "يتم توصيل الطلب", -"code": "الرمز", -"sender_name": "اسم المرسل", -"sender_phone_number": "رقم المرسل", -"sender_role": "دور المرسل", -"points": "النقاط", -"accept": "قبول", -"transaction_code": "رمز الحوالة", -"enter_transaction_code": "الرجاء إدخال رمز الحوالة", -"search": "بحث", -"transaction_not_found": "لا توجد حوالة", -"date": "التاريخ", -"number_of_receivers": "عدد المستقبلين", -"total_points": "عدد النقاط الكلية", -"receivers": "المستقبلين", -"receiver_name": "اسم المستقبل", -"receiver_phone_number": "رقم المستقبل", -"receiver_email": "بريد المستقبل", -"receiver_role": "دور المستقبل", -"confirm_transaction": "تأكيد الحوالة", -"confirm_transaction_message": "هل أنت متأكد أنك تريد قبول الحوالة؟", -"no": "كلا", -"yes": "نعم", -"cancel_transaction": "إلغاء الحوالة", -"cancel_transaction_message": "هل أنت متأكد أنك تريد إلغاء الحوالة؟", -"contact_info": "معلومات التواصل", -"addresses": "العناوين", -"terms_&_conditions": "الشروط والأحكام", -"advertisements": "الإعلانات", -"mobile_image": "صورة الموبايل", -"title": "العنوان", -"default_advertisements": "الإعلانات العادية", -"custom_advertisement": "الإعلانات المخصصة", -"custom_with_btn_advertisements": "مع الزر", -"custom_without_btn_advertisements": "بدون الزر", -"large_image": "الصورة الكبيرة", -"link": "الرابط", -"please_fill_out_this_feild": "الرجاء ملئ العنصر", -"add_ad": "إضافة إعلان ", -"edit_ad": "تعديل إعلان ", -"discounts": "الخصومات", -"button": "الزر", -"description": "الوصف", -"button_description": "وصف الزر", -"products": "المنتجات", -"add_product": "إضافة منتج", -"view_all_products": "عرض كافة المنتجات", -"basic_info": "المعلومات الأساسية", -"selection": "الاختيارات", -"product_details": "تفاصيل المنتج", -"additional_images": "الصور الإضافية", -"product_name": "اسم المنتج", -"product_description": "وصف المنتج", -"product_mobile_description": "وصف المنتج الخاص بالموبايل", -"subcategory": "القسم الفرعي", -"subsubcategory": "القسم الفرعي للقسم الفرعي", -"view_product": " إظهار المنتج", -"product_price": "سعر المنتج", -"product_quantity": "كمية المنتج", -"product_main_image": "صورة المنتج الرئيسية", -"product_video_link": "رابط الفيديو الخاص بالمنتج", -"product_sort": "ترتيب المنتج", -"is_active": "فعال", -"is_most_purchase":"الأكثر شراء", -"is_latest":"الأحدث", -"is_highlight": "مميز", -"price": "السعر", -"price_after_discount": "السعر بعد الحسم", -"product": "المنتج", -"no_images": "لا يوجد صور", -"add_new_images": "إضافة صور جديدة", -"delete": "حذف", -"image_sort": "ترتيب الصورة", -"offers": "العروض", -"add_offer": "إضافة عرض", -"view_all_offers": "كافة العروض", -"offer_start_at": "تاريخ بدء العرض", -"offer_end_at": "تاريخ انتهاء العرض", -"offer_details": "تفاصيل العرض", -"offer_name": "اسم العرض", -"offer_description": "وصف العرض", -"offer_note": "ملاحظة عن العرض", -"offer_mobile_description": "وصف العرض الخاص بالموبايل", -"offer_price_in_points": "سعر العرض مقابل النقاط", -"offer_video_link": "رابط الفيديو الخاص بالعرض", -"offer_sort": "ترتيب العرض", -"offer_main_image": "صور العرض الرئيسية", -"offer": "العرض", -"loading": "جار التحميل...", -"_loading": { - "delete": "جار الحذف..." -}, -"login_again": "الرجاء إعادة تسجيل الدخول بالمعلومات الجديدة", -"login": "تسجيل الدخول", -"welcome_login": "أهلاً بك، الرجاء تسجيل الدخول إلى حسابك", -"fill_fields": "الرجاء ملئ كافة الحقول", -"logout": "تسجيل الخروج", - -"home": "الصفحة الرئيسية", -"welcome_to_dashboard": "مرحبا بك في لوحة التحكم!", -"order_offers": "طلبات شراء العروض", -"orders": "الطلبات", -"orders_to_export":"الطلبات التي تريد تصديرها ", -"from":"من", -"to":"إلى", -"print_order":"طباعة الطلب", -"view_order_offer": "عرض طلب الشراء", -"client_phone": "رقم الزبون", -"client_image": "صورة الزبون", -"client_link": "الرابط الخاص بالزبون", -"client_email": "بريد الزبون", -"client_full_name": "اسم الزبون الكامل", -"offer_code": "رمز الطلب", -"offer_order_not_found": "لم يتم العثور على الطلب", -"enter_offer_code": "الرجاء إدخال رمز الطلب", -"confirm_offer_order": "تأكيد الطلب", -"confirm_offer_order_message": "هل أنت متأكد أنك تريد قبول الطلب؟", -"cancel_offer_order": "إلغاء الطلب", -"cancel_offer_order_message": "هل أنت متأكد أنك تريد إلغاء الطلب؟", -"clients": "زبائننا", -"edit_client": "تعديل الزبون", -"is_verified": "تم التحقق منه", -"change_password": "تغيير كلمة المرور", -"no_records": "لا يوجد أية بيانات", -"failed_to_get_data": "حدث خطأ أثناء جلب البيانات", -"added_successfully": "تمت الإضافة بنجاح", -"failed_to_add_data": "حدث خطأ أثناء إضافة البيانات", -"updated_successfully": "تم التعديل بنجاح", -"failed_to_update_data": "حدث خطأ أثناء تعديل البيانات", -"deleted_successfully": "تم الحذف بنجاح", -"failed_to_delete_data": "حدث خطأ أثناء حذف البيانات", -"toggle_success": "تم تغيير الحالة بنجاح", -"toggle_failed": "حدث خطأ أثناء تغيير الحالة", -"back": "العودة", -"password_must_match": "كلمة السر يجب ان تتطابق", -"gallery": "المعرض", -"add_gallery_item": "إضافة عنصر للمعرض", -"update_gallery_item": "التعديل على عنصر في المعرض", -"social_media": "وسائل التواصل الاجتماعية", -"add_social_media": "إضافة وسيلة تواصل إجتماعية", -"edit_social_media": "تعديل وسيلة تواصل إجتماعية", -"social_media_image": "صورة وسيلة التواصل الاجتماعية", -"social_media_link": "رابط وسيلة التواصل الاجتماعية", -"information": "المعلومات", -"vision_description": "وصف الرؤية", -"mission_description": "وصف المهمة", -"privacy_description": "وصف الخصوصية", -"conditions_description": "وصف الشروط", -"vision_image": "صورة الرؤية", -"mission_image": "صورة المهمة", -"footer": "شريط المعلومات السفلي", -"update_footer": "تعديل شريط المعلومات السفلي", -"address": "العوان", -"messages": "الرسائل", -"upload_image":"تحميل صورة", -"view_message": "اظهار تفاصيل الرسالة", -"categories_views": "مشاهدات الاقسام الرئيسية", -"descktop_visitors": "الزوار من الحاسوب", -"mobile_visitors": "الزوار من الموبايل", -"all_visitors": "جميع الزوار", -"monthly_visitors": "عدد الزوار في الشهر", -"daily_visitors": "عدد الزوار في اليوم", -"yearly_visitors": "عدد الزوار في السنة", -"weekly_visitors": "عدد الزوار في الاسبوع", -"yearly_visitors_over_month": "الزوار في السنة ضمن الأشهر", -"active_categories_count": " عدد الاقسام الرئيسية", -"active_products_count": "عدد المنتجات", -"visitors": "عدد الزوار", -"search_for_categories": "البحث في الاقسام الرئيسية", -"search_for_sub_categories": "البحث في الاقسام الفرعيه", -"search_for_products": "البحث في المنتجات", -"search_for_messages": "البحث في الرسائل", -"search_for_accounts": "البحث في الحسابات", -"my_account": "حسابي", -"add_client": "إضافة زبون", -"services_count": "عدد الخدمات", -"team_members": "أعضاء الفريق", -"add_team_member": "إضافة عضو فريق", -"edit_team_member": "تعديل بيانات عضو الفريق", -"member_name": "اسم عضو الفريق", -"member_image": "صورة عضو الفريق", -"facebook_link": "رابط الفيسبوك", -"linkedin_link": "رابط لينكد ان", -"instgram_link": "رابط انستغرام", -"awards": "الجوائز", -"awards_description": "وصف الجوائز", -"awards_image": "صورة الجوائز", -"about_us": "من نحن", -"about_us_description": "وصف فقرة من نحن", -"about_us_image": "صورة فقرة من نحن", -"ceo_message": "رسالة المدير التنفيذي", -"company_info": "معلومات الشركة", -"test": "تيست", -"services_views": "عدد مشاهدات الخدمات", -"home_videos": "فيديوهات الصفحة الرئيسية", -"large_screens": "الشاشات الكبيرة", -"mobile_screens": "شاشات الموبايل", -"main_video": "الفيديو الرئيسي", -"sub_video": "الفيديو الفرعي", -"main_video_title": "عنوان الفيديو الرئيسي", -"sub_video_title": "عنوان الفيديو الفرعي", -"home_main_video": "الفيديو الرئيسي", -"home_sub_video": "الفيديو الفرعي", -"discount_name": "اسم الخصم", -"discount_rate": "نسبة الخصم", -"start_at": "تاريخ البداية", -"end_at": "تاريخ النهاية", -"add_discount": "إضافة خصم", -"edit_discount": "تعديل خصم", -"is_discount_date_active": "صلاحية وقت الخصم", -"currencies": "العملات", -"currency_name": "اسم العملة", -"currency_code": "رمز العملة", -"currency_rate": "نسبة العملة", -"add_currency": "إضافة عملة", -"edit_currency": "تعديل عملة", -"default_currency": "العملة الافتراضية", -"currency": "عملة", -"rate":"النسبة", -"shops": "المتاجر", -"add_shop": "إضافة متجر", -"edit_shop": "تعديل متجر", -"shop_name": "اسم المتجر", -"shop_description": "وصف المتجر", -"shop_mobile_description": "وصف المتجر الخاص بالموبايل", -"shop_image": "صورة المتجر", -"test2":"تيست", - -"auctions":"المزادات", -"edit_auction":"التعديل على المزاد", -"auction_status":"حالة المزاد", -"auction_details":"معلومات المزاد", -"auction_description":"وصف المزاد", -"auction_name":"اسم المزاد", -"auction_mobile_description":"وصف المزاد في الموبايل", -"auction_main_image":"صورة المزاد الرئيسية", -"auction_sort":"ترتيب المزاد", -"add_auction":"إضافة مزاد", -"starting_price":"السعر الإبتدائي", -"auction_order_status":"حالة طلب المزاد", - -"auctions_orders":"طلبات المزادات", -"add_auction_order":"إضافة طلب مزاد", -"edit_auction_order":"التعديل على طلب المزاد", -"customer_address":"عنوان الزبون", -"customer_zone_number":"رقم منطقة الزبون", -"payment_id":"رمز عملية الدفع", -"payment_getaway_status":"حالة عملية الدفع", -"busy":"مشغول", -"available":"متاح", - -"customer_info":"معلومات الزبون", -"auction_order_details":"تفاصيل طلب المزاد", -"cutomer_number":"رقم الزبون", -"auction_order_code":"رمز طلب المزاد", -"auction_order_total":"السعر الكلي للطلب", -"auction_order_price":"سعر طلب المزاد", -"select_user":"اختر الزبون", -"change_user":"تغيير الزبون", -"search_for_user":"البحث عن زبون", - - -"customer_address_country": "البلد", -"customer_address_city": "المديتة", -"customer_address_street": "الشارع", -"customer_address_building_number": "رقم البناء", -"customer_address_additional_information": "معلومات إضافية", -"customer_email": "البريد الاإلكتروني للزبون", -"payment_method": "طريقة الدفع", -"payment_code": "رمز عملية الدفع", - -"employee_name":"اسم الموظف", -"employee_phone":"رقم الموظف", -"employee_id":"رمز الموظف", -"employee_status":"حالة الموظف", -"employee_orders":"طلبات الموظف", -"employee_wallet":"محفظة الموظف", -"delivery":"توصيل", -"employee_image":"صورة الموظف", -"employee_password":"كلمة سر الموظف", -"employee_password_confirmation":"تأكيد كلمة سر الموظف", -"delivery_employee_information":"معلومات موظف التوصيل", -"add_delivery_employee":"إضافة موظف توصيل", -"old_password":"كلمة السر القديمة", -"not_delivered_yet":"لم يتم توصيله بعد", -"not_pickuped_yet":"لم يتم استلامه بعد", -"vendor_orders":"طلبات الوكلاء", - - -"latest_orders": "اخر الطلبات", -"show_all_orders": "عرض جميع الطلبات", -"latest_users": "اخر الزوار", -"show_all_users": "عرض جميع الزوار", - - -"size_name":"اسم الحجم", - - - -"comments_and_reviews":"التعليقات والتقييمات", -"comments":"التعليقات", -"comment":"التعليق", -"reviews":"التقييمات", -"change_review_status":"تغيير حالة التقييم", -"review_status":"حالة التقييم", -"review_description":"تفاصيل التقييم", -"review_stars":"نجوم التقييم", -"showed":"ظاهر", -"hidden":"مخفي", - -"all_shops":"كل المتاجر", -"shop_categories":"الأقسام الرئيسية للمتجر", -"add_shop_category":"إضافة فئة رئيسية للمنتح", -"shop_subCategories":"الأقسام الفرعية للمتجر", -"owner_products": "منتجات المالك", -"owner_product": "منتج المالك", -"shops_products": "منتجات المتاجر", -"shop_product": "منتج المتجر", -"shop": "المتجر", -"quantity": "الكمية", -"please_select_a_shop": "الرجاء اختيار متجر", -"please_select_vendor": "الرجاء اختيار وكيل", -"edit_product": "تعديل المنتج", - -"products_colors":"ألوان المنتجات", -"color_name":"اسم اللون ", -"color_image":"صورة اللون ", -"add_color":"إضافة لون", -"add_new_color":"إضافة لون جديد", -"edit_color":"تعديل لون", -"colors":"الألوان", - -"delivery_fee":"قيمة التوصيل", -"please_select_shop":"الرجاء اختيار متجر", -"type_your_message":"اكتب رسالتك ...", - -"shop_category_name":"اسم القسم الرئيسي للمتجر", -"please_select_shop_first":"الرجاء اختيار متجر اولاََ", -"no_shops":"لايوجد متاجر", - -"shop_subcategories":"الأقسام الفرعية للمتجر", -"shop_subcategory_name":"اسم القسم الفرعي التابع للمتجر", -"add_shop_subcategory":"إضافة قسم فرعي لمتجر", -"edit_shop_subcategory":"تعديل قسم فرقي لمتجر", -"shop_category":"القسم الرئيسي للمتجر", -"shop_subcategory":"القسم الفرعي للمتجر", - -"live_stream":"بث مباشر", - -"sizes":"الحجوم", -"product_variation":"", -"add_size":"إضافة حجم", -"add_new_size":"إضافة حجم جديد", -"edit_size":"تعديل حجم", -"products_sizes":"احجام المنتجات", -"sizes&colors":"الألوان والحجوم", -"no_size_chosen":"لم يتم اختيار حجم", -"no_color_chosen":"لم يتم اختيار لون", - -"order_code": "رمز العرض", -"order_created_at":"أنشئ الطلب في", -"customer_name": "اسم الزبون", -"customer_phone_number": "رقم الزبون", -"order_status": "حالة الطلب", -"payment_status": "حالة الدفع", -"paid":"مدفوع", -"unpaid":"غير مدفوع", -"order_total": "سعر الطلب ", -"cash_on_delivery":"الدفع عند التوصيل", -"stripe":"سترايب", -"totals": "المجموع", -"sub_total": "المجموع الجزئي", -"tax_total": "مجموع الضرائب", -"overall_total": "المجموع الكلي", - -"delivery_employees":"موظفي التوصيل", - -"welcome_message": "مرحباً بك في لوحة التحكم الخاصة بمزاد النخبة", -"statistics": "الإحصائيات", -"google_analytics": "إحصائيات غوغل", -"signin_via_google": "تسجيل الدخول عبر غوغل", -"open_google_dashboard": "فتح إحصاءات غوغل", -"google_analytics_instructions": "يمكنك تسجيل الدخول عبر حساب غوغل الخاص بالإحصاءات لعرض الإحصاءات في هذه الصفحة، أو يمكنك الذهاب إلى لوحة الإحصاءات الخاصة بغوغل", -"err_occured": "حدث خطأ ما الرجاء إعادة المحاولة", - - -"discount": "الحسم", -"no_discount": "لايوجد حسم", -"view": "عرض", - - -"export":"تصدير", - -"_currency":{ - "update_are_you_sure":"هل انت متأكد من تغيير العملة الافتراضية", - "yes_update_it":"نعم", - "cancel":"إلغاء", - "body":"في حال تغيير العملة ستتغير في جميع المنتجات" -}, - -"_active": { - "products_count": "المنتجات المفعلة", - "orders_count": "الطلبات", - "categories_count": "الأقسام الرئيسية المفعلة", - "shops_count": "المتاجر", - "users_count":"عدد المستخدمين" -}, - -"_search": { - "category": "ابحث عن قسم رئيسي", - "subcategory": "ابحث عن قسم فرعي", - "product": "ابحث عن منتج", - "employee":"ابحث عن موظف", - "shop": "ابحث عن متجر", - "team_member": "ابحث عن عضو فريق", - "order": "ابحث عن طلب", - "vendor":"البحث عن وكيل", - "color":"البحث عن لون", - "size":"البحث عن حجم", - "customer_products":"البحث على منتجات الزبون" -}, -"new": { - "password": "كلمة المرور الجديدة", - "confirm_password": "تأكيد كلمة المرور الجديدة" -}, -"required": "هذا الحقل مطلوب", -"_required": { - "link": "الرجاء إدخال الرابط", - "password": "كلمة المرور مطلوبة", - "email": "حقل البريد الإلكتروني مطلوب", - "member_name": "اسم عضو الفريق مطلوب", - "member_image": "صورة عضو الفريق مطلوبة", - "name": "الإسم مطلوب", - "phone": "رقم الهاتف مطلوب", - "discount_name": "اسم الخصم مطلوب", - "start_at": "تاريخ البداية مطلوب", - "end_at": "تاريخ النهاية مطلوب", - "discount_rate": "نسبة الخصم مطلوبة", - "is_discount_date_active": "صلاحية وقت الخصم مطلوبة", - "currency_name": "اسم العملة مطلوب", - "currency_code": "رمز العملة مطلوب", - "currency_rate": "نسبة العملة مطلوبة" -}, -"validation": { - "link": "الرجاء إدخال رابط صحيح", - "passwords_match": "يجب أن تتطابق كلمات السر", - "invalid_email": "البريد الإلكتروني غير صحيح", - "invalid_name": "الاسم غير صحيح", - "invalid_phone": "الرقم غير صحيح", - "confirm_password": "كلمة السر يجب ان تتطابق", - "min_number": "الرقم يجب ان يكون بين الواحد والمئة", - "max_number": "الرقم يجب ان يكون بين الواحد والمئة", - "size_and_color":"يجب اختيار اللون او الحجم" -}, -"lang_1": "انكليزي", -"lang_2": "عربي", -"_messages": { - "success": { - "upload": "تم الرفع ينجاح" - }, - "error": { - "upload": "حدث خطأ أثناء عملية الرفع" - } -}, -"you_are_not_authorized": "غير مصرح لك بالدخول إلى الصفحة", -"page_not_found": "لم يتم العثور على الصفحة", -"an_error_occured": "حدث خطأ ما", - -"_not_found": { - "product": "لم يتم العثور على المنتج" -}, -"customer_products":"منتجات الزبائن", -"change_product_status":"تغير حالة المنتجات الى ", -"customer_product_information":"معلومات منتج الزبون", -"pendding":"معلق", -"product_category":"صنف المنتج", -"customer_id_number":"رقم تعريف الزبون", -"customer":"زبون", -"rejected_cause":"سبب الرفض", -"(rejected)":"(مرفوض)", -"number_of_day_show":"عدد الايام العرض", -"(successful)":"(مقبول)", -"product_subcategory":"الاقسام الفرعية للمنتج", -"product_subsubcategory":"قسم فرعي للاقسام فرعية للمنتج", -"date_is_smaller_than_now":"التاريخ اقل من وقت حالي ", -"change_status":"تغير الحالة الى ", -"add_branch":"اضافة قسم ", -"view_branch":"عرض افرع المتجر", -"branch_name":"اسم الفرع ", -"zone_number":"رقم المنطقة", -"building_number":"رقم البناء", -"street":"الشارع", -"floor_number":"رقم الطابق", -"view_branchs":"عرض افرع المتجر", -"enter_city":"ادخل المنطقة" , -"location_name":"اسم الموقع" , -"edit_branch":"تعديل الفرع", -"start_point":"نقطة البداية", -"delivary_by":"توصيل بواسطة" , -"please_add_at_least_one_branch":"الرجاء إضافة فرع واحد على الأقل", -"special_delivery_fee":"رسوم التوصيل الخاصة", -"notification":"اشعارات", -"add_notification":"اضافة اشعار ", -"notification_body":"المحتوى", -"notification_title":"العنوان", -"body":"المحتوى", -"created_at":"تاريخ الانشاء", -"payment":"الدفع ", -"cash":"نقود", -"online":"عن بعد", -"category_products":"منتجات الاقسام", -"km_price":"سعر الكيلومتر ", -"auction_enrollments":"التسجيلات في المزاد", -"front_personal_identity_image":"صورة الهوية الشخصية الامامية", -"back_personal_identity_image":"صورة الهوية الشخصية الخلفية", -"general_delivery_fee":"قيمة التوصيل العامة", -"auction_qatar_fee":"قيمة توصيل مزادات الى قطر", -"product_image":"صورة المنتج", -"ending_price":"سعر التوقف", -"additional_time":"الوقت المضاف بعد المزايدة (بالدقائق)", -"increase_amount":"كمية الزيادة", -"profit_percentage":"نسبة الربح ", -"insurance_amount":"مبلغ التأميني", -"bank_commission":"عمولة البنك ", -"sub_vendor":"وكيل الفرعي ", -"version_mobile":"نسخة الجوال", -"photo_settings":"صور التطبيق " , -"photo" :"الصور", -"is_ads" :"اعلان؟" , -"for_shop":"الى متجر ", -"change_to":"تغيير الى ", -"change":"تغيير", -"type":"النوع ", -"leave_it_empty_to_not_ability_for_clicked":"اتركه فارغًا لتعطيل النقر عليه", -"null":"فارغ ", -"file":"ملف", -"preview":"عرض", -"note":"ملاحظة", -"select_sub":"اختر قسم فرعي رجائا", -"select_shop":"اختر متجر رجائا", -"note : leave the date empty to fill now":"ملاحظة : اترك حقل فارغا لتعبئته ب تاريخ اليوم ", -"other":"اخر", -"ios_link":"رابط Ios", -"android_link":"رابط Android", -"Error in export orders":"حدث خطأ أثناء عملية تصدير الطلبات ", -"Error in subcategory orders export":"حدث خطأ أثناء تصدير طلبات القسم الفرعي ", -"Error in shop orders export":"حدث خطأ أثناء تصدير طلبات المتجر", -"from_date" :"تاريخ البداية", -"to_date":"تاريخ النهاية", -"order_value":"قيمة الطلب ", -"get_orders_rewards":"جلب طلبات للمكافئة", -"get_resulte":"جلب النتائج", -"rewards":"الجوائز", - - - - -"phone_verfication":"توثيق الهاتف ", - -"app_setting":"إعدادات التطبيق" , -"add_setting":"اضافة اعدادات", -"setting_name":"اسم الإعدادات", -"edit_setting":"تعديل الإعدادات", -"value":"القيمة", -"Code":"قسيمات الشراء" , -"Wallets":"المحفظة", -"Transaction":"التحويلات", -"user_management":"ادارة المستخدم", -"drivers":"السائقين", -"customers":"الزبائن", -"pos":"مركز الخدمة ", -"add_code":"اضافة قسيمة ", -"code_number":"عدد القسيمات" , -"order":"طلبات", -"driver_name":"اسم السائق", -"address_from":"عنوان البداية", -"address_to":"عنوان النهاية", -"paid_type":"طريقة الدفع ", -"money_of_customer":"اموال الزبون", -"is_paid":"مدفوع", -"select_driver":"اختر سائق", -"select":"اختار", -"select_customer":"اختر زبون", -"name_driver_selected":"اسم السائق الذي تم اختياره", -"name_customer_selected":"اسم الزبون الذي تم اختياره", -"enter_button_select":"اكبس على زر اختيار لملا الحقل", -"add_customer":"اضافة زبون ", -"customer_image":"صورة الزبون", -"edit_cusotmer":"تعديل زبون ", -"driver_id_number":"رقم تعريف السائق", -"id_number":"رقم التعريف", -"car_type":"نوع السيارة", -"customer_information":"معلومات الزبون", -"customer_details":"تفاصيل الزبون", -"driver_order":"طلبات السائق ", -"driver_information":"معلومات السائق", -"gift":"هدايا", -"gift_to":"هدية الى", -"add_gift":"اضافة هدية", -"draiver_date_of_birith":"عيد ميلاد السائق", -"gender":"جنس", -"car_color":"لون السيارة", -"car_model":"طراز السيارة", -"car_seats_number":"عدد مقاعد السيارة ", -"car_back_side":"الجانب الخلفي للسيارة", -"car_front_side":"الجانب الامامي للسيارة", -"car_right_side":"جانب السيارة الايمن ", -"car_left_side":"جانب السيارة الايسر", -"car_internal_front_side":"الجانب الأمامي الداخلي للسيارة", -"car_internal_back_side":"الجانب الخلفي الداخلي للسيارة", -"driver_license_number":"رقم رخصة القيادة", -"driver_license_info":"معلومات رخصة القيادة", -"additional_car_info":"معلومات السيارة الإضافية", -"additional_driver_info":"معلومات إضافية للسائق", -"driver_nationality_id":"رقم الوطني للسائق", -"driver_residential_card_number":"رقم بطاقة سكن السائق", -"driver_residential_card_image":"صورة بطاقة سكن السائق", -"driver_yearly_image_front":"صورة اجازة تسجيل سيارة الامامية", -"driver_yearly_image_back":"صورة اجازة تسجيل سيارة الخلفية", -"driver_nationality_image_back":"صورة جنسية السائق الخلفية ", -"driver_nationality_image_front":"صورة جنسية السائق الامامية", -"driver_license_back_image":"صورة رخصة القيادة الامامية", -"driver_license_front_image":"صورة رخصة القيادة الخلفية", -"driver_yearly_id":"معرف سائق سنوي", -"latest_customer":"اخر الزبائن", -"latest_driver":"اخر السائقين", -"show_all_customer":"عرض كل الزبائن", -"show_all_driver":"عرض كل السائقين", -"enter_notification":"ادخل تنبيه", -"send_notification":"ارسال تنبيه", -"driver_block_page":"صفحة حظر السائق", -"blocking_driver":"حظر السائق", -"number_of_day_blocking":"عدد ايام الحظر", -"add_block_for_user":"حظر الزبون", -"block_time_remaining":"عدد ايام حظر المتبقي", -"driver_code":"رمز السائق" , -"city":"المدينة" , -"driver_image":"صورة السائق", -"driver_phone":"رقم السائق", -"customer_code":"رمز الزبون", -"end_point":"نقطة النهاية", -"final_price":"السعر النهائي", -"start_time_trip":" وقت بداية الرحلة", -"end_time_trip":"وقت نهاية الرحلة", -"driver_rate":"تقيم طلبات السائقين", -"unacceptable_order":"طلبات غير مقبولين", -"content":"المحتوى", -"reason": "السبب", -"driver":"السائق", -"person_from":"الشخص المرسل", -"person_to":"الشخص المستقبل", -"transaction_date":"تاريخ التحويل", -"Type From":"نوع المرسل", -"Type To":"نوع المستقبل", -"schedule":"مجدول", -"Order Type":"نوع الطلب", -"wallet":"المحفظة", -"blocking_customer":"حظر المستخدم", -"customer_block_page":"صفحة حظر المستخدن", -"date_blocking":"تاريخ الحظر", -"enter_code":"ادخل قسيمة", -"driver_gift_page":"صفحة اهداء السائق", -"customer_gift_page":"صفحة اهداء الزبون", -"give":"اعطاء", -"blocked":"محظور", -"unblocked":"غير محظور", -"customer_wallet":"محفظة االزبون", -"customer_city":"مدينة ", -"customer_phone":"الرقم", -"driver_birthday":"تاريخ ولادة السائق", -"driver_gender":"الجنس", -"driver_wallet":"المحفظة", -"car_front_side_image":"صورة السيارة الامامية", -"car_internal_back_side_image":"صورة الداخلية في الجزء الخلفي للسيارة ", -"car_internal_front_side_image":"صورة الداخلية في الجزء الامامي للسيارة ", -"car_right_side_image":" صورة السيارة اليمينية", -"car_left_side_image":"صورة السيارة اليسارية", -"car_back_side_image":"صورة السيارة الخلفية", -"driver_order_rate":"تقيم سائق الطلب", -"trip_information":"معلومات الرحلة", -"personal_information":"معلومات الشخصية", -"User_in_your_Application" :"مستخدم في التطبيق .", -"Driver_in_your_Application":"سائق في التطبيق .", -"Order_in_your_Application":"طلب في التطبيق .", -"You_have":"لديك", -"send_to":"ارسال الى", -"notification_form":"لوحة الاشعارات", -"multi":"متعدد", -"start":"في رحلة", -"order_information":"معلومات الطلب", -"complete":"وصول", -"offline":"غير متصل", -"busiest_drivers":"السائقين الاكثر انشغالا", -"un_blocking_customer":"فك الحظر المستخدم", -"un_customer_block_page":"صفحة فك حظر المستخدم", -"un_block_for_customer":"فك الحظر على المستخدم", -"un_blocking_driver":"فك حظر السائق", -"un_driver_block_page":"صفحة فك حظر السائق ", -"un_block_for_driver":"فك حظر السائق", -"add_block_for_driver":"حظر السائق", -"unavailable":"غير متاح", -"used":"متاح", -"unused":"غير متاح", -"select_permission":"اختر اذن ", -"role_name":"اسم الدور", -"number_permissions":"عدد الصلاحيات", -"add_role":"اضافة دور", -"print":"طباعة", -"add_to_wallet":"اضافة الى الحافظة", -"setting_name_precent":"اسم الاعدادت (بالنسبة المئوية)", -"precent":"بالنسبة المئوية", -"price_per_km":"سعر الكيلو متر الواحد", -"price_per_min":"سعر الدقيقة الواحدة", -"customer_profit_ratio":"نسبة ربح الزبون ", -"driver_profit_ratio":"نسبة ربح السائق ", -"driver_min_wallet":"اقل كمية ب محفظة السائق", -"Baghdad Governorate":"بغداد محافظة", -"Rusafa":"الرصافة", -"Adhamiyah":"الحمدانية", -"Thawra":"الصدر", -"9 Nissan":"9 نيسان ", -"Karadah":"الكرادة", -"Kadhimiyah":"الكاظمية", -"Mansour":"المنصور", -"Al Rashid":"الرشيد", -"Karkh":"الكرخ", -"relative_cost":"السعر التقريبي", -"The_cost_of_opening_the_door":"كلفة فتح الباب (اول قيمة يتم خصمها من الزبون) تضاف الى الكلفة", -"radius_of_the_circle_per_km":"نصف قطر الدئرة التي سيتم ارسال طلبات الزبائن الى السائقين الموجودين فيها (مقدراً بالكيلو متر)", -"time_to_cancel_order_per_m":"الوقت المحدد لإلغاء طلب السائق بعد تجاوزه (بالدقائق)", -"discount_customer_for_being_late":"الكلفة التي يجب ان تخصم من الراكب في حال تأخر عن السائق", -"waiting_time_befor_cancel":"الوقت الواجب على السائق انتظار الراكب حتى يستطيع الغاء الرحلة", -"radius_of_the_circle_befor_press_waiting_per_km":"اقرب مسافة لوصول السائق الى مكان الزبون (مقدرا ب كيلو متر)", -"driver_profit_when_cancel_order":"قيمة ربح السائق عند الغاء طلب من قبل الزبون ", -"canceled_by":"الغاء بواسطة ", -"sunday":"الأحد" , -"monday":"الإثنين" , -"tuesday":"الثلاثاء" , -"wednesday":"الأربعاء" , -"thursday":"الخميس" , -"friday":"الجمعة" , -"saturday":"السبت" , -"daily_order_over_week":"الطلبات اليومية على مدار الأسبوع", -"order_count":"عدد الطلبات ", -"daily_order":"الطلبات اليومية ", -"total_order_price":"مجموع اسعار الطلبات ", -"end_tripe_date":"تاريخ انتهاء الرحلة ", -"money_received":"المبلغ المستلم", -"order_price":"قيمة الطلب ", -"created_by":"انشئت من قبل" , -"high_drivers_rate":"اعلى السائقين تقيما", -"join_at":"سجل في ", -"user_name":"اسم المستخدم", -"user_phone":"رقم المستخدم", -"user_code":"رمز المستخدم", -"distance_per_km":"المسافة بالكيلومتر", -"time_per_m":"الوقت بالدقائق", -"is_percentage":"هل هي نسبة", -"account":"الحساب", -"daily_order_per_years":"الطلبات اليومية في السنوات", -"glass":"وضغ الزجاجي", -"in_active":"غير فعال" , -"Driver Order":"طلب السائق", -"Additional Driver Info":"برنامج تشغيل إضافي", -"Additional Car Info":"معلومات السيارة الإضافية", -"BasicInfo":"معلومات أساسية", -"car_seat_count":"عدد مقاعد السيارة", -"car_front":"أمام السيارة", - "car_right":"يمين السيارة", - "car_internal":"داخلية السيارة", - "car_back":"خلف السيارة", - "car_left":"يسار السيارة", - "car_internal_back":"داخلية خلف السيارة", - "order_info":"معلومات الطلب", - - - - "license_front_image":"صورة أمامية للرخصة", - "license_back":"صورة خلفية للرخصة", - "nationality_back":"صورة الجنسية الخلفية", - "yearly_back":"صورة اجازة تسجيل السيارة الخلفية", - "nationality_front":"صورة الجنسية الامامية", - "residential_card":"صورة بطاقة سكن السائق", - "yearly_front":"صورة اجازة تسجيل السيارة الامامية", - "View_information":"عرض المعلومات", - "number":"الرقم", - "Ops":"للأسف ", - "An Error According":"حدث خطأ", - "Please Try Again Later":"الرجاء المحاولة لاحقا", - "fav_trips":"الرحلات المفضلة", - "You Are Not Connected":"انت غير متصل", - "SocketDebug":"تصحيح مأخذ التوصيل", - "event":"حدث", - "room":"قناة", - "socket_id":"رمز المقبس", - "data":"البيانات", - "clear":"حذف", - "Socket Are Connected":"المقبس متصل", - "Socket Are Disconnected":"تم قطع الاتصال بالمقبس", - "add_block_for_":"حظر ", - "blocking_":"حظر ", - "_block_page":" ", - "al":"", - "_gift_page":"", - "un_block_page":"", - "un_blocking_":"فك حظر ", - "un_block_for_":"فك حظر ", - "Add Successful":"تم الوضع بنجاح", - "Has Accepte the Order":"قبل الطلب", - "open":"افتح", - "Driver Info":"معلومات السائق", - "Customer Info":"معلومات االزبون", - "driver order today":"طلبات السائق اليوم", - "driver order yesterday":"طلبات السائق اليوم الماضي", - "distance":"المسافة", - "Send Order To Nearst 5 Driver":"ارسل الطلب لاقرب 5 سائقين", - "one":"واحد" - - - - - - - - - + "Arabic": "عربي", + "English": "إنجليزي", + "German" : "ألمانية", + "Login": "تسجيل الدخول", + "Welcome back, please login to your account.": "مرحبًا بك مرة أخرى ، يرجى تسجيل الدخول إلى حسابك.", + "Username": "اسم المستخدم", + "Password": "كلمة المرور", + "Sign in": "تسجيل الدخول", + "Point © 2022 | All Rights Reserved": "Point © 2022 |كل الحقوق محفوظة", + "unknown": "مجهول", + "super admin": "مشرف سوبر", + "admin": "مسؤل", + "Home": "الصفحة الرئيسية", + "example": "مثال", + "Log Out": "تسجيل خروج", + "Example": "مثال", + "Add": "اضافة", + "username": "اسم ", + "password": "كلمة المرور ", + "name": "اسم", + "email": "الحساب", + "cancel": "الغاء", + "edit": "تعديل", + "light": "وضع النهاري", + "dark": "وضع اليلي", + "Categories": "الفئات", + "Products": "المنتجات", + "Order": "الطلب", + "Coupon": "القسيمة", + "Slider": "الشريحة", + "Product_in_your_Application": "المنتج في تطبيقك", + "categories_in_your_Application": "الفئات في تطبيقك", + "Order_in_your_Application": "الطلب في تطبيقك", + "You_have": "لديك", + "January": "يناير", + "February": "فبراير", + "March": "مارس", + "April": "أبريل", + "London": "لندن", + "Paris": "باريس", + "New York": "نيويورك", + "Seoul": "سيول", + "image": "صورة", + "parent_id": "الأب", + "product_count": "عدد المنتجات", + "basicinfo": "معلومات أساسية", + "view_information": "عرض المعلومات", + "back": "العودة", + "price": "السعر", + "description": "الوصف", + "favorite": "المفضلة", + "main_photo": "الصورة الرئيسية", + "category_id": " الفئة", + "order_code": "رمز الطلب", + "status": "الحالة", + "total": "المجموع", + "order_id": " الطلب", + "customer_name": "اسم العميل", + "customer_phone_number": "رقم هاتف العميل", + "order_created_at": "تم إنشاء الطلب في", + "address": "عنوان", + "country": "بلد", + "note": "ملاحظة", + "categories": "الفئات", + "coupon": "الفسيمة", + "orders": "الطلبات", + "products": "المنتجات", + "slider": "الشريحة", + "discount_type": "نوع الخصم", + "coupon_type": "نوع الكوبون", + "code": "الكود", + "coupon_value": "قيمة الكوبون", + "view_information_filed_fill_sucsessfully": "تم ملء حقل معلومات العرض بنجاح", + "category": "الفئة", + "View_information": "عرض المعلومات", + "VarianInfo": "معلومات المتغير", + "Base_info": "المعلومات الأساسية", + "name_ar": "الاسم بالعربية", + "name_en": "الاسم بالإنجليزية", + "name_de": "الاسم بالألمانية", + "description_ar": "الوصف بالعربية", + "description_en": "الوصف بالإنجليزية", + "description_de": "الوصف بالألمانية", + "upload_image": "تحميل الصورة", + "photo": "الصورة", + "admin_note": "ملاحظة الإدارة", + "state": "الحالة", + "title": "العنوان", + "totals": "المجموعات", + "delivery_fee": "رسوم التوصيل", + "overall_total": "المجموع الكلي", + "sub_total": "المجموع الفرعي", + "quantity": "الكمية", + "active_from_to": "النشاط من/إلى", + "maximum_number_of_uses": "الحد الأقصى لعدد الاستخدامات", + "minimum_total_to_order": "الحد الأدنى للإجمالي للطلب", + "maximum_number_of_uses_per_user": "الحد الأقصى لعدد الاستخدامات لكل مستخدم", + "product_item": "عنصر المنتج", + "categories_item_name": "اسم عنصر الفئات", + "variables": "المتغيرات", + "Information": "المعلومات", + "key": "المفتاح", + "Description": "الوصف", + "Add Another Item": "إضافة عنصر آخر", + "images": "الصور", + "no_records": "لا توجد سجلات", + "Total": "المجموع", + "items": "عناصر" } \ No newline at end of file diff --git a/src/translate/de.json b/src/translate/de.json new file mode 100644 index 0000000..d06fd29 --- /dev/null +++ b/src/translate/de.json @@ -0,0 +1,108 @@ +{ + "Ar": "Ar", + "En": "En", + "Arabic": "Arabisch", + "English": "Englisch", + "German": "Deutsch", + "Login": "Anmelden", + "Welcome back, please login to your account.": "Willkommen zurück, bitte melden Sie sich bei Ihrem Konto an.", + "Username": "Benutzername", + "Password": "Passwort", + "Sign in": "Einloggen", + "Point © 2022 | All Rights Reserved": "Point © 2022 | Alle Rechte vorbehalten", + "unknown": "unbekannt", + "super admin": "Superadmin", + "Home": "Startseite", + "example": "Beispiel", + "Log Out": "Abmelden", + "Example": "Beispiel", + "Add": "Hinzufügen", + "edit": "Bearbeiten", + "ligth": "Licht", + "dark": "Dunkel", + "Categories": "Kategorien", + "Products": "Produkte", + "Order": "Bestellung", + "Coupon": "Gutschein", + "Slider": "Schieberegler", + "Product_in_your_Application": "Produkt in Ihrer Anwendung", + "categories_in_your_Application": "Kategorien in Ihrer Anwendung", + "Order_in_your_Application": "Bestellung in Ihrer Anwendung", + "You_have": "Sie haben", + "January": "Januar", + "February": "Februar", + "March": "März", + "April": "April", + "London": "London", + "Paris": "Paris", + "New York": "New York", + "Seoul": "Seoul", + "name": "name", + "image": "bild", + "parent_id": "übergeordnete", + "product_count": "produktanzahl", + "basicinfo": "grundinfo", + "view_information": "information anzeigen", + "back": "zurück", + "price": "preis", + "description": "beschreibung", + "favorite": "favorit", + "main_photo": "hauptfoto", + "category_id": "kategorie", + "order_code": "bestellcode", + "email": "email", + "status": "status", + "total": "gesamt", + "order_id": "bestell", + "customer_name": "kundenname", + "customer_phone_number": "kunden telefonnummer", + "order_created_at": "bestellung erstellt am", + "address": "adresse", + "country": "land", + "note": "anmerkung", + "categories": "kategorien", + "coupon": "gutschein", + "orders": "bestellungen", + "products": "produkte", + "slider": "schieberegler", + "discount_type": "Rabatttyp", + "coupon_type": "Gutscheintyp", + "code": "Code", + "coupon_value": "Gutscheinwert", + "view_information_filed_fill_sucsessfully": "Anzeigeinformationsfeld erfolgreich ausgefüllt", + "category": "Kategorie", + "View_information": "Information anzeigen", + "VarianInfo": "Varianteninformation", + "Base_info": "Basisinformationen", + "name_ar": "Name (Arabisch)", + "name_en": "Name (Englisch)", + "name_de": "Name (Deutsch)", + "description_ar": "Beschreibung (Arabisch)", + "description_en": "Beschreibung (Englisch)", + "description_de": "Beschreibung (Deutsch)", + "upload_image": "Bild hochladen", + "images": "Bilder", + "photo": "Foto", + "admin_note": "Admin-Hinweis", + "state": "Status", + "title": "Titel", + "totals": "Summen", + "delivery_fee": "Liefergebühr", + "overall_total": "Gesamtsumme", + "sub_total": "Teilsumme", + "quantity": "Menge", + "active_from_to": "Aktiv von/bis", + "maximum_number_of_uses": "Maximale Anzahl von Verwendungen", + "minimum_total_to_order": "Mindestgesamtbestellung", + "maximum_number_of_uses_per_user": "Maximale Anzahl von Verwendungen pro Benutzer", + "product_item": "Produktartikel", + "categories_item_name": "Name der Kategorienartikel", + "variables": "Variablen", + "Information": "Informationen", + "key": "Schlüssel", + "Description": "Beschreibung", + "Add Another Item": "Weiteres Element hinzufügen", + "no_records": "Keine Datensätze", + "Total": "Insgesamt", + "items": "Artikel" +} \ No newline at end of file diff --git a/src/translate/en.json b/src/translate/en.json index 5aff3da..4f26ab7 100644 --- a/src/translate/en.json +++ b/src/translate/en.json @@ -3,12 +3,13 @@ "En": "En", "Arabic": "Arabic", "English": "English", + "German": "German", "Login": "Login", "Welcome back, please login to your account.": "Welcome back, please login to your account.", "Username": "Username", "Password": "Password", "Sign in": "Sign in", - "SDNone © 2022 | All Rights Reserved": "SDNone © 2022 | All Rights Reserved", + "Point © 2022 | All Rights Reserved": "Point © 2022 | All Rights Reserved", "unknown": "unknown", "super admin": "super admin", "Home": "Home", @@ -19,898 +20,89 @@ "edit": "Edit", "ligth": "Light", "dark": "Dark", - "": "", - "phone_verfication":"Phone Verfication", - "brand_name": "Samkary", - "dashboard": "Dashboard", - "accounts": "Accounts", - "users": "Users", - "view_accounts": "View Accounts", - "add_account": "Add Account", - "edit_account": "Edit Account", - "account":"Account", - "add": "Add", - "save": "Save", - "all": "All", - "viewer": "Viewer", - "vendor": "Vendor", - "admin": "Admin", - "super-admin": "Super Admin", - "client": "Client", - "full_name": "Full Name", - "role": "Role", - "email": "Email", - "phone": "Phone", - "optional": "Optional", - "password": "Password", - "account_image": "Account Image", - "image_preview": "Image Preview", - "confirm_password": "Confirm Password", - "permissions": "Permissions", - "_permissions": { - "viewer": "Viewer Permissions", - "vendor": "Vendor Permissions", - "admin": "Admin Permissions", - "super-admin": "Super Admin Permissions" - }, - "image": "Image", - "brands": "Brands", - "sort": "Sort", - "name": "Name", - "brand_points": "Brand Points", - "categories_count": "Categories Count", - "status": "Status", - "active": "Active", - "inactive": "Inactive", - "brand_name_field": "Brand Name", - "en": "English", - "ar": "Arabic", - "brand_sort": "Brand Sort", - "brand_image": "Brand Image", - "cancel": "Cancel", - "add_brand": "Add Brand", - "edit_brand": "Edit Brand", - "categories": "Categories", - "brand": "Brand", - "subcategories_count": "SubCategories Count", - "category_name": "Category Name", - "add_category": "Add Category", - "edit_category": "Edit Category", - "subcategories": "Sub Categories", - "subsubcategories": "Sub Sub Categories", - "category": "Category", - "products_count": "Products Count", - "add_subcategory": "Add Subcategory", - "edit_subcategory": "Edit Subcategory", - "subcategory_name": "Subcategory Name", - "subcategory_image": "Subcategory Image", - "add_subsubcategory": "Add Sub Subcategory", - "edit_subsubcategory": "Edit Sub Subcategory", - "subsubcategory_name": "Sub Subcategory Name", - "subsubcategory_image": "Sub Subcategory Image", - "settings": "Settings", - "general_settings": "General Settings", - "fax": "Fax", - "office_hours": "Office Hours", - "address_1": "First Address", - "address_2": "Second Address", - "address_3": "Third Address", - "conditions": "Conditions and Terms", - "privacy": "Privacy", - "transactions": "Transactions", - "send_points": "Send Points", - "select_recievers": "Select Recievers", - "confirm_send_points": "Confirm Send Points", - "amount": "Amount", - "total_amount": "Total Amount", - "number_of_recievers": "Number Of Recievers", - "send": "Send", - "rows": "Rows", - "view_transaction": "View Transaction", - "view_all": "View All", - "pending": "Pending", - "pending_payment": "Un Paid", - "paid": "Paid", - "unpaid": "Un Paid", - "on_going": "On Going", - "reject": "Reject", - "pend": "Pend", - "rejected": "Rejected", - "accepted": "Accepted", - "done": "Done", - "canceled": "Canceled", - "delivered": "Delivered", - "deliver": "Deliver", - "delivering": "Delivering", + "Categories": "Categories", + "Products": "Products", + "Order": "Order", + "Coupon": "Coupon", + "Slider": "Slider", + "Product_in_your_Application": "Product in your Application", + "categories_in_your_Application": "Categories in your Application", + "Order_in_your_Application": "Order in your Application", + "You_have": "You have", + "January": "January", + "February": "February", + "March": "March", + "April": "April", + "London": "London", + "Paris": "Paris", + "New York": "New York", + "Seoul": "Seoul", + "name": "name", + "image": "image", + "parent_id": "parent", + "product_count": "product count", + "basicinfo": "basic info", + "view_information": "view information", + "back": "back", + "price": "price", + "description": "description", + "favorite": "favorite", + "main_photo": "main photo", + "category_id": "category", + "order_code": "order code", + "email": "email", + "status": "status", + "total": "total", + "order_id": "order", + "customer_name": "customer name", + "customer_phone_number": "customer phone number", + "order_created_at": "order created at", + "address": "address", + "country": "country", + "note": "note", + "categories": "categories", + "coupon": "coupon", + "orders": "orders", + "products": "products", + "slider": "slider", + "discount_type": "Discount Type", + "coupon_type": "Coupon Type", "code": "Code", - "sender_name": "Sender Name", - "sender_phone_number": "Sender Phone", - "sender_role": "Sender Role", - "points": "Points", - "accept": "Accept", - "transaction_code": "Transaction Code", - "enter_transaction_code": "Please enter a transaction code", - "search": "Search", - "transaction_not_found": "Transaction NOT Found", - "date": "Date", - "number_of_receivers": "Number of Receivers", - "total_points": "Total Points", - "receivers": "Receivers", - "receiver_name": "Receiver Name", - "receiver_phone_number": "Receiver Phone Number", - "receiver_email": "Receiver Email", - "receiver_role": "Receiver Role", - "confirm_transaction": "Confirm Transaction", - "confirm_transaction_message": "Are you sure you want to Accept this transaction?", - "no": "NO", - "yes": "YES", - "cancel_transaction": "Cancel Transaction", - "cancel_transaction_message": "Are you sure you want to Cancel this transaction?", - "contact_info": "Contact Info", - "addresses": "Addresses", - "terms_&_conditions": "Terms and Conditions", - "advertisements": "Advertisements", - "mobile_image": "Mobile Image", - "title": "Title", - "link": "Link", - "large_image": "Large Image", - "category_image": "Category Image", - "category_images": "Category Images", - "Category_is_required": "Category Is Required", - "category_main_image": "Category Main Image", - "category_sub_image": "Category Sub Image", - "category_main_description": "Category Main Description", - "category_sub_description": "Category Sub Description", - "category_main_title": "Category Main Title", - "category_sub_title": "Category Sub Title", - "view_category": "View Category", - "please_fill_out_this_feild": "Please Fill Out This Feild", - "add_ad": "Add Advertisement", - "edit_ad": "Edit Advertisement", - "add_custom_ad_with_btn": "Add Custom Advertisement With Button", - "edit_custom_ad_with_btn": "Edit Custom Advertisement With Button", - "add_custom_ad_without_btn": "Add Custom Advertisement Without Button", - "edit_custom_ad_without_btn": "Edit Custom Advertisement Without Button", - "discounts": "Discounts", - "button": "Button", - "description": "Description", - "button_description": "Button Description", - "products": "Products", - "add_product": "Add Product", - "view_all_products": "View All Products", - "basic_info": "Basic Info", - "selection": "Selection", - "product_details": "Product Details", - "additional_images": "Additional Images", - "product_name": "Product Name", - "product_description": "Product Description", - "product_mobile_description": "Product Mobile Description", - "subcategory": "Subcategory", - "subsubcategory": "Sub Subcategory", - "product_price": "Product Price", - "product_quantity": "Product Quantity", - "product_main_image": "Product Main Image", - "product_video_link": "Product Video Link", - "product_sort": "Product Sort", - "view_product": "View Product", - "is_active": "Is Active", - "is_most_purchase": "Most Purchased", - "is_latest": "Is Latest", - "is_highlight": "Is Highlight", - "price": "Price", - "price_after_discount": "Price After Discount", - "product": "Product", - "no_images": "No Images", - "add_new_images": "Add New Images", - "delete": "Delete", - "image_sort": "Image Sort", - "offers": "Offers", - "add_offer": "Add Offer", - "view_all_offers": "View All Offers", - "offer_start_at": "Offer Starting Time", - "offer_end_at": "Offer Ending Time", - "offer_details": "Offer Details", - "offer_name": "Offer Name", - "offer_description": "Offer Description", - "offer_note": "Offer Note", - "offer_mobile_description": "Offer Mobile Description", - "offer_price_in_points": "Offer Price in Points", - "offer_video_link": "Offer Video Link", - "offer_sort": "Offer Sort", - "offer_main_image": "Offer Main Image", - "offer": "Offer", - "services_views": "Services Views", - "loading": "Loading...", - "_loading": { - "delete": "Deleting..." - }, - "login_again": "Please login with your new account information", - "login": "Login", - "welcome_login": "Welcome back, please login to your account.", - "fill_fields": "Please fill all the fields!", - "logout": "Log out", - "delete_are_you_sure": "DELETE, Are you sure?", - "yes_delete_it": "Yes, delete it!", - "no_revert": "You won't be able to revert this!", - "home": "Home", - "welcome_to_dashboard": "Welcome to the Dashboard!", - "order_offers": "Offer Orders", - "orders": "Orders", - "orders_to_export": "Orders To Export", - "from": "From", - "to": "To", - "print_order": "Print Order", - "view_order_offer": "View Order Offer", - "client_phone": "client Phone", - "client_image": "Client Image", - "client_link": "Client Link", - "client_email": "client Email", - "client_full_name": "client Full Name", - "offer_code": "Offer Code", - "offer_order_not_found": "Offer Order Not Found", - "enter_offer_code": "Please Enter Offer Order Code", - "confirm_offer_order": "Confirm Order", - "confirm_offer_order_message": "Are you sure you want to Accept this Order?", - "cancel_offer_order": "Cancel Order", - "cancel_offer_order_message": "Are you sure you want to Cancel this Order?", - "clients": "Our Clients", - "edit_client": "Edit client", - "is_verified": "Is Verified", - "change_password": "Change Password", - "no_records": "There are no records to display", - "failed_to_get_data": "Failed to Get Data", - "added_successfully": "Added Successfully", - "failed_to_add_data": "Failed to Add Data", - "updated_successfully": "Updated Successfully", - "failed_to_update_data": "Failed to Update Data", - "deleted_successfully": "Deleted Successfully", - "failed_to_delete_data": "Failed to Delete Data", - "toggle_success": "Toggled Successfully", - "toggle_failed": "Failed to Toggle Status", - "back": "Back", - "password_must_match": "Password Must Match", - "gallery": "Gallery", - "add_gallery_item": "Add Gallery Item", - "update_gallery_item": "Update Gallery Item", - "social_media": "Social Media", - "add_social_media": "Add Social Media", - "edit_social_media": "Edit Social Media", - "social_media_image": "Social Media Image", - "social_media_link": "Social Media Link", - "information": "Information", - "vision_description": "Vision Description", - "mission_description": "Mission Description", - "privacy_description": "Privacy Description", - "conditions_description": "Conditions Description", - "vision_image": "Vision Image", - "mission_image": "Mission Image", - "footer": "Footer", - "update_footer": "Update Footer", - "address": "Address", - "messages": "Messages", + "coupon_value": "Coupon Value", + "view_information_filed_fill_sucsessfully": "View information field filled successfully", + "category": "Category", + "View_information": "View Information", + "VarianInfo": "Variant Information", + "Base_info": "Base Information", + "name_ar": "Name (Arabic)", + "name_en": "Name (English)", + "name_de": "Name (German)", + "description_ar": "Description (Arabic)", + "description_en": "Description (English)", + "description_de": "Description (German)", "upload_image": "Upload Image", - "view_message": "View Message", - "categories_views": "Categories Views", - "descktop_visitors": "Desktop Visitors", - "mobile_visitors": "Mobile Visitors", - "all_visitors": "All Visitors", - "monthly_visitors": "Monthly Visitors", - "daily_visitors": "Daily Visitors", - "yearly_visitors": "Yearly Visitors", - "weekly_visitors": "Weekly Visitors", - "yearly_Statistics": "Yearly Statistics", - "yearly_visitors_over_month": "Yearly Visitors Over Months", - "active_categories_count": "Categories Count", - "active_products_count": "Products Count", - "visitors": "Number Of Visitors", - "search_for_categories": "Search For Categories", - "search_for_sub_categories": "Search For Sub Categories", - "search_for_products": "Search For Products", - "search_for_messages": "Search For Messages", - "search_for_accounts": "Search For Accounts", - "my_account": "My Account", - "add_client": "Add Client", - "services_count": "Services Count", - "team_members": "Team Members", - "add_team_member": "Add Team Member", - "edit_team_member": "Edit Team Member Info", - "member_name": "Member Name", - "member_image": "Member Image", - "facebook_link": "Facebook Link", - "linkedin_link": "LinkedIn Link", - "instgram_link": "Instagram Link", - "awards": "Awards", - "awards_description": "Awards Description", - "awards_image": "Awards Image", - "about_us": "About Us", - "about_us_description": "About Us Description", - "about_us_image": "About Us Image", - "ceo_message": "CEO Message", - "company_info": "Company Info", - "test": "test", - "home_videos": "Home Videos", - "large_screens": "Large Screens", - "mobile_screens": "Mobile Screens", - "main_video": "Main Video", - "sub_video": "Sub Video", - "main_video_title": "Main Video Title", - "sub_video_title": "Sub Video Title", - "home_main_video": "Home Main Video", - "home_sub_video": "Home Sub Video", - "discount_rate": "Discount Rate", - "discount_name": "Discont Name", - "start_at": "Start Date", - "end_at": "End Date", - "add_discount": "Add Discount", - "edit_discount": "Edit Discount", - "is_discount_date_active": "Is Discount Date Active", - "discount_status": "Discount Status", - "currencies": "Currencies", - "currency_name": "Currency Name", - "currency_code": "Currency Code", - "currency_rate": "Currency Rate", - "add_currency": "Add Currency", - "edit_currency": "Edit Currency", - "default_currency": "Default Currency", - "currency": "Currency", - "rate": "Rate", - "all_shops": "All Shops", - "shop_categories": "Shop Categories", - "add_shop_category": "Add Shop Category", - "shop_subCategories": "Shop Sub Categories", - "shops": "Shops", - "add_shop": "Add Shop", - "edit_shop": "Edit Shop", - "shop_name": "Shop Name", - "shop_description": "Shop Description", - "shop_mobile_description": "Shop Mobile Description", - "shop_image": "Shop Image", - "products_colors": "Products Colors", - "color_name": "Color Name", - "color_image": "Color Image", - "add_color": "Add Color", - "add_new_color": "Add New Color", - "edit_color": "Edit Color", - "colors": "Colors", - "delivery_fee": "Delivery Fee", - "delivery_fee_for_animal_feed": "Delivery Fee For Animal Feed", - "shop_category_name": "Shop Category Name", - "please_select_shop_first": "Please Select Shop First", - "please_select_vendor": "Please Select Vendor First", - "no_shops": "No Shops", - "shop_category_image": "Shop Category Image", - "shop_category": "Shop Category", - "shop_subcategories": "Shop Sub Categories", - "shop_subcategory_name": "Shop Sub Category Name", - "add_shop_subcategory": "Add Shop Subcategory", - "edit_shop_subcategory": "Edit Shop Subcategory", - "shop_subcategory": "Shop Subcategory", - "size_name": "Size Name", - "auctions": "Auctions", - "auction_status": "Auction Status", - "edit_auction": "Edit Auction", - "auction_details": "Auction Details", - "auction_description": "Auction Description", - "auction_name": "Auction Name", - "auction_mobile_description": "Auction Mobile Description", - "auction_main_image": "Auction Main Image", - "auction_sort": "Auction Sort", - "add_auction": "Add Auction", - "starting_price": "Starting Price", - "auction_order_status": "Auction Order Status", - "auctions_orders": "Auctions Orders", - "add_auction_order": "Add Auction Order", - "edit_auction_order": "Edit Auction Order", - "customer_info": "Customer Info", - "customer_address": "Customer Address", - "auction_order_details": "Auction Order Details", - "auction_order_code": "Auction Order Code", - "auction_order_total": "Auction Order Total", - "auction_order_price": "Auction Order Price", - "select_user": "Select User", - "change_user": "Change User", - "search_for_user": "Search For User", - "owner_products": "Owner Products", - "owner_product": "Owner Product", - "shops_products": "Shops Products", - "shop_product": "Shop Product", - "shop": "Shop", - "quantity": "Quantity", - "please_select_a_shop": "Please select a shop", - "edit_product": "Edit Product", - "customer_address_country": "Country", - "customer_address_city": "City", - "customer_address_street": "Street", - "customer_address_building_number": "Building Number", - "customer_address_additional_information": "Additional Information", - "customer_email": "Customer Email", - "payment_method": "Payment Method", - "payment_code": "Payment Code", - "employee_name": "Employee Name", - "employee_phone": "Employee Phone", - "employee_id": "Employee ID", - "employee_status": "Employee Status", - "employee_orders": "Employee Orders", - "employee_wallet": "Employee Wallet", - "employee_image": "Employee Image", - "employee_password": "Employee Password", - "employee_password_confirmation": "Employee Password Confirmation", - "add_delivery_employee": "Add Delivery Employee", - "delivery_employee_information": "Delivery Employee Information", - "old_password": "Old Password", - "not_delivered_yet": "Not Delivered Yet", - "not_pickuped_yet": "Not Picked Up Yet", - "vendor_orders": "Vendor Orders", - "delivery": "Delivery", - "please_select_shop": "Please Select Shop", - "type_your_message": "Type Your Message ...", - "order_code": "Order Code", - "order_created_at": "Order Created At", - "customer_name": "Customer Name", - "customer_phone_number": "Customer Phone Number", - "customer_zone_number": "Customer Zone Number", - "payment_id": "Payment ID", - "payment_getaway_status": "Payment Getaway Status", - "busy": "Busy", - "available": "Available", - "order_status": "Order Status", - "payment_status": "Payment Status", - "order_total": "Order Price", - "cash_on_delivery": "Cash On Delivery", - "stripe": "Stripe", + "images": "Images", + "photo": "Photo", + "admin_note": "Admin Note", + "state": "State", + "title": "Title", "totals": "Totals", - "sub_total": "Sub Total", - "tax_total": "Tax Total", + "delivery_fee": "Delivery Fee", "overall_total": "Overall Total", - "delivery_employees": "Delivery Employees", - "welcome_message": "Welcome to Elite Auction Admin Dashboard", - "statistics": "Statistics", - "google_analytics": "Google Analytics", - "signin_via_google": "Signin via Google", - "open_google_dashboard": "Open Google Dashboard", - "google_analytics_instructions": "You can signin with your google analytics account to view the analytics on this page, or navigate to google analytics dashboard.", - "err_occured": "An Error occured, Please try again", - "live_stream": "Live Stream", - "sizes": "Sizes", - "add_size": "Add Size", - "add_new_size": "Add New Size", - "edit_size": "Edit Size", - "products_sizes": "Products Sizes", - "sizes&colors": "Sizes And Colors", - "no_size_chosen": "No Size Chosen", - "no_color_chosen": "No Color Chosen", - "discount": "Discount", - "no_discount": "No Discount", - "comming_soon": "Comming Soon", - "latest_users": "Latest Users", - "latest_orders": "Latest Orders", - "show_all_orders": "Show All Orders", - "show_all_users": "Show All Users", - "comments_and_reviews": "Comments And Reviews", - "comments": "Comments", - "comment": "Comment", - "reviews": "Reviews", - "change_review_status": "Change Review Status", - "review_status": "Review Status", - "review_description": "Review Description", - "review_stars": "Review Stars", - "showed": "Showed", - "hidden": "Hidden", - "view": "View", - "export": "Export", - "_currency": { - "update_are_you_sure": "Are You Sure You Want To Change The Default Currency", - "yes_update_it": "Yes Change It", - "cancel": "Cancel", - "body": "In Case You Change The Default Currency It Will Change In All Products" - }, - "_active": { - "products_count": "Acivte Products", - "orders_count": "Orders", - "categories_count": "Active Categories", - "shops_count": "Shops", - "users_count": "Users Count" - }, - "_search": { - "category": "Search for Category", - "subcategory": "Search for Sub Category", - "product": "Search for Product", - "shop": "Search for Shop", - "team_member": "Search for Team member", - "order": "Search For Order", - "employee": "Search For Employee", - "vendor": "Search For Vendor", - "color": "Search For Color", - "size": "Search For Size", - "customer_products": "Search For Customer Products" - }, - "new": { - "password": "New Password", - "confirm_password": "Confirm New Password" - }, - "required": "Required", - "_required": { - "link": "Link is Required", - "password": "Password is Required", - "email": "Email is Required", - "member_name": "Member Name is Required", - "member_image": "Member Image is Required", - "name": "Name is Required", - "phone": "Phone is Required", - "discount_name": "Discount Name Is Required", - "start_at": "Start Date Required", - "end_at": "End Date Required", - "discount_rate": "Discount Rate Required", - "is_discount_date_active": "Is Discount Date Acitve Is Required", - "currency_name": "Currency Name Required", - "currency_code": "Currency Code Required", - "Currency_rate": "Currency Rate Required" - }, - "validation": { - "link": "Please enter a valid URL link", - "passwords_match": "Passwords MUST match", - "invalid_email": "Invalid Email", - "invalid_name": "Invalid Name", - "invalid_phone": "Invalid Phone", - "confirm_password": "Passwords Must Match", - "min_number": "The Number Must Be Between 1 - 100", - "Max_number": "The Number Must Be Between 1 - 100", - "size_and_color": "Must Choose Either Size Or Color" - }, - "lang_1": "English", - "lang_2": "Arabic", - "_messages": { - "success": { - "upload": "Uploaded Successfully" - }, - "error": { - "upload": "An error occured while uploading" - } - }, - "you_are_not_authorized": "Your Are Not Authorized!", - "page_not_found": "Page Not Found", - "an_error_occured": "An Error Occured", - "_not_found": { - "product": "Product not found" - }, - "customer_products": "Customer Products", - "customer_product_information": "Customer Product Info", - "change_product_status": "Change Product Status To", - "pendding": "Pendding", - "product_category": "Product Categorie", - "customer_id_number": "Customer Id Number", - "customer": "Customer", - "rejected_cause": "Rejected Cause", - "(rejected)": "(Rejected)", - "number_of_day_show": "Number Of Day Show", - "(successful)": "(Successful)", - "product_subcategory": "Product SubCategory", - "product_subsubcategory": "Product SubSubCategory", - "date_is_smaller_than_now": "Date Smaller Than Now", - "change_status": "Change Status To ", - "add_branch": "Add Branch", - "view_branch": "View Branch ", - "branch_name": "Branch Name", - "zone_number": "Zone Number", - "building_number": "Building Number", - "street": "Street", - "floor_number": "Floor Number", - "view_branchs": "View Branchs", - "enter_city": "Enter Region", - "location_name": "Location Name", - "edit_branch": "Edit Branch", - "start_point": "Start Point", - "delivary_by": "Delivary By", - "please_add_at_least_one_branch": "Please Add At Least One Branch", - "special_delivery_fee": "Special Delivery fee", - "notification": "Notification", - "add_notification": "Add Notification", - "notification_body": "Notification Body", - "notification_title": "Notification Title", - "body": "Body", - "created_at": "Created at", - "payment": "Payment", - "cash": "Cash", - "online": "Online", - "category_products": "Category Products", - "km_price": "Km Price", - "auction_enrollments": "Auction Enrollments", - "username": "UserName", - "front_personal_identity_image": "Front Personal Identity image", - "back_personal_identity_image": "Back Personal Identity image", - "general_delivery_fee": "General Delivery Fee", - "auction_qatar_fee": "Auction Qatar Fee", - "product_image": "Product Image", - "ending_price": "Ending Price", - "additional_time": " Additional Time After Bidding (per Minutes)", - "increase_amount": "Increase Amount", - "profit_percentage": "Profit Percentage", - "insurance_amount": "Insurance Amount", - "bank_commission": "Bank Commission", - "sub_vendor": "Sub Vendor ", - "version_mobile": "Version Mobile", - "photo_settings": "Photo Settings", - "photo": "Photo ", - "is_ads": "Is Ads", - "for_shop": "For Shop", - "change_to": "Change To", - "change": "Change", - "type": "Type", - "leave_it_empty_to_not_ability_for_clicked": "Leave it blank to disable it from being clicked", - "null": "Null", - "file": "File", - "preview": "Preview", - "note": "Note", - "select_sub": "Select SubCategory Please", - "select_shop": "Select Shop Please", - "note : leave the date empty to fill now": "Note : Leave the Date Empty to fill now", - "other": "Other", - "ios_link": "Ios Link", - "android_link": "Android Link", - "Error in export orders": "Error in export orders", - "Error in shop orders export": "Error in shop orders export", - "Error in subcategory orders export": "Error in subcategory orders export", - "from_date": "From Date", - "to_date": "To Date", - "order_value": "Order Value", - "get_orders_rewards": "Get Orders To Rewards", - "get_resulte": "Get Resulte", - "rewards": "Rewards", - - - "app_setting":"App Setting", - "add_setting":"Add Setting", - "setting_name":"Setting Name", - "edit_setting":"Edit Setting", - "value":"Value", - "Code":"Coupon", - "Wallets":"Wallets", - "Transaction":"Transaction", - "user_management":"User Management", - "drivers":"Drivers", - "customers":"Customres", - "pos":"Pos", - "add_code":"Add Coupon", - "code_number":"Number Coupon", - "order":"Order", - "driver_name":"Driver Name", - "address_from":"Address From", - "address_to":"Address To", - "paid_type":"Paid Type", - "money_of_customer":"Money Of Customer", - "is_paid":"Is Paid", - "select_driver":"Select Driver", - "select":"Select", - "select_customer":"Select Customer", - "name_driver_selected":"Name Driver Selected", - "name_customer_selected":"Name Customer Selected", - "enter_button_select":"Enter Button Select To fill", - "add_customer":"Add Customer", - "customer_image":"Customer Image", - "edit_customer":"Edit Customer", - "driver_id_number":"Driver Id Number", - "id_number":"ID Number", - "car_type":"Car Type", - "customer_information":"Customer Information", - "customer_details":"Customer Details", - "driver_order":"Driver Order", - "driver_information":"Driver Information", - "gift":"Gifts", - "gift_to":"Gift To", - "add_gift":"Add Gift", - "draiver_date_of_birith":"Driver Date Of Birith", - "gender":"Gender", - "car_color":"Car Color", - "car_model":"Car Model", - "car_seats_number":"Car Seats Number", - "car_back_side":"Car Back Side", - "car_front_side":"Car Front Side", - "car_right_side":"Car Right Side", - "car_left_side":"Car Left Side", - "car_internal_front_side":"Car Internal Back Side", - "car_internal_back_side":"Car Internal Front Side", - "additional_car_info":"Additional Car Info", - "additional_driver_info":"Additional Driver Info", - "driver_nationality_id":"Driver Nationality Id", - "driver_residential_card_number":"Driver Residential Card Number", - "driver_residential_card_image":"Driver Residential Card Image", - "driver_yearly_image_front":"Driver Yearly Image Front ", - "driver_yearly_image_back":"Driver Yearly Image Back", - "driver_nationality_image_back":"Driver Nationality Image Back", - "driver_nationality_image_front":"Driver Nationality Image Front", - "driver_license_back_image":"Driver License Back Image", - "driver_license_front_image":"Driver License Front Image", - "driver_yearly_id":"Driver Yearly Id", - "edit_cusotmer":"Edit Customer", - "driver_license_number":"Driver License Number", - "driver_license_info":"Driver License Info", - "latest_customer":"Latest Customer", - "latest_driver":"Latest Driver", - "show_all_customer":"Show All Customer", - "show_all_driver":"Show All Driver", - "enter_notification":"Enter Notification", - "send_notification":"Send Notification", - "driver_block_page":"Driver Block Page ", - "blocking_driver":"Blocking Driver", - "number_of_day_blocking":"Number Of Day Blocking", - "add_block_for_user":"Block User ", - "block_time_remaining":"Block Time Remaining", - "driver_code":"Driver Code" , - "city":"City " , - "driver_image":"Driver Image", - "driver_phone":"Driver Phone", - "customer_code":"Customer Code", - "end_point":"End Pont ", - "final_price":"Final Price", - "start_time_trip":"Start Time Trip", - "end_time_trip":"End Time Trip", - "driver_rate":"Driver Order Rate", - "unacceptable_order":"Un Accepted Order", - "content":"Content", - "reason":"Reason" , - "person_from":"Person From", - "person_to":"Preson To ", - "transaction_date":"Transaction Date", - "schedule":"Schedule", - "wallet":"Wallet", - "blocking_customer":"Blocking Customer", - "customer_block_page":"Customer BLock Page", - "date_blocking":"Date Blocking", - "enter_code":"Enter Coupon", - "give":"Give", - "blocked":"Blocked", - "unblocked":"Un Blocked", - "customer_wallet":"Wallet", - "customer_city":"City", - "customer_phone":"Phone", - "driver_birthday":"Driver Birithday", - "driver_gender":"Gender", - "driver_wallet":"Wallet", - "car_front_side_image":"Car Front Side Image", - "car_internal_back_side_image":"Car Internal Back Side Image", - "car_internal_front_side_image":"Car Internal Image Side Image", - "car_right_side_image":"Car Right Side Image ", - "car_left_side_image":"Car Left Side Image", - "car_back_side_image":"Car Back Side Image", - "driver":"Driver", - "driver_gift_page":"Driver Gift Page", - "driver_order_rate":"Driver Order Rate", - "trip_information":"Trip Information", - "personal_information":"Personal Information", - "User_in_your_Application" :"User in Your Application", - "Driver_in_your_Application":"Driver in Your Application", - "Order_in_your_Application":"Order In Your Application", - "You_have":"You Have ", - "send_to":"Send To", - "notification_form":"Notification Form", - "multi":"Multi", - "start":"In Trip", - "order_information":"Order Information", - "complete":"Complete", - "offline":"Offline", - "busiest_drivers":"Busiest Drivers", - "yearly_order_over_month":"Yearly Order Over Month", - "un_blocking_customer":"Un Block Customer", - "un_customer_block_page":"Un Block Customer Page", - "un_block_for_customer":"Un Block Customer", - "un_blocking_driver":"Un Blocking Driver ", - "un_driver_block_page":"Un block Driver Page", - "un_block_for_driver":"Un Block Driver ", - "add_block_for_driver":"Block Driver", - "unavailable":"Unavailable", - "used":"Used", - "unused":"Un Used", - "select_permistions":"Select Permissions", - "role_name":"Role Name", - "customer_gift_page":"Customer Gift Page", - "number_permissions":"Number Permissions", - "add_role":"Add Role", - "print":"Print", - "add_to_wallet":"Add To Wallet", - "precent":"Precent", - "price_per_km":"Price Per km", - "customer_profit_ratio":"Customer Profit Ratio", - "driver_profit_ratio":"Driver Profit Ratio", - "driver_min_wallet":"Driver Minimum Wallet", - "price_per_min":"Price Per min", - "Baghdad Governorate":"Baghdad Governorate", - "Rusafa":"Rusafa", - "Adhamiyah":"Adhamiyah", - "Thawra":"Thawra", - "9 Nissan":"9 Nissan", - "Karadah":"Karadah", - "Kadhimiyah":"Kadhimiyah", - "Mansour":"Mansour", - "Al Rashid":"Al Rashid", - "Karkh":"Karkh", - "relative_cost":"Relative Cost", - "The_cost_of_opening_the_door":"The Cost Of Opening The Door", - "radius_of_the_circle_per_km":"Radius Of The Circle Per km", - "time_to_cancel_order_per_m":"Time to Cancel Order Per m ", - "waiting_time_befor_cancel":"Waiting Time Befor Cancel", - "discount_customer_for_being_late":"Discount Customer For Being Late", - "radius_of_the_circle_befor_press_waiting_per_km":"Radius of the Circle Before Enter Waiting per km", - "driver_profit_when_cancel_order":"Driver Profit When Cancel Order", - "sunday":"Sunday" , - "monday":"Monday" , - "tuesday":"Tuesday" , - "wednesday":"Wednesday" , - "thursday":"Thursday" , - "friday":"Friday" , - "saturday":"Saturday" , - "daily_order_over_week":"Daily Order Over Week", - "canceled_by":"Canceled By", - "order_count":"Order Count", - "daily_order":"Daily Order ", - "total_order_price":"Total Order Price", - "end_tripe_date":"End Trip Date", - "money_received":"Money Received", - "order_price":"Order Price", - "created_by":"Created By", - "high_drivers_rate":"High Driver Rate", - "join_at":"Join at", - "user_name":"User Name", - "user_phone":"User Phone", - "user_code":"User Code", - "distance_per_km":"Distance Km", - "time_per_m":"Time Minutes", - "is_percentage":"is Percentage", - "daily_order_per_years":"Daily order per years", - "glass":"glass", - "in_active":"Inactive", - "Driver Order":"Driver Order", - "Additional Driver Info":"Additional Driver Info", - "Additional Car Info":"Additional Car Info", - "BasicInfo":"Basic Info", - "car_seat_count":"car seat count", - "car_front":"car front", - "car_right":"car right", - "car_internal":"car internal", - "car_back":"car back", - "car_left":"car left", - "car_internal_back":"car internal back", - "order_info":"order info", - - - "license_front_image":"license front image", - "license_back":"license back image", - "nationality_back":"nationality back image", - "yearly_back":"yearly back image", - "nationality_front":"nationality front image", - "residential_card":"residential card image", - "yearly_front":"yearly front image", - "View_information":"View information", - "add_block_for_":"Block ", - "number":"number", - "Ops":"Ops", - "An Error According":"An Error According", - "Please Try Again Later":"Please Try Again Later", - "fav_trips":"Favourite Trips", - "You Are Not Connected":"You Are Not Connected", - "SocketDebug":"SocketDebug", - "event":"event", - "room":"room", - "socket_id":"socket id", - "data":"data", - "clear":"Clear", - "Socket Are Connected":"Socket Are Connected", - "Socket Are Disconnected":"Socket Are Disconnected", - "blocking_":"Blocking ", - "_block_page":" block page", - "al":"", - "_gift_page":"gift page", - "un_block_page":"un block page", - "un_blocking_":"un blocking ", - "un_block_for_":"un block for ", - "Add Successful":"Add Successful", - "Has Accepte the Order":"Has Accepte the Order", - "open":"Open", - "Driver Info":"Driver Info", - "Customer Info":"Customer Info", - "driver order today":"Driver order today", - "driver order yesterday":"Driver order yesterday", - "distance":"Distance", - "Send Order To Nearst 5 Driver":"Send Order To Nearst 5 Driver", - "one":"One" - + "sub_total": "Sub Total", + "quantity": "Quantity", + "active_from_to": "Active From/To", + "maximum_number_of_uses": "Maximum Number of Uses", + "minimum_total_to_order": "Minimum Total to Order", + "maximum_number_of_uses_per_user": "Maximum Number of Uses Per User", + "product_item": "Product Item", + "categories_item_name": "Categories Item Name", + "variables": "Variables", + "Information": "Information", + "key": "Key", + "Description": "Description", + "Add Another Item": "Add Another Item", + "no_records": "No records", + "Total": "Total", + "items": "items" } \ No newline at end of file diff --git a/src/translate/text b/src/translate/text new file mode 100644 index 0000000..e69de29 diff --git a/src/utils/Array/ArrayToObjectFormik.ts b/src/utils/Array/ArrayToObjectFormik.ts new file mode 100644 index 0000000..5c11d90 --- /dev/null +++ b/src/utils/Array/ArrayToObjectFormik.ts @@ -0,0 +1,26 @@ +export function objectToArray(obj:any) { + // Initialize an empty array to store the result + const result = [] as any ; + + // Iterate over the keys of the object + for (const key in obj) { + if (obj.hasOwnProperty(key)) { + // Extract the index from the key + const index = parseInt(key.split('.')[0]); + + // Get the attribute name from the key + const attributeName = key.split('.')[1]; + + // If the index does not exist in the result array, create a new object + if (!result[index]) { + result[index] = {}; + } + + + // Set the attribute value in the result object + result[index][attributeName] = obj[key]; + } + } + + return result; + } \ No newline at end of file diff --git a/src/utils/Array/changeShapeInfo.tsx b/src/utils/Array/changeShapeInfo.tsx new file mode 100644 index 0000000..0908eb2 --- /dev/null +++ b/src/utils/Array/changeShapeInfo.tsx @@ -0,0 +1,14 @@ +export function changeShapeInfo(originalObject: any) { + const transformedObject: any = {}; + + for (const key in originalObject) { + if (originalObject.hasOwnProperty(key)) { + const index = key.split('.')[0]; // Extract index from key + const attribute = key.split('.')[1]; // Extract attribute from key + + transformedObject[originalObject[`${index}.key`]] = originalObject[`${index}.Description`]; + } + } + + return transformedObject +} \ No newline at end of file diff --git a/src/utils/Array/getInfoKeyAndDescriptions.ts b/src/utils/Array/getInfoKeyAndDescriptions.ts new file mode 100644 index 0000000..8ff163f --- /dev/null +++ b/src/utils/Array/getInfoKeyAndDescriptions.ts @@ -0,0 +1,12 @@ +export function convertToObject(obj:any) { + const newObj = {} as any; + for (const key in obj) { + if (key.includes('.Key')) { + const newKey = obj[key]; + const valueKey = key.replace('.Key', '.Description'); + const value = obj[valueKey]; + newObj[newKey] = value; + } + } + return newObj; +} \ No newline at end of file