From e0e47a12fea4fdadb17a01df1c91bb05315b1521 Mon Sep 17 00:00:00 2001
From: ArsPro1323 <131661233+ArsPro1323@users.noreply.github.com>
Date: Sun, 7 Jan 2024 13:54:37 +0300
Subject: [PATCH 1/3] done sprint 12
---
.gitignore | 1 +
.vscode/settings.json | 3 -
README.md | 46 -----
.../package-lock.json => package-lock.json | 178 ++++++++++++++++++
react-burger/package.json => package.json | 6 +
{react-burger/public => public}/favicon.ico | Bin
{react-burger/public => public}/index.html | 0
{react-burger/public => public}/logo192.png | Bin
{react-burger/public => public}/logo512.png | Bin
{react-burger/public => public}/manifest.json | 0
{react-burger/public => public}/robots.txt | 0
react-burger/.gitignore | 23 ---
.../burger-constructor/burger-constructor.tsx | 57 ------
.../burger-ingredients/burger-ingredients.tsx | 34 ----
.../ingredient-table/card/card.tsx | 36 ----
react-burger/src/components/main/main.tsx | 43 -----
.../get-ingredients/get-ingredients.ts | 11 --
.../src => src}/components/App/app.module.css | 0
.../src => src}/components/App/app.tsx | 0
.../app-header/app-header.module.css | 0
.../components/app-header/app-header.tsx | 0
.../burger-constructor-types.ts | 0
.../burger-constructor/burger-constructor.jsx | 96 ++++++++++
.../burger-constructor.module.css | 8 +-
.../burger-element.module.css | 0
.../constructor-element-types.ts | 1 +
.../constructor-element.jsx | 47 ++++-
.../burger-ingredients-types.ts | 0
.../burger-ingredients.module.css | 0
.../burger-ingredients/burger-ingredients.tsx | 111 +++++++++++
.../ingredient-table/card/card.module.css | 14 ++
.../ingredient-table/card/card.tsx | 62 ++++++
.../ingredient-table/card/data.ts | 0
.../ingredient-table/ingredient-item-name.ts | 1 +
.../ingredient-table.module.css | 0
.../ingredient-table/ingredient-table.tsx | 6 +-
.../ingredient-deatail-types.ts | 1 -
.../ingredient-details.module.css | 0
.../ingredient-details/ingredient-details.tsx | 9 +-
.../ingredient-substance.module.css | 0
.../ingredient-substance.tsx | 0
.../ingredient-substancse-types.ts | 0
.../components/main/main.module.css | 0
src/components/main/main.tsx | 17 ++
.../modal-overlay/modal-overlay.module.css | 0
.../modal-overlay/modal-overlay.tsx | 0
.../components/modal/modal-type.ts | 0
.../components/modal/modal.module.css | 0
.../src => src}/components/modal/modal.tsx | 0
.../orders-details/order-details-types.ts | 1 +
.../orders-details/order-details.module.css | 0
.../orders-details/orders-details.tsx | 4 +-
{react-burger/src => src}/images/done.png | Bin
{react-burger/src => src}/index.css | 0
{react-burger/src => src}/index.tsx | 6 +-
{react-burger/src => src}/react-app-env.d.ts | 0
{react-burger/src => src}/reportWebVitals.ts | 0
src/services/actions/constructor-action.ts | 31 +++
src/services/actions/ingredients-actions.ts | 14 ++
src/services/actions/modal-action.ts | 11 ++
.../get-ingredients/get-ingredients-types.ts | 2 +-
.../get-ingredients/get-ingredients.ts | 25 +++
src/services/reducers/constructor-reducer.ts | 55 ++++++
src/services/reducers/ingredients-reducer.ts | 23 +++
src/services/reducers/modal-reducer.ts | 28 +++
src/services/reducers/store.ts | 21 +++
src/services/reducers/types.ts | 43 +++++
{react-burger/src => src}/setupTests.ts | 0
react-burger/tsconfig.json => tsconfig.json | 0
69 files changed, 802 insertions(+), 273 deletions(-)
create mode 100644 .gitignore
delete mode 100644 .vscode/settings.json
delete mode 100644 README.md
rename react-burger/package-lock.json => package-lock.json (98%)
rename react-burger/package.json => package.json (84%)
rename {react-burger/public => public}/favicon.ico (100%)
rename {react-burger/public => public}/index.html (100%)
rename {react-burger/public => public}/logo192.png (100%)
rename {react-burger/public => public}/logo512.png (100%)
rename {react-burger/public => public}/manifest.json (100%)
rename {react-burger/public => public}/robots.txt (100%)
delete mode 100644 react-burger/.gitignore
delete mode 100644 react-burger/src/components/burger-constructor/burger-constructor.tsx
delete mode 100644 react-burger/src/components/burger-ingredients/burger-ingredients.tsx
delete mode 100644 react-burger/src/components/burger-ingredients/ingredient-table/card/card.tsx
delete mode 100644 react-burger/src/components/main/main.tsx
delete mode 100644 react-burger/src/services/get-ingredients/get-ingredients.ts
rename {react-burger/src => src}/components/App/app.module.css (100%)
rename {react-burger/src => src}/components/App/app.tsx (100%)
rename {react-burger/src => src}/components/app-header/app-header.module.css (100%)
rename {react-burger/src => src}/components/app-header/app-header.tsx (100%)
rename {react-burger/src => src}/components/burger-constructor/burger-constructor-types.ts (100%)
create mode 100644 src/components/burger-constructor/burger-constructor.jsx
rename {react-burger/src => src}/components/burger-constructor/burger-constructor.module.css (66%)
rename {react-burger/src => src}/components/burger-constructor/constructor-element/burger-element.module.css (100%)
rename {react-burger/src => src}/components/burger-constructor/constructor-element/constructor-element-types.ts (90%)
rename react-burger/src/components/burger-constructor/constructor-element/constructor-element.tsx => src/components/burger-constructor/constructor-element/constructor-element.jsx (50%)
rename {react-burger/src => src}/components/burger-ingredients/burger-ingredients-types.ts (100%)
rename {react-burger/src => src}/components/burger-ingredients/burger-ingredients.module.css (100%)
create mode 100644 src/components/burger-ingredients/burger-ingredients.tsx
rename {react-burger/src => src}/components/burger-ingredients/ingredient-table/card/card.module.css (55%)
create mode 100644 src/components/burger-ingredients/ingredient-table/card/card.tsx
rename {react-burger/src => src}/components/burger-ingredients/ingredient-table/card/data.ts (100%)
rename {react-burger/src => src}/components/burger-ingredients/ingredient-table/ingredient-item-name.ts (79%)
rename {react-burger/src => src}/components/burger-ingredients/ingredient-table/ingredient-table.module.css (100%)
rename {react-burger/src => src}/components/burger-ingredients/ingredient-table/ingredient-table.tsx (77%)
rename {react-burger/src => src}/components/ingredient-details/ingredient-deatail-types.ts (87%)
rename {react-burger/src => src}/components/ingredient-details/ingredient-details.module.css (100%)
rename {react-burger/src => src}/components/ingredient-details/ingredient-details.tsx (66%)
rename {react-burger/src => src}/components/ingredient-details/ingredient-substance/ingredient-substance.module.css (100%)
rename {react-burger/src => src}/components/ingredient-details/ingredient-substance/ingredient-substance.tsx (100%)
rename {react-burger/src => src}/components/ingredient-details/ingredient-substance/ingredient-substancse-types.ts (100%)
rename {react-burger/src => src}/components/main/main.module.css (100%)
create mode 100644 src/components/main/main.tsx
rename {react-burger/src => src}/components/modal-overlay/modal-overlay.module.css (100%)
rename {react-burger/src => src}/components/modal-overlay/modal-overlay.tsx (100%)
rename {react-burger/src => src}/components/modal/modal-type.ts (100%)
rename {react-burger/src => src}/components/modal/modal.module.css (100%)
rename {react-burger/src => src}/components/modal/modal.tsx (100%)
rename {react-burger/src => src}/components/orders-details/order-details-types.ts (88%)
rename {react-burger/src => src}/components/orders-details/order-details.module.css (100%)
rename {react-burger/src => src}/components/orders-details/orders-details.tsx (82%)
rename {react-burger/src => src}/images/done.png (100%)
rename {react-burger/src => src}/index.css (100%)
rename {react-burger/src => src}/index.tsx (68%)
rename {react-burger/src => src}/react-app-env.d.ts (100%)
rename {react-burger/src => src}/reportWebVitals.ts (100%)
create mode 100644 src/services/actions/constructor-action.ts
create mode 100644 src/services/actions/ingredients-actions.ts
create mode 100644 src/services/actions/modal-action.ts
rename {react-burger/src => src}/services/get-ingredients/get-ingredients-types.ts (94%)
create mode 100644 src/services/get-ingredients/get-ingredients.ts
create mode 100644 src/services/reducers/constructor-reducer.ts
create mode 100644 src/services/reducers/ingredients-reducer.ts
create mode 100644 src/services/reducers/modal-reducer.ts
create mode 100644 src/services/reducers/store.ts
create mode 100644 src/services/reducers/types.ts
rename {react-burger/src => src}/setupTests.ts (100%)
rename react-burger/tsconfig.json => tsconfig.json (100%)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3c3629e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+node_modules
diff --git a/.vscode/settings.json b/.vscode/settings.json
deleted file mode 100644
index ca89b74..0000000
--- a/.vscode/settings.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "editor.fontSize": 16
-}
\ No newline at end of file
diff --git a/README.md b/README.md
deleted file mode 100644
index b87cb00..0000000
--- a/README.md
+++ /dev/null
@@ -1,46 +0,0 @@
-# Getting Started with Create React App
-
-This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
-
-## Available Scripts
-
-In the project directory, you can run:
-
-### `npm start`
-
-Runs the app in the development mode.\
-Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
-
-The page will reload if you make edits.\
-You will also see any lint errors in the console.
-
-### `npm test`
-
-Launches the test runner in the interactive watch mode.\
-See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
-
-### `npm run build`
-
-Builds the app for production to the `build` folder.\
-It correctly bundles React in production mode and optimizes the build for the best performance.
-
-The build is minified and the filenames include the hashes.\
-Your app is ready to be deployed!
-
-See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
-
-### `npm run eject`
-
-**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
-
-If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
-
-Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
-
-You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
-
-## Learn More
-
-You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
-
-To learn React, check out the [React documentation](https://reactjs.org/).
diff --git a/react-burger/package-lock.json b/package-lock.json
similarity index 98%
rename from react-burger/package-lock.json
rename to package-lock.json
index 984495e..360562f 100644
--- a/react-burger/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,7 @@
"name": "react-burger",
"version": "0.1.0",
"dependencies": {
+ "@reduxjs/toolkit": "^2.0.1",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
@@ -17,8 +18,13 @@
"@types/react-dom": "^18.2.15",
"@ya.praktikum/react-developer-burger-ui-components": "^1.14.0",
"react": "^18.2.0",
+ "react-dnd": "^16.0.1",
+ "react-dnd-html5-backend": "^16.0.1",
"react-dom": "^18.2.0",
+ "react-redux": "^9.0.4",
"react-scripts": "^5.0.1",
+ "redux": "^5.0.1",
+ "redux-thunk": "^3.1.0",
"typescript": "^4.9.5",
"web-vitals": "^2.1.4"
}
@@ -3248,6 +3254,53 @@
}
}
},
+ "node_modules/@react-dnd/asap": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-5.0.2.tgz",
+ "integrity": "sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A=="
+ },
+ "node_modules/@react-dnd/invariant": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-4.0.2.tgz",
+ "integrity": "sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw=="
+ },
+ "node_modules/@react-dnd/shallowequal": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz",
+ "integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA=="
+ },
+ "node_modules/@reduxjs/toolkit": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.0.1.tgz",
+ "integrity": "sha512-fxIjrR9934cmS8YXIGd9e7s1XRsEU++aFc9DVNMFMRTM5Vtsg2DCRMj21eslGtDt43IUf9bJL3h5bwUlZleibA==",
+ "dependencies": {
+ "immer": "^10.0.3",
+ "redux": "^5.0.0",
+ "redux-thunk": "^3.1.0",
+ "reselect": "^5.0.1"
+ },
+ "peerDependencies": {
+ "react": "^16.9.0 || ^17.0.0 || ^18",
+ "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "react": {
+ "optional": true
+ },
+ "react-redux": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@reduxjs/toolkit/node_modules/immer": {
+ "version": "10.0.3",
+ "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.3.tgz",
+ "integrity": "sha512-pwupu3eWfouuaowscykeckFmVTpqbzW+rXFCX8rQLkZzM9ftBmU/++Ra+o+L27mz03zJTlyV4UUr+fdKNffo4A==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/immer"
+ }
+ },
"node_modules/@rollup/plugin-babel": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
@@ -4213,6 +4266,11 @@
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.6.tgz",
"integrity": "sha512-HYtNooPvUY9WAVRBr4u+4Qa9fYD1ze2IUlAD3HoA6oehn1taGwBx3Oa52U4mTslTS+GAExKpaFu39Y5xUEwfjg=="
},
+ "node_modules/@types/use-sync-external-store": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
+ "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
+ },
"node_modules/@types/ws": {
"version": "8.5.9",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.9.tgz",
@@ -6694,6 +6752,24 @@
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="
},
+ "node_modules/dnd-core": {
+ "version": "16.0.1",
+ "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-16.0.1.tgz",
+ "integrity": "sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==",
+ "dependencies": {
+ "@react-dnd/asap": "^5.0.1",
+ "@react-dnd/invariant": "^4.0.1",
+ "redux": "^4.2.0"
+ }
+ },
+ "node_modules/dnd-core/node_modules/redux": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
+ "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
+ "dependencies": {
+ "@babel/runtime": "^7.9.2"
+ }
+ },
"node_modules/dns-equal": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
@@ -8718,6 +8794,19 @@
"he": "bin/he"
}
},
+ "node_modules/hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+ "dependencies": {
+ "react-is": "^16.7.0"
+ }
+ },
+ "node_modules/hoist-non-react-statics/node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ },
"node_modules/hoopy": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
@@ -14478,6 +14567,43 @@
"node": ">=8"
}
},
+ "node_modules/react-dnd": {
+ "version": "16.0.1",
+ "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-16.0.1.tgz",
+ "integrity": "sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==",
+ "dependencies": {
+ "@react-dnd/invariant": "^4.0.1",
+ "@react-dnd/shallowequal": "^4.0.1",
+ "dnd-core": "^16.0.1",
+ "fast-deep-equal": "^3.1.3",
+ "hoist-non-react-statics": "^3.3.2"
+ },
+ "peerDependencies": {
+ "@types/hoist-non-react-statics": ">= 3.3.1",
+ "@types/node": ">= 12",
+ "@types/react": ">= 16",
+ "react": ">= 16.14"
+ },
+ "peerDependenciesMeta": {
+ "@types/hoist-non-react-statics": {
+ "optional": true
+ },
+ "@types/node": {
+ "optional": true
+ },
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-dnd-html5-backend": {
+ "version": "16.0.1",
+ "resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz",
+ "integrity": "sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==",
+ "dependencies": {
+ "dnd-core": "^16.0.1"
+ }
+ },
"node_modules/react-dom": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
@@ -14500,6 +14626,32 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
},
+ "node_modules/react-redux": {
+ "version": "9.0.4",
+ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.0.4.tgz",
+ "integrity": "sha512-9J1xh8sWO0vYq2sCxK2My/QO7MzUMRi3rpiILP/+tDr8krBHixC6JMM17fMK88+Oh3e4Ae6/sHIhNBgkUivwFA==",
+ "dependencies": {
+ "@types/use-sync-external-store": "^0.0.3",
+ "use-sync-external-store": "^1.0.0"
+ },
+ "peerDependencies": {
+ "@types/react": "^18.2.25",
+ "react": "^18.0",
+ "react-native": ">=0.69",
+ "redux": "^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ },
+ "redux": {
+ "optional": true
+ }
+ }
+ },
"node_modules/react-refresh": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
@@ -14635,6 +14787,19 @@
"node": ">=8"
}
},
+ "node_modules/redux": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
+ "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w=="
+ },
+ "node_modules/redux-thunk": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz",
+ "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==",
+ "peerDependencies": {
+ "redux": "^5.0.0"
+ }
+ },
"node_modules/reflect.getprototypeof": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz",
@@ -14780,6 +14945,11 @@
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
},
+ "node_modules/reselect": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.0.1.tgz",
+ "integrity": "sha512-D72j2ubjgHpvuCiORWkOUxndHJrxDaSolheiz5CO+roz8ka97/4msh2E8F5qay4GawR5vzBt5MkbDHT+Rdy/Wg=="
+ },
"node_modules/resolve": {
"version": "1.22.8",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
@@ -16648,6 +16818,14 @@
"requires-port": "^1.0.0"
}
},
+ "node_modules/use-sync-external-store": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
+ "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
diff --git a/react-burger/package.json b/package.json
similarity index 84%
rename from react-burger/package.json
rename to package.json
index e4e2a4b..3933cf0 100644
--- a/react-burger/package.json
+++ b/package.json
@@ -3,6 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
+ "@reduxjs/toolkit": "^2.0.1",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
@@ -12,8 +13,13 @@
"@types/react-dom": "^18.2.15",
"@ya.praktikum/react-developer-burger-ui-components": "^1.14.0",
"react": "^18.2.0",
+ "react-dnd": "^16.0.1",
+ "react-dnd-html5-backend": "^16.0.1",
"react-dom": "^18.2.0",
+ "react-redux": "^9.0.4",
"react-scripts": "^5.0.1",
+ "redux": "^5.0.1",
+ "redux-thunk": "^3.1.0",
"typescript": "^4.9.5",
"web-vitals": "^2.1.4"
},
diff --git a/react-burger/public/favicon.ico b/public/favicon.ico
similarity index 100%
rename from react-burger/public/favicon.ico
rename to public/favicon.ico
diff --git a/react-burger/public/index.html b/public/index.html
similarity index 100%
rename from react-burger/public/index.html
rename to public/index.html
diff --git a/react-burger/public/logo192.png b/public/logo192.png
similarity index 100%
rename from react-burger/public/logo192.png
rename to public/logo192.png
diff --git a/react-burger/public/logo512.png b/public/logo512.png
similarity index 100%
rename from react-burger/public/logo512.png
rename to public/logo512.png
diff --git a/react-burger/public/manifest.json b/public/manifest.json
similarity index 100%
rename from react-burger/public/manifest.json
rename to public/manifest.json
diff --git a/react-burger/public/robots.txt b/public/robots.txt
similarity index 100%
rename from react-burger/public/robots.txt
rename to public/robots.txt
diff --git a/react-burger/.gitignore b/react-burger/.gitignore
deleted file mode 100644
index 4d29575..0000000
--- a/react-burger/.gitignore
+++ /dev/null
@@ -1,23 +0,0 @@
-# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
-
-# dependencies
-/node_modules
-/.pnp
-.pnp.js
-
-# testing
-/coverage
-
-# production
-/build
-
-# misc
-.DS_Store
-.env.local
-.env.development.local
-.env.test.local
-.env.production.local
-
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
diff --git a/react-burger/src/components/burger-constructor/burger-constructor.tsx b/react-burger/src/components/burger-constructor/burger-constructor.tsx
deleted file mode 100644
index 842bed8..0000000
--- a/react-burger/src/components/burger-constructor/burger-constructor.tsx
+++ /dev/null
@@ -1,57 +0,0 @@
-import React, { useState } from 'react';
-import { CurrencyIcon, Button } from '@ya.praktikum/react-developer-burger-ui-components'
-import { ConstructorTopElement, ConstructorBottomElement, ConstructorMidElement } from './constructor-element/constructor-element';
-import { IngredientsType } from '../burger-ingredients/burger-ingredients-types';
-import styles from "./burger-constructor.module.css"
-import OrderDetails from '../orders-details/orders-details';
-
-export function BurgerConstructor(props: IngredientsType) {
- let orderAmount = 2 * Number(props.buns[0]?.price ?? 0);
-
- const [amount, changeAmount] = useState(0)
-
- props.sauces.forEach((item) => {
- orderAmount += Number(item.price);
- })
-
- props.mains.forEach((item) => {
- orderAmount += Number(item.price);
- })
-
- const [isModalOpen, setIsModalOpen] = useState(false);
- const [modalHeader, setModalHeader] = useState("");
-
-
- function onModalClose() {
- setIsModalOpen(false);
- }
-
- function onModalOpen() {
- setModalHeader("");
- setIsModalOpen(true);
- }
-
- return(
-
-
-
- {props.sauces.map((item) => {
- return
- })}
- {props.mains.map((item) => {
- return
- })}
-
-
-
-
-
-
{ orderAmount }
-
-
- {isModalOpen && (
-
- )}
-
- )
-}
\ No newline at end of file
diff --git a/react-burger/src/components/burger-ingredients/burger-ingredients.tsx b/react-burger/src/components/burger-ingredients/burger-ingredients.tsx
deleted file mode 100644
index 3f8bc32..0000000
--- a/react-burger/src/components/burger-ingredients/burger-ingredients.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import React from 'react';
-import styles from "./burger-ingredients.module.css";
-import IngredientsTable from './ingredient-table/ingredient-table';
-import { Tab } from '@ya.praktikum/react-developer-burger-ui-components'
-import { IngredientsType } from './burger-ingredients-types';
-
-export default function BurgerIngredients(props: IngredientsType) {
- const [current, setCurrent] = React.useState('bun')
-
- return(
-
-
Соберите бургер
-
-
-
- Булка
-
-
- Соус
-
-
- Основа
-
-
-
-
-
-
-
-
-
- )
-
-}
\ No newline at end of file
diff --git a/react-burger/src/components/burger-ingredients/ingredient-table/card/card.tsx b/react-burger/src/components/burger-ingredients/ingredient-table/card/card.tsx
deleted file mode 100644
index ab0e09b..0000000
--- a/react-burger/src/components/burger-ingredients/ingredient-table/card/card.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import React, { useState } from 'react';
-import { CurrencyIcon } from '@ya.praktikum/react-developer-burger-ui-components'
-import { cardData } from './data';
-import styles from './card.module.css';
-import Modal from '../../../modal/modal';
-import IngredientDetails from '../../../ingredient-details/ingredient-details';
-import { Ingredients } from '../../../../services/get-ingredients/get-ingredients-types';
-
-export default function IngredientCard(props: cardData) {
- const [isModalOpen, setIsModalOpen] = useState(false);
- const [modalData, setModalData] = useState();
-
- function onModalClose() {
- setIsModalOpen(false);
- }
-
- function onModalOpen(header: string, item: Ingredients) {
- setModalData(item);
- setIsModalOpen(true);
- }
-
- return(
- <>
- onModalOpen(props.name, props.item)}>
-

-
{ props.price }
-
{ props.name }
-
- {isModalOpen && (
-
-
-
- )}
- >
- )
-}
\ No newline at end of file
diff --git a/react-burger/src/components/main/main.tsx b/react-burger/src/components/main/main.tsx
deleted file mode 100644
index 176a3ec..0000000
--- a/react-burger/src/components/main/main.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import React, { useState, useEffect, ReactNode } from 'react';
-import BurgerIngredients from '../burger-ingredients/burger-ingredients';
-import { BurgerConstructor } from '../burger-constructor/burger-constructor';
-import getIngredients from '../../services/get-ingredients/get-ingredients';
-import { Ingredients } from '../../services/get-ingredients/get-ingredients-types';
-import styles from "./main.module.css";
-
-
-export default function MainContent() {
- const [main, setMainData] = useState([])
- const [bun, setBunData] = useState([])
- const [sauce, setSauceData] = useState([])
- const [loading, setLoaded] = useState(false)
-
- useEffect(() => {
- async function getData() {
- const url = "https://norma.nomoreparties.space/api/ingredients";
- const res = await getIngredients(url);
-
- setMainData(res.data.filter((item: Ingredients) => item.type === "main"))
- setBunData(res.data.filter((item: Ingredients) => item.type === "bun"))
- setSauceData(res.data.filter((item: Ingredients) => item.type === "sauce"))
- setLoaded(Boolean(res.success));
- }
- getData().catch((err) => console.log("error while recieveng data: ", err));
- }, [])
-
- const [modalChild, setModalChild] = React.useState('');
- const [modalHeader, setModalHeader] = React.useState('');
-
-
- if (loading) {
- return (
-
-
-
-
- );
- }
- return (
- <>>
- );
-}
\ No newline at end of file
diff --git a/react-burger/src/services/get-ingredients/get-ingredients.ts b/react-burger/src/services/get-ingredients/get-ingredients.ts
deleted file mode 100644
index 1a8ea95..0000000
--- a/react-burger/src/services/get-ingredients/get-ingredients.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { IngredientsResp } from "./get-ingredients-types";
-
-const getIngredients = async(url: string): Promise => {
- const resp = await fetch(url);
- if (resp.ok) {
- return resp.json();
- }
- return Promise.reject(`Ошибка ${resp.status}`);
-}
-
-export default getIngredients;
\ No newline at end of file
diff --git a/react-burger/src/components/App/app.module.css b/src/components/App/app.module.css
similarity index 100%
rename from react-burger/src/components/App/app.module.css
rename to src/components/App/app.module.css
diff --git a/react-burger/src/components/App/app.tsx b/src/components/App/app.tsx
similarity index 100%
rename from react-burger/src/components/App/app.tsx
rename to src/components/App/app.tsx
diff --git a/react-burger/src/components/app-header/app-header.module.css b/src/components/app-header/app-header.module.css
similarity index 100%
rename from react-burger/src/components/app-header/app-header.module.css
rename to src/components/app-header/app-header.module.css
diff --git a/react-burger/src/components/app-header/app-header.tsx b/src/components/app-header/app-header.tsx
similarity index 100%
rename from react-burger/src/components/app-header/app-header.tsx
rename to src/components/app-header/app-header.tsx
diff --git a/react-burger/src/components/burger-constructor/burger-constructor-types.ts b/src/components/burger-constructor/burger-constructor-types.ts
similarity index 100%
rename from react-burger/src/components/burger-constructor/burger-constructor-types.ts
rename to src/components/burger-constructor/burger-constructor-types.ts
diff --git a/src/components/burger-constructor/burger-constructor.jsx b/src/components/burger-constructor/burger-constructor.jsx
new file mode 100644
index 0000000..60a48ef
--- /dev/null
+++ b/src/components/burger-constructor/burger-constructor.jsx
@@ -0,0 +1,96 @@
+import { useCallback, useRef, useState } from 'react';
+import { Button } from '@ya.praktikum/react-developer-burger-ui-components'
+import styles from "./burger-constructor.module.css"
+import OrderDetails from '../orders-details/orders-details';
+import { useDispatch, useSelector } from 'react-redux';
+import {addIngredient, changeBun, sendIngredients} from '../../services/actions/constructor-action';
+import {
+ ConstructorBottomElement,
+ ConstructorMidElement,
+ ConstructorTopElement
+} from './constructor-element/constructor-element';
+import { CurrencyIcon } from '@ya.praktikum/react-developer-burger-ui-components';
+import { useDrop } from "react-dnd";
+import { clearConstructor } from '../../services/actions/constructor-action';
+
+export function BurgerConstructor() {
+ const myRef = useRef();
+ const handleAdding = (item, pos) => {
+ if (item && item.type === 'bun') {
+ dispatch(changeBun(item));
+ } else {
+ dispatch(addIngredient(item));
+ }
+ }
+
+ const [order, setOrder] = useState("");
+
+ const [isModalOpen, setIsModalOpen] = useState(false);
+
+
+ const dispatch = useDispatch();
+ const {elements, bun} = useSelector((state) => state.elementConstructor)
+
+ const [{ isOver }, drop] = useDrop(() => ({
+ accept: 'card',
+ drop: (item) => {
+ handleAdding(item, elements.length);
+ },
+ collect: (monitor) => ({
+ isOver: !!monitor.isOver(),
+ }),
+ }))
+
+ const [{ isOverBetween }, dropBetween] = useDrop(() => ({
+ accept: 'cardBetween',
+ collect: (monitor) => ({
+ isOverBetween: monitor.isOver(),
+ }),
+ }))
+
+ function onModalClose() {
+ setIsModalOpen(false);
+ }
+
+ const calcOrderSum = useCallback(() => {
+ return 2 * (bun?.price ?? 0) + elements.reduce((acc, item) => {
+ return acc + item.price
+ }, 0)
+ }, [elements, bun])
+
+ const makeOrder = useCallback(async () => {
+ const baseElements = elements.map(elem => elem._id);
+ const orderDetails = await sendIngredients({ ingredients: (bun ? baseElements.concat(bun._id) : baseElements)})
+ dispatch(clearConstructor());
+
+ orderDetails && setOrder(orderDetails.order.number.toString())
+ setIsModalOpen(true);
+ }, [elements, bun])
+
+ return(
+
+
+ { bun && (
+
+ )}
+
+ {elements.map((item, index) => {
+ return
+ })}
+
+
+ { bun && (
+
+ )}
+
+
+
+
{ calcOrderSum() }
+
+
+ {isModalOpen && (
+
+ )}
+
+ )
+}
\ No newline at end of file
diff --git a/react-burger/src/components/burger-constructor/burger-constructor.module.css b/src/components/burger-constructor/burger-constructor.module.css
similarity index 66%
rename from react-burger/src/components/burger-constructor/burger-constructor.module.css
rename to src/components/burger-constructor/burger-constructor.module.css
index b8c7b8d..01c578e 100644
--- a/react-burger/src/components/burger-constructor/burger-constructor.module.css
+++ b/src/components/burger-constructor/burger-constructor.module.css
@@ -2,7 +2,7 @@
display: flex;
flex-direction: column;
overflow-y: scroll;
- height: calc(100vh - 532px);
+ height: calc(100vh - 342px);
gap: 10px;
}
@@ -12,4 +12,10 @@
justify-content: center;
align-items: center;
height: auto;
+}
+
+.mainElements {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
}
\ No newline at end of file
diff --git a/react-burger/src/components/burger-constructor/constructor-element/burger-element.module.css b/src/components/burger-constructor/constructor-element/burger-element.module.css
similarity index 100%
rename from react-burger/src/components/burger-constructor/constructor-element/burger-element.module.css
rename to src/components/burger-constructor/constructor-element/burger-element.module.css
diff --git a/react-burger/src/components/burger-constructor/constructor-element/constructor-element-types.ts b/src/components/burger-constructor/constructor-element/constructor-element-types.ts
similarity index 90%
rename from react-burger/src/components/burger-constructor/constructor-element/constructor-element-types.ts
rename to src/components/burger-constructor/constructor-element/constructor-element-types.ts
index 8b9a307..ee26e12 100644
--- a/react-burger/src/components/burger-constructor/constructor-element/constructor-element-types.ts
+++ b/src/components/burger-constructor/constructor-element/constructor-element-types.ts
@@ -3,4 +3,5 @@ import { Ingredients } from "../../../services/get-ingredients/get-ingredients-t
export interface ElementProps {
isLocked: boolean;
item: Ingredients;
+ index: number;
}
\ No newline at end of file
diff --git a/react-burger/src/components/burger-constructor/constructor-element/constructor-element.tsx b/src/components/burger-constructor/constructor-element/constructor-element.jsx
similarity index 50%
rename from react-burger/src/components/burger-constructor/constructor-element/constructor-element.tsx
rename to src/components/burger-constructor/constructor-element/constructor-element.jsx
index afbafe7..1df3e13 100644
--- a/react-burger/src/components/burger-constructor/constructor-element/constructor-element.tsx
+++ b/src/components/burger-constructor/constructor-element/constructor-element.jsx
@@ -1,9 +1,12 @@
import React from 'react';
import { ConstructorElement, DragIcon } from '@ya.praktikum/react-developer-burger-ui-components'
-import { ElementProps } from './constructor-element-types';
import styles from "./burger-element.module.css"
+import { useDispatch } from 'react-redux';
+import {removeIngredients, swapElements} from '../../../services/actions/constructor-action';
+import { useDrag, useDrop } from 'react-dnd';
+import { useRef } from 'react';
-export function ConstructorTopElement(props: ElementProps) {
+export function ConstructorTopElement(props) {
return(
@@ -20,7 +23,7 @@ export function ConstructorTopElement(props: ElementProps) {
)
}
-export function ConstructorBottomElement(props: ElementProps) {
+export function ConstructorBottomElement(props) {
return(
@@ -37,18 +40,42 @@ export function ConstructorBottomElement(props: ElementProps) {
)
}
-export function ConstructorMidElement(props: ElementProps) {
+export function ConstructorMidElement({ index, isLocked, item }) {
+ const dispatch = useDispatch();
+ const ref = useRef();
+
+ const [{ isDragging}, dragBetween] = useDrag(() => ({
+ type: 'cardBetween',
+ item: { index },
+ collect: (monitor) => ({
+ isDragging: monitor.isDragging(),
+ })
+ }))
+
+ const [{ isOverBetween }, dropBetween] = useDrop(() => ({
+ accept: 'cardBetween',
+ collect: (monitor) => ({
+ isOverBetween: monitor.isOver(),
+ }),
+ drop: (curItem) => {
+ dispatch(swapElements(curItem.index, index));
+ }
+ }))
+
return(
-
+
{
+ dispatch(removeIngredients(index));
+ }}
/>
- {!props.isLocked ?
: null }
+ {!isLocked ?
: null }
)
}
\ No newline at end of file
diff --git a/react-burger/src/components/burger-ingredients/burger-ingredients-types.ts b/src/components/burger-ingredients/burger-ingredients-types.ts
similarity index 100%
rename from react-burger/src/components/burger-ingredients/burger-ingredients-types.ts
rename to src/components/burger-ingredients/burger-ingredients-types.ts
diff --git a/react-burger/src/components/burger-ingredients/burger-ingredients.module.css b/src/components/burger-ingredients/burger-ingredients.module.css
similarity index 100%
rename from react-burger/src/components/burger-ingredients/burger-ingredients.module.css
rename to src/components/burger-ingredients/burger-ingredients.module.css
diff --git a/src/components/burger-ingredients/burger-ingredients.tsx b/src/components/burger-ingredients/burger-ingredients.tsx
new file mode 100644
index 0000000..2ff0e3d
--- /dev/null
+++ b/src/components/burger-ingredients/burger-ingredients.tsx
@@ -0,0 +1,111 @@
+import React, { useCallback, useMemo } from 'react';
+import styles from "./burger-ingredients.module.css";
+import IngredientsTable from './ingredient-table/ingredient-table';
+import { Tab } from '@ya.praktikum/react-developer-burger-ui-components'
+import { IngredientsType } from './burger-ingredients-types';
+import { useSelector } from 'react-redux';
+import store from '../../services/reducers/store';
+import { RootState } from '../../services/reducers/store';
+import { AppDispatch } from '../../services/reducers/store';
+import { useDispatch } from 'react-redux';
+import { useEffect } from 'react';
+import { initialiseIngredients } from '../../services/actions/ingredients-actions';
+import { useRef } from 'react';
+
+export default function BurgerIngredients() {
+ const dispatch = useDispatch
();
+ const [current, setCurrent] = React.useState('bun')
+
+ const bunTabRef = useRef(null);
+ const sauceTabRef = useRef(null);
+ const mainTabRef = useRef(null);
+ const menuRef = useRef(null);
+
+ useEffect(() => {
+ dispatch(initialiseIngredients());
+ }, []);
+
+ const menuAbsoluteHeightHalf = useMemo(() => {
+ return menuRef.current?.offsetHeight ?? 0;
+ }, [menuRef.current?.offsetHeight]);
+
+ useEffect(() => {
+ const menu = menuRef.current;
+ if (menu) {
+ const onScroll = () => {
+ const bunTab = bunTabRef.current;
+ const sauceTab = sauceTabRef.current;
+ const mainTab = mainTabRef.current;
+
+ if (bunTab && sauceTab && mainTab) {
+ const bunTabTop = bunTab.getBoundingClientRect().top;
+ const sauceTabTop = sauceTab.getBoundingClientRect().top;
+ const mainTabTop = mainTab.getBoundingClientRect().top;
+
+ if (bunTabTop >= 0 && bunTabTop <= menuAbsoluteHeightHalf) {
+ setCurrent('bun');
+ } else if (sauceTabTop >= 0 && sauceTabTop <= menuAbsoluteHeightHalf) {
+ setCurrent('sauce');
+ } else if (mainTabTop >= 0 && mainTabTop <= menuAbsoluteHeightHalf) {
+ setCurrent('main');
+ }
+ }
+ };
+
+ menu.addEventListener('scroll', onScroll);
+ return () => {
+ menu.removeEventListener('scroll', onScroll);
+ };
+ }
+ }, [menuRef.current?.offsetHeight]);
+
+ const scrollToTab = useCallback((current: string) => {
+ if (current === 'bun') {
+ bunTabRef.current?.scrollIntoView({ behavior: 'smooth' });
+ } else if (current === 'sauce') {
+ sauceTabRef.current?.scrollIntoView({ behavior: 'smooth' });
+ } else if (current === 'main') {
+ mainTabRef.current?.scrollIntoView({ behavior: 'smooth' });
+ }
+ }, [current]);
+
+ const handleTabClick = useCallback((current: string) => {
+ setCurrent(current);
+ scrollToTab(current);
+ }, [current]);
+
+ // const { buns, mains, sauces } = useSelector((store: RootState) => ({
+ // buns: store.ingredients.bun,
+ // mains: store.ingredients.main,
+ // sauces: store.ingredients.sauce
+ // }))
+
+ const buns = useSelector((store: RootState) => store.ingredients.bun);
+ const mains = useSelector((store: RootState) => store.ingredients.main);
+ const sauces = useSelector((store: RootState) => store.ingredients.sauce);
+
+ return(
+
+
Соберите бургер
+
+
+
+ Булка
+
+
+ Соус
+
+
+ Основа
+
+
+
+
+
+
+
+
+
+ )
+
+}
\ No newline at end of file
diff --git a/react-burger/src/components/burger-ingredients/ingredient-table/card/card.module.css b/src/components/burger-ingredients/ingredient-table/card/card.module.css
similarity index 55%
rename from react-burger/src/components/burger-ingredients/ingredient-table/card/card.module.css
rename to src/components/burger-ingredients/ingredient-table/card/card.module.css
index c522e17..207f286 100644
--- a/react-burger/src/components/burger-ingredients/ingredient-table/card/card.module.css
+++ b/src/components/burger-ingredients/ingredient-table/card/card.module.css
@@ -23,4 +23,18 @@
.img {
width: 80%;
+}
+
+.amount {
+ border-radius: 50%;
+ background-color: #4C4CFF;
+ width: 35px;
+ height: 35px;
+ margin-left: auto;
+ margin-right: 20px;
+ margin-top: auto;
+ margin-bottom: -35px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
}
\ No newline at end of file
diff --git a/src/components/burger-ingredients/ingredient-table/card/card.tsx b/src/components/burger-ingredients/ingredient-table/card/card.tsx
new file mode 100644
index 0000000..2907460
--- /dev/null
+++ b/src/components/burger-ingredients/ingredient-table/card/card.tsx
@@ -0,0 +1,62 @@
+import React, { useState } from 'react';
+import { CurrencyIcon } from '@ya.praktikum/react-developer-burger-ui-components'
+import { cardData } from './data';
+import styles from './card.module.css';
+import Modal from '../../../modal/modal';
+import IngredientDetails from '../../../ingredient-details/ingredient-details';
+import { Ingredients } from '../../../../services/get-ingredients/get-ingredients-types';
+import { useSelector } from 'react-redux';
+import { RootState } from '../../../../services/reducers/store';
+import { useDispatch } from 'react-redux';
+import { AppDispatch } from '../../../../services/reducers/store';
+import { closeModal, openModal } from '../../../../services/actions/modal-action';
+import {useDrag} from "react-dnd";
+
+function countElements (elems: Ingredients[], bun: Ingredients | null, _id: string) {
+ let ans = 0;
+ for (let i = 0; i < elems.length; i++) {
+ if (elems[i]._id === _id) {
+ ans++;
+ }
+ }
+ if (bun && bun._id === _id) {
+ ans++;
+ }
+ return ans;
+}
+
+export default function IngredientCard(props: Ingredients) {
+ const [isModalOpen, setIsModalOpen] = useState(false);
+ const [modalData, setModalData] = useState();
+
+ const dispatch = useDispatch();
+ const modalElement = useSelector((state: RootState) => state.modalWindow)
+
+ const [{isDragging}, drag] = useDrag(() => ({
+ type: 'card',
+ item: props,
+ collect: (monitor) => ({
+ isDragging: monitor.isDragging(),
+ })
+ }))
+
+ const { elements, bun } = useSelector((state: RootState) => state.elementConstructor)
+
+ return(
+ <>
+ dispatch(openModal(props))}>
+ {countElements(elements, bun, props._id) !== 0 && (
+
{countElements(elements, bun, props._id)}
+ )}
+

+
{ props.price }
+
{ props.name }
+
+ {modalElement.isOpened && (
+ dispatch(closeModal()) } header={"Детали ингредиента"}>
+ dispatch(closeModal()) }/>
+
+ )}
+ >
+ )
+}
\ No newline at end of file
diff --git a/react-burger/src/components/burger-ingredients/ingredient-table/card/data.ts b/src/components/burger-ingredients/ingredient-table/card/data.ts
similarity index 100%
rename from react-burger/src/components/burger-ingredients/ingredient-table/card/data.ts
rename to src/components/burger-ingredients/ingredient-table/card/data.ts
diff --git a/react-burger/src/components/burger-ingredients/ingredient-table/ingredient-item-name.ts b/src/components/burger-ingredients/ingredient-table/ingredient-item-name.ts
similarity index 79%
rename from react-burger/src/components/burger-ingredients/ingredient-table/ingredient-item-name.ts
rename to src/components/burger-ingredients/ingredient-table/ingredient-item-name.ts
index 545e19f..f5e2d00 100644
--- a/react-burger/src/components/burger-ingredients/ingredient-table/ingredient-item-name.ts
+++ b/src/components/burger-ingredients/ingredient-table/ingredient-item-name.ts
@@ -3,4 +3,5 @@ import { Ingredients } from "../../../services/get-ingredients/get-ingredients-t
export interface IngredientsItemType {
name: string;
items: Array;
+ innerRef: React.RefObject;
}
\ No newline at end of file
diff --git a/react-burger/src/components/burger-ingredients/ingredient-table/ingredient-table.module.css b/src/components/burger-ingredients/ingredient-table/ingredient-table.module.css
similarity index 100%
rename from react-burger/src/components/burger-ingredients/ingredient-table/ingredient-table.module.css
rename to src/components/burger-ingredients/ingredient-table/ingredient-table.module.css
diff --git a/react-burger/src/components/burger-ingredients/ingredient-table/ingredient-table.tsx b/src/components/burger-ingredients/ingredient-table/ingredient-table.tsx
similarity index 77%
rename from react-burger/src/components/burger-ingredients/ingredient-table/ingredient-table.tsx
rename to src/components/burger-ingredients/ingredient-table/ingredient-table.tsx
index 27e7bdf..9f65d00 100644
--- a/react-burger/src/components/burger-ingredients/ingredient-table/ingredient-table.tsx
+++ b/src/components/burger-ingredients/ingredient-table/ingredient-table.tsx
@@ -8,11 +8,11 @@ import Modal from '../../modal/modal';
export default function IngredientsTable(props: IngredientsItemType) {
return(
-
+
{ props.name }
- { props.items.map((item) => (
-
+ { props.items.map((item, pos) => (
+
))}
diff --git a/react-burger/src/components/ingredient-details/ingredient-deatail-types.ts b/src/components/ingredient-details/ingredient-deatail-types.ts
similarity index 87%
rename from react-burger/src/components/ingredient-details/ingredient-deatail-types.ts
rename to src/components/ingredient-details/ingredient-deatail-types.ts
index adbe303..55fb3c8 100644
--- a/react-burger/src/components/ingredient-details/ingredient-deatail-types.ts
+++ b/src/components/ingredient-details/ingredient-deatail-types.ts
@@ -1,6 +1,5 @@
import { Ingredients } from "../../services/get-ingredients/get-ingredients-types";
export interface IngredientDetailsType {
- item?: Ingredients;
onModalClose: () => void;
}
\ No newline at end of file
diff --git a/react-burger/src/components/ingredient-details/ingredient-details.module.css b/src/components/ingredient-details/ingredient-details.module.css
similarity index 100%
rename from react-burger/src/components/ingredient-details/ingredient-details.module.css
rename to src/components/ingredient-details/ingredient-details.module.css
diff --git a/react-burger/src/components/ingredient-details/ingredient-details.tsx b/src/components/ingredient-details/ingredient-details.tsx
similarity index 66%
rename from react-burger/src/components/ingredient-details/ingredient-details.tsx
rename to src/components/ingredient-details/ingredient-details.tsx
index 847e179..7a36fec 100644
--- a/react-burger/src/components/ingredient-details/ingredient-details.tsx
+++ b/src/components/ingredient-details/ingredient-details.tsx
@@ -2,8 +2,15 @@ import Modal from '../modal/modal';
import { IngredientDetailsType } from './ingredient-deatail-types';
import styles from "./ingredient-details.module.css"
import IngredientSubstance from './ingredient-substance/ingredient-substance';
+import { useDispatch } from 'react-redux';
+import { AppDispatch } from '../../services/reducers/store';
+import { useSelector } from 'react-redux';
+import { RootState } from '../../services/reducers/store';
+
+export default function IngredientDetails(onModalClose: IngredientDetailsType) {
+ const dispatch = useDispatch
();
+ const item = useSelector((state: RootState) => state.modalWindow.modalData)
-export default function IngredientDetails({item, onModalClose}: IngredientDetailsType) {
return(
<>
diff --git a/react-burger/src/components/ingredient-details/ingredient-substance/ingredient-substance.module.css b/src/components/ingredient-details/ingredient-substance/ingredient-substance.module.css
similarity index 100%
rename from react-burger/src/components/ingredient-details/ingredient-substance/ingredient-substance.module.css
rename to src/components/ingredient-details/ingredient-substance/ingredient-substance.module.css
diff --git a/react-burger/src/components/ingredient-details/ingredient-substance/ingredient-substance.tsx b/src/components/ingredient-details/ingredient-substance/ingredient-substance.tsx
similarity index 100%
rename from react-burger/src/components/ingredient-details/ingredient-substance/ingredient-substance.tsx
rename to src/components/ingredient-details/ingredient-substance/ingredient-substance.tsx
diff --git a/react-burger/src/components/ingredient-details/ingredient-substance/ingredient-substancse-types.ts b/src/components/ingredient-details/ingredient-substance/ingredient-substancse-types.ts
similarity index 100%
rename from react-burger/src/components/ingredient-details/ingredient-substance/ingredient-substancse-types.ts
rename to src/components/ingredient-details/ingredient-substance/ingredient-substancse-types.ts
diff --git a/react-burger/src/components/main/main.module.css b/src/components/main/main.module.css
similarity index 100%
rename from react-burger/src/components/main/main.module.css
rename to src/components/main/main.module.css
diff --git a/src/components/main/main.tsx b/src/components/main/main.tsx
new file mode 100644
index 0000000..a8c8afb
--- /dev/null
+++ b/src/components/main/main.tsx
@@ -0,0 +1,17 @@
+import React, { useState, useEffect, ReactNode } from 'react';
+import BurgerIngredients from '../burger-ingredients/burger-ingredients';
+import { BurgerConstructor } from '../burger-constructor/burger-constructor';
+import styles from "./main.module.css";
+import {DndProvider} from "react-dnd";
+import {HTML5Backend} from "react-dnd-html5-backend";
+
+export default function MainContent() {
+ return (
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/react-burger/src/components/modal-overlay/modal-overlay.module.css b/src/components/modal-overlay/modal-overlay.module.css
similarity index 100%
rename from react-burger/src/components/modal-overlay/modal-overlay.module.css
rename to src/components/modal-overlay/modal-overlay.module.css
diff --git a/react-burger/src/components/modal-overlay/modal-overlay.tsx b/src/components/modal-overlay/modal-overlay.tsx
similarity index 100%
rename from react-burger/src/components/modal-overlay/modal-overlay.tsx
rename to src/components/modal-overlay/modal-overlay.tsx
diff --git a/react-burger/src/components/modal/modal-type.ts b/src/components/modal/modal-type.ts
similarity index 100%
rename from react-burger/src/components/modal/modal-type.ts
rename to src/components/modal/modal-type.ts
diff --git a/react-burger/src/components/modal/modal.module.css b/src/components/modal/modal.module.css
similarity index 100%
rename from react-burger/src/components/modal/modal.module.css
rename to src/components/modal/modal.module.css
diff --git a/react-burger/src/components/modal/modal.tsx b/src/components/modal/modal.tsx
similarity index 100%
rename from react-burger/src/components/modal/modal.tsx
rename to src/components/modal/modal.tsx
diff --git a/react-burger/src/components/orders-details/order-details-types.ts b/src/components/orders-details/order-details-types.ts
similarity index 88%
rename from react-burger/src/components/orders-details/order-details-types.ts
rename to src/components/orders-details/order-details-types.ts
index 28f77e8..0d82bc3 100644
--- a/react-burger/src/components/orders-details/order-details-types.ts
+++ b/src/components/orders-details/order-details-types.ts
@@ -2,4 +2,5 @@ import { Ingredients } from "../../services/get-ingredients/get-ingredients-type
export interface OrderDetailsType {
onModalClose: () => void;
+ orderId: string;
}
\ No newline at end of file
diff --git a/react-burger/src/components/orders-details/order-details.module.css b/src/components/orders-details/order-details.module.css
similarity index 100%
rename from react-burger/src/components/orders-details/order-details.module.css
rename to src/components/orders-details/order-details.module.css
diff --git a/react-burger/src/components/orders-details/orders-details.tsx b/src/components/orders-details/orders-details.tsx
similarity index 82%
rename from react-burger/src/components/orders-details/orders-details.tsx
rename to src/components/orders-details/orders-details.tsx
index c4a6788..e6d790b 100644
--- a/react-burger/src/components/orders-details/orders-details.tsx
+++ b/src/components/orders-details/orders-details.tsx
@@ -3,10 +3,10 @@ import { OrderDetailsType } from './order-details-types';
import image from "../../images/done.png"
import styles from "./order-details.module.css"
-export default function OrderDetails({onModalClose}: OrderDetailsType) {
+export default function OrderDetails({onModalClose, orderId}: OrderDetailsType) {
return(
- 034536
+ {orderId}
идендификатор заказа
Ваш заказ начали готовить
diff --git a/react-burger/src/images/done.png b/src/images/done.png
similarity index 100%
rename from react-burger/src/images/done.png
rename to src/images/done.png
diff --git a/react-burger/src/index.css b/src/index.css
similarity index 100%
rename from react-burger/src/index.css
rename to src/index.css
diff --git a/react-burger/src/index.tsx b/src/index.tsx
similarity index 68%
rename from react-burger/src/index.tsx
rename to src/index.tsx
index 3c7a027..5b8256b 100644
--- a/react-burger/src/index.tsx
+++ b/src/index.tsx
@@ -2,6 +2,8 @@ import React from 'react';
import ReactDOM from 'react-dom/client';
import reportWebVitals from './reportWebVitals';
import App from './components/App/app';
+import { Provider } from 'react-redux';
+import store from './services/reducers/store';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
@@ -9,7 +11,9 @@ const root = ReactDOM.createRoot(
root.render(
-
+
+
+
);
diff --git a/react-burger/src/react-app-env.d.ts b/src/react-app-env.d.ts
similarity index 100%
rename from react-burger/src/react-app-env.d.ts
rename to src/react-app-env.d.ts
diff --git a/react-burger/src/reportWebVitals.ts b/src/reportWebVitals.ts
similarity index 100%
rename from react-burger/src/reportWebVitals.ts
rename to src/reportWebVitals.ts
diff --git a/src/services/actions/constructor-action.ts b/src/services/actions/constructor-action.ts
new file mode 100644
index 0000000..e893fe9
--- /dev/null
+++ b/src/services/actions/constructor-action.ts
@@ -0,0 +1,31 @@
+import { Ingredients, PostOrderRequest, PostOrderResponse } from "../reducers/types";
+import { constructorActions } from "../reducers/constructor-reducer";
+import { AppDispatch } from "../reducers/store";
+import { postIngredients } from "../get-ingredients/get-ingredients";
+
+export const addIngredient = (ingredient: Ingredients) => (dispatch: AppDispatch) => {
+ dispatch(constructorActions.addIngredients(ingredient));
+}
+
+export const changeBun = (ingredient: Ingredients) => (dispatch: AppDispatch) => {
+ dispatch(constructorActions.changeBun(ingredient));
+}
+
+export const removeIngredients = (index: number) => (dispatch: AppDispatch) => {
+ dispatch(constructorActions.removeIngredients(index));
+}
+
+export const swapElements = (index1: number, index2: number) => (dispatch: AppDispatch) => {
+ dispatch(constructorActions.swapElements({firstId: index1, secondId: index2}));
+}
+
+export const sendIngredients = async (request: PostOrderRequest): Promise => {
+ const url = 'https://norma.nomoreparties.space/api/orders';
+
+ const res = await postIngredients(url, request);
+ return res;
+}
+
+export const clearConstructor = () => (dispatch: AppDispatch) => {
+ dispatch(constructorActions.clearConstructor());
+}
diff --git a/src/services/actions/ingredients-actions.ts b/src/services/actions/ingredients-actions.ts
new file mode 100644
index 0000000..0e0e286
--- /dev/null
+++ b/src/services/actions/ingredients-actions.ts
@@ -0,0 +1,14 @@
+import { getIngredients } from "../get-ingredients/get-ingredients";
+import { ingredientsActions } from "../reducers/ingredients-reducer";
+import { AppDispatch } from "../reducers/store";
+
+export const initialiseIngredients = () => {
+ const url = "https://norma.nomoreparties.space/api/ingredients";
+
+ return async (dispatch: AppDispatch) => {
+ const ingredients = await getIngredients(url);
+ if (ingredients.success) {
+ dispatch(ingredientsActions.setIngredients(ingredients.data));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/actions/modal-action.ts b/src/services/actions/modal-action.ts
new file mode 100644
index 0000000..94a1b83
--- /dev/null
+++ b/src/services/actions/modal-action.ts
@@ -0,0 +1,11 @@
+import { Ingredients } from "../reducers/types";
+import { modalActions } from "../reducers/modal-reducer";
+import { AppDispatch } from "../reducers/store";
+
+export const openModal = (ingredient: Ingredients) => (dispatch: AppDispatch) => {
+ dispatch(modalActions.setModal(ingredient));
+}
+
+export const closeModal = () => (dispatch: AppDispatch) => {
+ dispatch(modalActions.closeModal());
+}
\ No newline at end of file
diff --git a/react-burger/src/services/get-ingredients/get-ingredients-types.ts b/src/services/get-ingredients/get-ingredients-types.ts
similarity index 94%
rename from react-burger/src/services/get-ingredients/get-ingredients-types.ts
rename to src/services/get-ingredients/get-ingredients-types.ts
index b3f23ad..e5a7adb 100644
--- a/react-burger/src/services/get-ingredients/get-ingredients-types.ts
+++ b/src/services/get-ingredients/get-ingredients-types.ts
@@ -7,7 +7,7 @@ export interface Ingredients {
image_large: string;
image_mobile: string;
name: string;
- price: string;
+ price: number;
proteins: number;
type: string;
}
diff --git a/src/services/get-ingredients/get-ingredients.ts b/src/services/get-ingredients/get-ingredients.ts
new file mode 100644
index 0000000..11a82b0
--- /dev/null
+++ b/src/services/get-ingredients/get-ingredients.ts
@@ -0,0 +1,25 @@
+import { PostOrderRequest } from "../reducers/types";
+import { IngredientsResp } from "./get-ingredients-types";
+import { PostOrderResponse } from "../reducers/types";
+
+export const getIngredients = async(url: string): Promise => {
+ const resp = await fetch(url);
+ if (resp.ok) {
+ return resp.json();
+ }
+ return Promise.reject(`Ошибка ${resp.status}`);
+}
+
+export const postIngredients = async (url: string, request: PostOrderRequest): Promise => {
+ const resp = await fetch(url, {
+ method: 'POST',
+ headers: {'Content-Type': 'application/json'},
+ body: JSON.stringify(request),
+ })
+
+ if (resp.ok) {
+ return resp.json();
+ }
+
+ return Promise.reject(`Ошибка ${resp.status}`);
+}
\ No newline at end of file
diff --git a/src/services/reducers/constructor-reducer.ts b/src/services/reducers/constructor-reducer.ts
new file mode 100644
index 0000000..f740094
--- /dev/null
+++ b/src/services/reducers/constructor-reducer.ts
@@ -0,0 +1,55 @@
+import { createSlice } from "@reduxjs/toolkit";
+import { Burger } from './types';
+
+const initial = { elements: [], bun: null } as Burger;
+
+const { actions, reducer } = createSlice({
+ name: 'ELEMENT_CONSTRUCTOR',
+ initialState: initial,
+ reducers: {
+ addIngredients(state, action) {
+ return {
+ ...state,
+ elements: state.elements.concat(action.payload)
+ }
+ },
+ removeIngredients(state, action) {
+ const newElements = state.elements.slice(0, action.payload).concat(state.elements.slice(action.payload + 1));
+ return {
+ ...state,
+ elements: newElements,
+ }
+ },
+ changeBun(state, action) {
+ return {
+ ...state,
+ bun: action.payload,
+ }
+ },
+ swapElements(state, action) {
+ let index1 = action.payload.firstId;
+ let index2 = action.payload.secondId;
+ const newElements = state.elements.slice();
+ if (index1 > index2) {
+ let tmp = index1;
+ index1 = index2;
+ index2 = tmp;
+ }
+ let tmp = newElements[index2];
+ for (let i = index2; i > index1; i--) {
+ newElements[i] = newElements[i - 1];
+ }
+ newElements[index1] = tmp;
+ return {
+ ...state,
+ elements: newElements,
+ }
+ },
+ clearConstructor(state) {
+ return initial;
+ },
+ },
+})
+
+export const constructorActions = actions;
+export default reducer
\ No newline at end of file
diff --git a/src/services/reducers/ingredients-reducer.ts b/src/services/reducers/ingredients-reducer.ts
new file mode 100644
index 0000000..25be249
--- /dev/null
+++ b/src/services/reducers/ingredients-reducer.ts
@@ -0,0 +1,23 @@
+import { createSlice } from '@reduxjs/toolkit'
+import BurgerIngredients from '../../components/burger-ingredients/burger-ingredients';
+import { BurgerComponents } from './types';
+import { Ingredients } from './types';
+
+const initial: BurgerComponents = {bun: [], main: [], sauce: []}
+
+const { actions, reducer } = createSlice({
+ name: 'INGREDIENTS',
+ initialState: initial,
+ reducers: {
+ setIngredients: (state, action) => {
+ return action.payload.reduce((acc: BurgerComponents, ingredient: Ingredients) => {
+ const ingredientType = ingredient.type as keyof BurgerComponents;
+ acc[ingredientType].push(ingredient);
+ return acc;
+ }, { bun: [], main: [], sauce: [] });
+ },
+ },
+})
+
+export const ingredientsActions = actions;
+export default reducer
\ No newline at end of file
diff --git a/src/services/reducers/modal-reducer.ts b/src/services/reducers/modal-reducer.ts
new file mode 100644
index 0000000..55e5427
--- /dev/null
+++ b/src/services/reducers/modal-reducer.ts
@@ -0,0 +1,28 @@
+import { createSlice } from '@reduxjs/toolkit'
+import { Ingredients } from './types';
+
+const sampleIngredient: Ingredients = {"_id": "", "name": "", "type": "", "proteins": 0, "fat": 0, "carbohydrates": 0, "calories": 0, "price": 0, "image": "", "image_mobile": "", "image_large": "",};
+
+const initial = { isOpened: false, modalData : sampleIngredient }
+
+const { actions, reducer } = createSlice({
+ name: 'MODAL_WINDOW',
+ initialState: initial,
+ reducers: {
+ setModal(state, action) {
+ return {
+ modalData: action.payload,
+ isOpened: true
+ }
+ },
+ closeModal(state) {
+ return {
+ ...state,
+ isOpened: false
+ }
+ },
+ },
+})
+
+export const modalActions = actions;
+export default reducer
\ No newline at end of file
diff --git a/src/services/reducers/store.ts b/src/services/reducers/store.ts
new file mode 100644
index 0000000..8b73618
--- /dev/null
+++ b/src/services/reducers/store.ts
@@ -0,0 +1,21 @@
+import { configureStore } from '@reduxjs/toolkit'
+
+import ingredientsReducer from './ingredients-reducer'
+import constructorReducer from './constructor-reducer'
+import modalReducer from './modal-reducer'
+
+const store = configureStore({
+ reducer: {
+ ingredients: ingredientsReducer,
+ elementConstructor: constructorReducer,
+ modalWindow: modalReducer,
+ },
+ middleware: (getDefaultMiddleware) => getDefaultMiddleware({
+ serializableCheck: false,
+ }),
+ devTools: process.env.NODE_ENV !== 'production',
+})
+
+export default store
+export type RootState = ReturnType
+export type AppDispatch = typeof store.dispatch
\ No newline at end of file
diff --git a/src/services/reducers/types.ts b/src/services/reducers/types.ts
new file mode 100644
index 0000000..c2580c4
--- /dev/null
+++ b/src/services/reducers/types.ts
@@ -0,0 +1,43 @@
+import { BooleanLiteral, StringLiteral } from "typescript";
+
+export interface Ingredients {
+ _id: string;
+ calories: number;
+ carbohydrates: number;
+ fat: number;
+ image: string;
+ image_large: string;
+ image_mobile: string;
+ name: string;
+ price: number;
+ proteins: number;
+ type: string;
+}
+
+export interface IngredientsResp {
+ success: boolean;
+ data: Ingredients[];
+}
+
+export interface PostOrderRequest {
+ ingredients: string[];
+}
+
+export interface PostOrderResponse {
+ name: string;
+ success: boolean;
+ order: {
+ number: number;
+ };
+}
+
+export interface BurgerComponents {
+ bun: Ingredients[];
+ main: Ingredients[];
+ sauce: Ingredients[];
+}
+
+export interface Burger {
+ elements: Ingredients[];
+ bun: Ingredients | null;
+}
\ No newline at end of file
diff --git a/react-burger/src/setupTests.ts b/src/setupTests.ts
similarity index 100%
rename from react-burger/src/setupTests.ts
rename to src/setupTests.ts
diff --git a/react-burger/tsconfig.json b/tsconfig.json
similarity index 100%
rename from react-burger/tsconfig.json
rename to tsconfig.json
From 152c0dcd257ee1d6de11c12a7f46a6f34afc8595 Mon Sep 17 00:00:00 2001
From: ArsPro1323 <131661233+ArsPro1323@users.noreply.github.com>
Date: Sun, 7 Jan 2024 17:30:03 +0300
Subject: [PATCH 2/3] add id's to dnd
---
package-lock.json | 19 ++++++++++++++++---
package.json | 1 +
.../burger-constructor/burger-constructor.jsx | 4 +++-
3 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 360562f..f9ebf46 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -26,6 +26,7 @@
"redux": "^5.0.1",
"redux-thunk": "^3.1.0",
"typescript": "^4.9.5",
+ "uuid": "^9.0.1",
"web-vitals": "^2.1.4"
}
},
@@ -15593,6 +15594,14 @@
"websocket-driver": "^0.7.4"
}
},
+ "node_modules/sockjs/node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
"node_modules/source-list-map": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
@@ -16859,9 +16868,13 @@
}
},
"node_modules/uuid": {
- "version": "8.3.2",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
- "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
+ "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
+ "funding": [
+ "https://github.com/sponsors/broofa",
+ "https://github.com/sponsors/ctavan"
+ ],
"bin": {
"uuid": "dist/bin/uuid"
}
diff --git a/package.json b/package.json
index 3933cf0..240dd5e 100644
--- a/package.json
+++ b/package.json
@@ -21,6 +21,7 @@
"redux": "^5.0.1",
"redux-thunk": "^3.1.0",
"typescript": "^4.9.5",
+ "uuid": "^9.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
diff --git a/src/components/burger-constructor/burger-constructor.jsx b/src/components/burger-constructor/burger-constructor.jsx
index 60a48ef..d173f13 100644
--- a/src/components/burger-constructor/burger-constructor.jsx
+++ b/src/components/burger-constructor/burger-constructor.jsx
@@ -67,6 +67,8 @@ export function BurgerConstructor() {
setIsModalOpen(true);
}, [elements, bun])
+ const { v4: uuidv4 } = require('uuid');
+
return(
@@ -75,7 +77,7 @@ export function BurgerConstructor() {
)}
{elements.map((item, index) => {
- return
+ return
})}
From bcb80a8b5e932b87c01e6e0f7ac8369b83232a4d Mon Sep 17 00:00:00 2001
From: ArsPro1323 <131661233+ArsPro1323@users.noreply.github.com>
Date: Sun, 7 Jan 2024 18:34:00 +0300
Subject: [PATCH 3/3] review
---
...constructor.jsx => burger-constructor.tsx} | 18 +++++-----
.../burger-ingredients/burger-ingredients.tsx | 6 ++--
.../orders-details/orders-details.tsx | 2 +-
src/services/actions/constructor-action.ts | 19 ++++++++---
src/services/actions/ingredients-actions.ts | 17 ++++++----
.../get-ingredients/get-ingredients.ts | 10 +++---
src/services/reducers/constructor-reducer.ts | 4 +--
src/services/reducers/ingredients-reducer.ts | 33 ++++++++++++++++---
src/services/reducers/order-reducer.ts | 32 ++++++++++++++++++
src/services/reducers/store.ts | 2 ++
src/services/reducers/types.ts | 20 +++++++++++
11 files changed, 129 insertions(+), 34 deletions(-)
rename src/components/burger-constructor/{burger-constructor.jsx => burger-constructor.tsx} (84%)
create mode 100644 src/services/reducers/order-reducer.ts
diff --git a/src/components/burger-constructor/burger-constructor.jsx b/src/components/burger-constructor/burger-constructor.tsx
similarity index 84%
rename from src/components/burger-constructor/burger-constructor.jsx
rename to src/components/burger-constructor/burger-constructor.tsx
index d173f13..9963381 100644
--- a/src/components/burger-constructor/burger-constructor.jsx
+++ b/src/components/burger-constructor/burger-constructor.tsx
@@ -12,10 +12,12 @@ import {
import { CurrencyIcon } from '@ya.praktikum/react-developer-burger-ui-components';
import { useDrop } from "react-dnd";
import { clearConstructor } from '../../services/actions/constructor-action';
+import { AppDispatch, RootState } from '../../services/reducers/store';
+import { Ingredients } from '../../services/get-ingredients/get-ingredients-types';
export function BurgerConstructor() {
const myRef = useRef();
- const handleAdding = (item, pos) => {
+ const handleAdding = (item: any, pos: any) => {
if (item && item.type === 'bun') {
dispatch(changeBun(item));
} else {
@@ -23,13 +25,11 @@ export function BurgerConstructor() {
}
}
- const [order, setOrder] = useState("");
-
const [isModalOpen, setIsModalOpen] = useState(false);
- const dispatch = useDispatch();
- const {elements, bun} = useSelector((state) => state.elementConstructor)
+ const dispatch = useDispatch
();
+ const {elements, bun} = useSelector((state: RootState) => state.elementConstructor)
const [{ isOver }, drop] = useDrop(() => ({
accept: 'card',
@@ -60,16 +60,18 @@ export function BurgerConstructor() {
const makeOrder = useCallback(async () => {
const baseElements = elements.map(elem => elem._id);
- const orderDetails = await sendIngredients({ ingredients: (bun ? baseElements.concat(bun._id) : baseElements)})
+ const ingredients = bun ? baseElements.concat(bun._id) : baseElements;
+ await dispatch(sendIngredients({ingredients}));
dispatch(clearConstructor());
-
- orderDetails && setOrder(orderDetails.order.number.toString())
setIsModalOpen(true);
}, [elements, bun])
const { v4: uuidv4 } = require('uuid');
+ const order = useSelector((state: RootState) => state.order.orderId);
+
return(
+ // @ts-ignore
{ bun && (
diff --git a/src/components/burger-ingredients/burger-ingredients.tsx b/src/components/burger-ingredients/burger-ingredients.tsx
index 2ff0e3d..97d9e09 100644
--- a/src/components/burger-ingredients/burger-ingredients.tsx
+++ b/src/components/burger-ingredients/burger-ingredients.tsx
@@ -80,9 +80,9 @@ export default function BurgerIngredients() {
// sauces: store.ingredients.sauce
// }))
- const buns = useSelector((store: RootState) => store.ingredients.bun);
- const mains = useSelector((store: RootState) => store.ingredients.main);
- const sauces = useSelector((store: RootState) => store.ingredients.sauce);
+ const buns = useSelector((store: RootState) => store.ingredients.entities.bun);
+ const mains = useSelector((store: RootState) => store.ingredients.entities.main);
+ const sauces = useSelector((store: RootState) => store.ingredients.entities.sauce);
return(
diff --git a/src/components/orders-details/orders-details.tsx b/src/components/orders-details/orders-details.tsx
index e6d790b..73e1681 100644
--- a/src/components/orders-details/orders-details.tsx
+++ b/src/components/orders-details/orders-details.tsx
@@ -7,7 +7,7 @@ export default function OrderDetails({onModalClose, orderId}: OrderDetailsType)
return(
{orderId}
- идендификатор заказа
+ Идентификатор заказа
Ваш заказ начали готовить
Дождитесь готовности на орбитальной станции
diff --git a/src/services/actions/constructor-action.ts b/src/services/actions/constructor-action.ts
index e893fe9..12ce342 100644
--- a/src/services/actions/constructor-action.ts
+++ b/src/services/actions/constructor-action.ts
@@ -2,6 +2,8 @@ import { Ingredients, PostOrderRequest, PostOrderResponse } from "../reducers/ty
import { constructorActions } from "../reducers/constructor-reducer";
import { AppDispatch } from "../reducers/store";
import { postIngredients } from "../get-ingredients/get-ingredients";
+import { orderActions } from "../reducers/order-reducer";
+import { BASE_URL } from "../reducers/types";
export const addIngredient = (ingredient: Ingredients) => (dispatch: AppDispatch) => {
dispatch(constructorActions.addIngredients(ingredient));
@@ -19,11 +21,18 @@ export const swapElements = (index1: number, index2: number) => (dispatch: AppDi
dispatch(constructorActions.swapElements({firstId: index1, secondId: index2}));
}
-export const sendIngredients = async (request: PostOrderRequest): Promise => {
- const url = 'https://norma.nomoreparties.space/api/orders';
-
- const res = await postIngredients(url, request);
- return res;
+export const sendIngredients = (request: PostOrderRequest) => async (dispatch: AppDispatch) => {
+ dispatch(orderActions.setLoading());
+ try {
+ const res = await postIngredients(request);
+ if (res.success) {
+ dispatch(orderActions.setOrder(res.order.number.toString()));
+ } else {
+ dispatch(orderActions.setError());
+ }
+ } catch (err) {
+ dispatch(orderActions.setError());
+ }
}
export const clearConstructor = () => (dispatch: AppDispatch) => {
diff --git a/src/services/actions/ingredients-actions.ts b/src/services/actions/ingredients-actions.ts
index 0e0e286..5455518 100644
--- a/src/services/actions/ingredients-actions.ts
+++ b/src/services/actions/ingredients-actions.ts
@@ -1,14 +1,19 @@
+import { createAsyncThunk } from "@reduxjs/toolkit";
import { getIngredients } from "../get-ingredients/get-ingredients";
import { ingredientsActions } from "../reducers/ingredients-reducer";
import { AppDispatch } from "../reducers/store";
-export const initialiseIngredients = () => {
- const url = "https://norma.nomoreparties.space/api/ingredients";
-
- return async (dispatch: AppDispatch) => {
- const ingredients = await getIngredients(url);
+export const initialiseIngredients = () => async (dispatch: AppDispatch) => {
+ dispatch(ingredientsActions.setLoading());
+
+ try {
+ const ingredients = await getIngredients();
if (ingredients.success) {
dispatch(ingredientsActions.setIngredients(ingredients.data));
+ } else {
+ dispatch(ingredientsActions.setError());
}
+ } catch (error) {
+ dispatch(ingredientsActions.setError());
}
-}
\ No newline at end of file
+}
diff --git a/src/services/get-ingredients/get-ingredients.ts b/src/services/get-ingredients/get-ingredients.ts
index 11a82b0..c0b9090 100644
--- a/src/services/get-ingredients/get-ingredients.ts
+++ b/src/services/get-ingredients/get-ingredients.ts
@@ -1,17 +1,17 @@
-import { PostOrderRequest } from "../reducers/types";
+import { BASE_URL, PostOrderRequest } from "../reducers/types";
import { IngredientsResp } from "./get-ingredients-types";
import { PostOrderResponse } from "../reducers/types";
-export const getIngredients = async(url: string): Promise => {
- const resp = await fetch(url);
+export const getIngredients = async(): Promise => {
+ const resp = await fetch(`${BASE_URL}/ingredients`);
if (resp.ok) {
return resp.json();
}
return Promise.reject(`Ошибка ${resp.status}`);
}
-export const postIngredients = async (url: string, request: PostOrderRequest): Promise => {
- const resp = await fetch(url, {
+export const postIngredients = async (request: PostOrderRequest): Promise => {
+ const resp = await fetch(`${BASE_URL}/orders`, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(request),
diff --git a/src/services/reducers/constructor-reducer.ts b/src/services/reducers/constructor-reducer.ts
index f740094..8fba520 100644
--- a/src/services/reducers/constructor-reducer.ts
+++ b/src/services/reducers/constructor-reducer.ts
@@ -1,7 +1,7 @@
import { createSlice } from "@reduxjs/toolkit";
-import { Burger } from './types';
+import { ActionState, Burger } from './types';
-const initial = { elements: [], bun: null } as Burger;
+const initial = { elements: [], bun: null, state: ActionState.INITIAL } as Burger;
const { actions, reducer } = createSlice({
name: 'ELEMENT_CONSTRUCTOR',
diff --git a/src/services/reducers/ingredients-reducer.ts b/src/services/reducers/ingredients-reducer.ts
index 25be249..3f8d6da 100644
--- a/src/services/reducers/ingredients-reducer.ts
+++ b/src/services/reducers/ingredients-reducer.ts
@@ -1,20 +1,45 @@
import { createSlice } from '@reduxjs/toolkit'
import BurgerIngredients from '../../components/burger-ingredients/burger-ingredients';
-import { BurgerComponents } from './types';
+import { ActionState, BurgerComponents, BurgerData } from './types';
import { Ingredients } from './types';
-const initial: BurgerComponents = {bun: [], main: [], sauce: []}
+const initial: BurgerData = {
+ entities: {
+ bun: [],
+ main: [],
+ sauce: []
+ } as BurgerComponents,
+ state: ActionState.INITIAL,
+}
const { actions, reducer } = createSlice({
name: 'INGREDIENTS',
initialState: initial,
reducers: {
- setIngredients: (state, action) => {
- return action.payload.reduce((acc: BurgerComponents, ingredient: Ingredients) => {
+ setLoading: (state) => {
+ return {
+ ...state,
+ state: ActionState.LOADING,
+ }
+ },
+ setError: (state) => {
+ return {
+ ...state,
+ state: ActionState.ERROR,
+ }
+ },
+ setIngredients: (state, action: { payload: Ingredients[] }) => {
+ const ingredients = action.payload.reduce((acc: BurgerComponents, ingredient: Ingredients) => {
const ingredientType = ingredient.type as keyof BurgerComponents;
acc[ingredientType].push(ingredient);
return acc;
}, { bun: [], main: [], sauce: [] });
+
+ return {
+ ...state,
+ entities: ingredients,
+ state: ActionState.SUCCESS,
+ }
},
},
})
diff --git a/src/services/reducers/order-reducer.ts b/src/services/reducers/order-reducer.ts
new file mode 100644
index 0000000..0d98d23
--- /dev/null
+++ b/src/services/reducers/order-reducer.ts
@@ -0,0 +1,32 @@
+import { createSlice } from '@reduxjs/toolkit'
+import { ActionState } from './types'
+
+const initial = { orderId : '', state: ActionState.INITIAL }
+
+const { actions, reducer } = createSlice({
+ name: 'ORDER',
+ initialState: initial,
+ reducers: {
+ setLoading: (state) => {
+ return {
+ ...state,
+ state: ActionState.LOADING,
+ }
+ },
+ setError: (state) => {
+ return {
+ ...state,
+ state: ActionState.ERROR,
+ }
+ },
+ setOrder: (state, action: { payload: string }) => {
+ return {
+ orderId: action.payload,
+ state: ActionState.SUCCESS,
+ }
+ }
+ },
+})
+
+export const orderActions = actions;
+export default reducer
\ No newline at end of file
diff --git a/src/services/reducers/store.ts b/src/services/reducers/store.ts
index 8b73618..0b5f8d7 100644
--- a/src/services/reducers/store.ts
+++ b/src/services/reducers/store.ts
@@ -3,12 +3,14 @@ import { configureStore } from '@reduxjs/toolkit'
import ingredientsReducer from './ingredients-reducer'
import constructorReducer from './constructor-reducer'
import modalReducer from './modal-reducer'
+import orderReducer from './order-reducer'
const store = configureStore({
reducer: {
ingredients: ingredientsReducer,
elementConstructor: constructorReducer,
modalWindow: modalReducer,
+ order: orderReducer,
},
middleware: (getDefaultMiddleware) => getDefaultMiddleware({
serializableCheck: false,
diff --git a/src/services/reducers/types.ts b/src/services/reducers/types.ts
index c2580c4..75949aa 100644
--- a/src/services/reducers/types.ts
+++ b/src/services/reducers/types.ts
@@ -14,6 +14,15 @@ export interface Ingredients {
type: string;
}
+export const BASE_URL = 'https://norma.nomoreparties.space/api';
+
+export enum ActionState {
+ INITIAL = '_INITIAL',
+ LOADING = '_LOADING',
+ ERROR = '_ERROR',
+ SUCCESS = '_SUCCESS'
+}
+
export interface IngredientsResp {
success: boolean;
data: Ingredients[];
@@ -37,7 +46,18 @@ export interface BurgerComponents {
sauce: Ingredients[];
}
+export interface BurgerData {
+ entities: BurgerComponents;
+ state: ActionState;
+}
+
export interface Burger {
elements: Ingredients[];
bun: Ingredients | null;
+ state: ActionState;
+}
+
+export interface OrderData {
+ orderId: string,
+ state: ActionState,
}
\ No newline at end of file