Commit a01fa831 authored by Nurasyl's avatar Nurasyl

redux

parent e438efa6
...@@ -8,9 +8,11 @@ ...@@ -8,9 +8,11 @@
"name": "burger-builder-template", "name": "burger-builder-template",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"@reduxjs/toolkit": "^2.2.5",
"axios": "^1.6.8", "axios": "^1.6.8",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-redux": "^9.1.2",
"react-router-dom": "^6.23.0" "react-router-dom": "^6.23.0"
}, },
"devDependencies": { "devDependencies": {
...@@ -777,6 +779,29 @@ ...@@ -777,6 +779,29 @@
"@jridgewell/sourcemap-codec": "1.4.14" "@jridgewell/sourcemap-codec": "1.4.14"
} }
}, },
"node_modules/@reduxjs/toolkit": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.5.tgz",
"integrity": "sha512-aeFA/s5NCG7NoJe/MhmwREJxRkDs0ZaSqt0MxhWUrwCf1UQXpwR87RROJEql0uAkLI6U7snBOYOcKw83ew3FPg==",
"dependencies": {
"immer": "^10.0.3",
"redux": "^5.0.1",
"redux-thunk": "^3.1.0",
"reselect": "^5.1.0"
},
"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/@remix-run/router": { "node_modules/@remix-run/router": {
"version": "1.16.0", "version": "1.16.0",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.0.tgz", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.0.tgz",
...@@ -798,16 +823,15 @@ ...@@ -798,16 +823,15 @@
"version": "15.7.5", "version": "15.7.5",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
"dev": true "devOptional": true
}, },
"node_modules/@types/react": { "node_modules/@types/react": {
"version": "18.0.28", "version": "18.3.2",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.28.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.2.tgz",
"integrity": "sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==", "integrity": "sha512-Btgg89dAnqD4vV7R3hlwOxgqobUQKgx3MmrQRi0yYbs/P0ym8XozIAlkqVilPqHQwXs4e9Tf63rrCgl58BcO4w==",
"dev": true, "devOptional": true,
"dependencies": { "dependencies": {
"@types/prop-types": "*", "@types/prop-types": "*",
"@types/scheduler": "*",
"csstype": "^3.0.2" "csstype": "^3.0.2"
} }
}, },
...@@ -820,11 +844,10 @@ ...@@ -820,11 +844,10 @@
"@types/react": "*" "@types/react": "*"
} }
}, },
"node_modules/@types/scheduler": { "node_modules/@types/use-sync-external-store": {
"version": "0.16.2", "version": "0.0.3",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
"dev": true
}, },
"node_modules/@vitejs/plugin-react": { "node_modules/@vitejs/plugin-react": {
"version": "3.1.0", "version": "3.1.0",
...@@ -966,7 +989,7 @@ ...@@ -966,7 +989,7 @@
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz",
"integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==",
"dev": true "devOptional": true
}, },
"node_modules/debug": { "node_modules/debug": {
"version": "4.3.4", "version": "4.3.4",
...@@ -1145,6 +1168,15 @@ ...@@ -1145,6 +1168,15 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/immer": {
"version": "10.1.1",
"resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz",
"integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/immer"
}
},
"node_modules/is-core-module": { "node_modules/is-core-module": {
"version": "2.11.0", "version": "2.11.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
...@@ -1325,6 +1357,28 @@ ...@@ -1325,6 +1357,28 @@
"react": "^18.2.0" "react": "^18.2.0"
} }
}, },
"node_modules/react-redux": {
"version": "9.1.2",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.2.tgz",
"integrity": "sha512-0OA4dhM1W48l3uzmv6B7TXPCGmokUU4p1M44DGN2/D9a1FjVPukVjER1PcPX97jIg6aUeLq1XJo1IpfbgULn0w==",
"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",
"redux": "^5.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"redux": {
"optional": true
}
}
},
"node_modules/react-refresh": { "node_modules/react-refresh": {
"version": "0.14.0", "version": "0.14.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz",
...@@ -1364,6 +1418,24 @@ ...@@ -1364,6 +1418,24 @@
"react-dom": ">=16.8" "react-dom": ">=16.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/reselect": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.0.tgz",
"integrity": "sha512-aw7jcGLDpSgNDyWBQLv2cedml85qd95/iszJjN988zX1t7AVRJi19d9kto5+W7oCfQ94gyo40dVbT6g2k4/kXg=="
},
"node_modules/resolve": { "node_modules/resolve": {
"version": "1.22.1", "version": "1.22.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
...@@ -1501,6 +1573,14 @@ ...@@ -1501,6 +1573,14 @@
"browserslist": ">= 4.21.0" "browserslist": ">= 4.21.0"
} }
}, },
"node_modules/use-sync-external-store": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz",
"integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/vite": { "node_modules/vite": {
"version": "4.2.1", "version": "4.2.1",
"resolved": "https://registry.npmjs.org/vite/-/vite-4.2.1.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-4.2.1.tgz",
...@@ -2014,6 +2094,17 @@ ...@@ -2014,6 +2094,17 @@
"@jridgewell/sourcemap-codec": "1.4.14" "@jridgewell/sourcemap-codec": "1.4.14"
} }
}, },
"@reduxjs/toolkit": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.5.tgz",
"integrity": "sha512-aeFA/s5NCG7NoJe/MhmwREJxRkDs0ZaSqt0MxhWUrwCf1UQXpwR87RROJEql0uAkLI6U7snBOYOcKw83ew3FPg==",
"requires": {
"immer": "^10.0.3",
"redux": "^5.0.1",
"redux-thunk": "^3.1.0",
"reselect": "^5.1.0"
}
},
"@remix-run/router": { "@remix-run/router": {
"version": "1.16.0", "version": "1.16.0",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.0.tgz", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.0.tgz",
...@@ -2032,16 +2123,15 @@ ...@@ -2032,16 +2123,15 @@
"version": "15.7.5", "version": "15.7.5",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
"dev": true "devOptional": true
}, },
"@types/react": { "@types/react": {
"version": "18.0.28", "version": "18.3.2",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.28.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.2.tgz",
"integrity": "sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==", "integrity": "sha512-Btgg89dAnqD4vV7R3hlwOxgqobUQKgx3MmrQRi0yYbs/P0ym8XozIAlkqVilPqHQwXs4e9Tf63rrCgl58BcO4w==",
"dev": true, "devOptional": true,
"requires": { "requires": {
"@types/prop-types": "*", "@types/prop-types": "*",
"@types/scheduler": "*",
"csstype": "^3.0.2" "csstype": "^3.0.2"
} }
}, },
...@@ -2054,11 +2144,10 @@ ...@@ -2054,11 +2144,10 @@
"@types/react": "*" "@types/react": "*"
} }
}, },
"@types/scheduler": { "@types/use-sync-external-store": {
"version": "0.16.2", "version": "0.0.3",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
"dev": true
}, },
"@vitejs/plugin-react": { "@vitejs/plugin-react": {
"version": "3.1.0", "version": "3.1.0",
...@@ -2159,7 +2248,7 @@ ...@@ -2159,7 +2248,7 @@
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz",
"integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==",
"dev": true "devOptional": true
}, },
"debug": { "debug": {
"version": "4.3.4", "version": "4.3.4",
...@@ -2278,6 +2367,11 @@ ...@@ -2278,6 +2367,11 @@
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"dev": true "dev": true
}, },
"immer": {
"version": "10.1.1",
"resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz",
"integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw=="
},
"is-core-module": { "is-core-module": {
"version": "2.11.0", "version": "2.11.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
...@@ -2406,6 +2500,15 @@ ...@@ -2406,6 +2500,15 @@
"scheduler": "^0.23.0" "scheduler": "^0.23.0"
} }
}, },
"react-redux": {
"version": "9.1.2",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.2.tgz",
"integrity": "sha512-0OA4dhM1W48l3uzmv6B7TXPCGmokUU4p1M44DGN2/D9a1FjVPukVjER1PcPX97jIg6aUeLq1XJo1IpfbgULn0w==",
"requires": {
"@types/use-sync-external-store": "^0.0.3",
"use-sync-external-store": "^1.0.0"
}
},
"react-refresh": { "react-refresh": {
"version": "0.14.0", "version": "0.14.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz",
...@@ -2429,6 +2532,22 @@ ...@@ -2429,6 +2532,22 @@
"react-router": "6.23.0" "react-router": "6.23.0"
} }
}, },
"redux": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w=="
},
"redux-thunk": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz",
"integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==",
"requires": {}
},
"reselect": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.0.tgz",
"integrity": "sha512-aw7jcGLDpSgNDyWBQLv2cedml85qd95/iszJjN988zX1t7AVRJi19d9kto5+W7oCfQ94gyo40dVbT6g2k4/kXg=="
},
"resolve": { "resolve": {
"version": "1.22.1", "version": "1.22.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
...@@ -2512,6 +2631,12 @@ ...@@ -2512,6 +2631,12 @@
"picocolors": "^1.0.0" "picocolors": "^1.0.0"
} }
}, },
"use-sync-external-store": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz",
"integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==",
"requires": {}
},
"vite": { "vite": {
"version": "4.2.1", "version": "4.2.1",
"resolved": "https://registry.npmjs.org/vite/-/vite-4.2.1.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-4.2.1.tgz",
......
...@@ -9,9 +9,11 @@ ...@@ -9,9 +9,11 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@reduxjs/toolkit": "^2.2.5",
"axios": "^1.6.8", "axios": "^1.6.8",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-redux": "^9.1.2",
"react-router-dom": "^6.23.0" "react-router-dom": "^6.23.0"
}, },
"devDependencies": { "devDependencies": {
......
import React from 'react'; import React from 'react';
import { Provider } from 'react-redux';
import { BrowserRouter, Routes, Route } from 'react-router-dom'; import { BrowserRouter, Routes, Route } from 'react-router-dom';
import BurgerBuilder from './containers/BurgerBuilder/BurgerBuilder'; import BurgerBuilder from './containers/BurgerBuilder/BurgerBuilder';
import { Checkout } from './containers/Checkout/Checkout'; import { Checkout } from './containers/Checkout/Checkout';
import { NotFound } from './components/NotFound/NotFound'; import { NotFound } from './components/NotFound/NotFound';
import { ContactData } from './containers/ContactData/ContactData'; import { ContactData } from './containers/ContactData/ContactData';
import { Layout } from './components/Layout/Layout'; import { Layout } from './components/Layout/Layout';
import { Orders } from './containers/Orders/Orders'; import Orders from './containers/Orders/Orders';
import { store } from './store';
function App() { function App() {
return ( return (
<Provider store={store}>
<BrowserRouter> <BrowserRouter>
<Routes> <Routes>
<Route path='/' element={<Layout/>}> <Route path='/' element={<Layout/>}>
...@@ -21,6 +24,7 @@ function App() { ...@@ -21,6 +24,7 @@ function App() {
</Route> </Route>
</Routes> </Routes>
</BrowserRouter> </BrowserRouter>
</Provider>
) )
} }
......
import { parseGetOrders } from "@/helpers/parseGetOrders";
import axios from "axios"; import axios from "axios";
axios.defaults.baseURL = "https://burger-278a4-default-rtdb.firebaseio.com/"; const axiosBurger = axios.create({
baseURL: "https://burger-278a4-default-rtdb.firebaseio.com/"
const axiosBurger = axios; });
export default axiosBurger; export default axiosBurger;
\ No newline at end of file
import React, { useState } from 'react'; import React, { useState } from 'react';
import { useNavigate, createSearchParams } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import type { Ingredients, IngredientNames } from '@/interfaces/Ingredients'; import type { Ingredients, IngredientNames } from '@/interfaces/Ingredients';
import Burger from '@/components/Burger/Burger'; import Burger from '@/components/Burger/Burger';
import BuildControls from '@/components/BuildControls/BuildControls'; import BuildControls from '@/components/BuildControls/BuildControls';
import { IngredientPrices } from '@/helpers/IngPrice'; import { IngredientPrices } from '@/helpers/IngPrice';
import { Modal } from '@/components/UI/Modal/Modal'; import { Modal } from '@/components/UI/Modal/Modal';
import { OrderSummary } from '@/components/Burger/OrderSummary'; import { OrderSummary } from '@/components/Burger/OrderSummary';
import { useAppSelector } from '@/store';
import { useAppDispatch } from '@/store';
import { setIngredients } from '@/store/ingredients.slice';
const BurgerBuilder = () => { const BurgerBuilder = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const dispatch = useAppDispatch();
const {ingredints} = useAppSelector(state => state);
const [totalPrice, setTotalPrice] = useState<number>(IngredientPrices.bread); const [totalPrice, setTotalPrice] = useState<number>(IngredientPrices.bread);
const [purshasable, setPurshasable] = useState<boolean>(false); const [purshasable, setPurshasable] = useState<boolean>(false);
const [show, setShow] = useState<boolean>(false); const [show, setShow] = useState<boolean>(false);
const [ingredients, setIngredients] = useState<Ingredients>({
salad: 0,
meat: 0,
bacon: 0,
cheese: 0
});
const onLessClick = (ingType: IngredientNames) => { const onLessClick = (ingType: IngredientNames) => {
const ingredientsCopy = {...ingredients}; if(ingredints[ingType] > 0) {
if(ingredientsCopy[ingType] > 0) { dispatch(setIngredients({ingType, actionType: "less"}));
ingredientsCopy[ingType] -= 1;
setIngredients(ingredientsCopy);
setTotalPrice(prevState => prevState - IngredientPrices[ingType]); setTotalPrice(prevState => prevState - IngredientPrices[ingType]);
updatePurshasable(ingredientsCopy); updatePurshasable(ingredints);
}; }
}; };
const onMoreClick = (ingType: IngredientNames) => { const onMoreClick = (ingType: IngredientNames) => {
const ingredientsCopy = {...ingredients}; dispatch(setIngredients({ingType, actionType: "more"}));
ingredientsCopy[ingType] += 1;
setTotalPrice(prevState => prevState + IngredientPrices[ingType]); setTotalPrice(prevState => prevState + IngredientPrices[ingType]);
setIngredients(ingredientsCopy); updatePurshasable(ingredints);
updatePurshasable(ingredientsCopy);
}; };
const updatePurshasable = (ings: Ingredients) => { const updatePurshasable = (ings: Ingredients) => {
...@@ -54,31 +49,27 @@ const BurgerBuilder = () => { ...@@ -54,31 +49,27 @@ const BurgerBuilder = () => {
}; };
const onPurchaseContinued = () => { const onPurchaseContinued = () => {
const searchParams = createSearchParams(ingredients as unknown as URLSearchParams) navigate({pathname: "/checkout"})
navigate({
pathname: "/checkout",
search: `${searchParams.toString()}`
})
}; };
return ( return (
<> <>
<Modal show={show} onClosed={onClosedHandler}> <Modal show={show} onClosed={onClosedHandler}>
<OrderSummary <OrderSummary
ingredients={ingredients} ingredients={ingredints}
price={totalPrice} price={totalPrice}
purchaseCancelled={onClosedHandler} purchaseCancelled={onClosedHandler}
purchaseContinued={onPurchaseContinued} purchaseContinued={onPurchaseContinued}
/> />
</Modal> </Modal>
<Burger ingredients={ingredients}/> <Burger ingredients={ingredints}/>
<BuildControls <BuildControls
purshasable={purshasable} purshasable={purshasable}
price={totalPrice} price={totalPrice}
onLessClick={onLessClick} onLessClick={onLessClick}
onMoreClick={onMoreClick} onMoreClick={onMoreClick}
onOpenModal={onOpenModalHandler} onOpenModal={onOpenModalHandler}
ingredients={ingredients} ingredients={ingredints}
/> />
</> </>
) )
......
import React, {useRef} from 'react'; import React from 'react';
import {useSearchParams, Outlet, useNavigate, NavLink} from "react-router-dom"; import {Outlet, useNavigate} from "react-router-dom";
import type {IngredientNames, Ingredients} from '@/interfaces/Ingredients';
import { CheckoutSummary } from '@/components/Order/CheckoutSummary/CheckoutSummary'; import { CheckoutSummary } from '@/components/Order/CheckoutSummary/CheckoutSummary';
import { parseParams } from '@/helpers/parseParams'; import { useAppSelector } from '@/store';
import { getTotalPrice } from '@/helpers/getTotalPrice';
import { IngredientPrices } from '@/helpers/IngPrice';
export const Checkout = () => { export const Checkout = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const [params] = useSearchParams(); const {ingredints} = useAppSelector(state => state);
const ingredients = useRef(parseParams<Ingredients>(params));
const checkoutCancelledHandler = () => { const checkoutCancelledHandler = () => {
navigate(-1); navigate(-1);
}; };
const checkoutContinuedHandler = () => { const checkoutContinuedHandler = () => {
const price = getTotalPrice(ingredients.current); navigate('contactData');
navigate('contactData', {state: {ingredients: ingredients.current, price}});
}; };
return ( return (
<> <>
<CheckoutSummary <CheckoutSummary
ingredients={ingredients.current} ingredients={ingredints}
checkoutCancelled={checkoutCancelledHandler} checkoutCancelled={checkoutCancelledHandler}
checkoutContinued={checkoutContinuedHandler} checkoutContinued={checkoutContinuedHandler}
/> />
......
...@@ -2,18 +2,17 @@ import React, { useState } from 'react'; ...@@ -2,18 +2,17 @@ import React, { useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom'; import { useLocation, useNavigate } from 'react-router-dom';
import axiosBurger from '@/config/axiosBurger'; import axiosBurger from '@/config/axiosBurger';
import { Button } from "@/components/UI/Button/Button"; import { Button } from "@/components/UI/Button/Button";
import { Ingredients } from '@/interfaces/Ingredients';
import { TContactData } from '@/interfaces/contactData'; import { TContactData } from '@/interfaces/contactData';
import { parseContactData } from '@/helpers/parseContactData';
import { Modal } from '@/components/UI/Modal/Modal'; import { Modal } from '@/components/UI/Modal/Modal';
import { Spinner } from '@/components/UI/Spinner/Spinner'; import { Spinner } from '@/components/UI/Spinner/Spinner';
import { useAppSelector } from '@/store';
import './ContactData.css'; import './ContactData.css';
export const ContactData = () => { export const ContactData = () => {
const location = useLocation(); const location = useLocation();
const navigate = useNavigate(); const navigate = useNavigate();
const {ingredints} = useAppSelector(state => state);
const [ingredients, setIngredients] = useState<Ingredients | null>(parseContactData(location));
const [isLoading, setIsLoading] = useState<boolean>(false); const [isLoading, setIsLoading] = useState<boolean>(false);
const [showModal, setShowModal] = useState<boolean>(false); const [showModal, setShowModal] = useState<boolean>(false);
const [contactData, setContactData] = useState<TContactData>({ const [contactData, setContactData] = useState<TContactData>({
...@@ -34,7 +33,7 @@ export const ContactData = () => { ...@@ -34,7 +33,7 @@ export const ContactData = () => {
const allDataReq = Object.values(contactData).every(el => el !== ""); const allDataReq = Object.values(contactData).every(el => el !== "");
const order = { const order = {
ingredients, ingredints,
contactData, contactData,
price: location.state.price price: location.state.price
}; };
......
...@@ -5,18 +5,16 @@ import { parseGetOrders } from "@/helpers/parseGetOrders"; ...@@ -5,18 +5,16 @@ import { parseGetOrders } from "@/helpers/parseGetOrders";
import { TOrder } from "@/interfaces/order"; import { TOrder } from "@/interfaces/order";
import { OrderItem } from "@/components/Order/OrderItem/OrderItem"; import { OrderItem } from "@/components/Order/OrderItem/OrderItem";
import { Spinner } from "@/components/UI/Spinner/Spinner"; import { Spinner } from "@/components/UI/Spinner/Spinner";
import withSpinnerHandler from "@/hoc/withSpinnerHandler";
export const Orders = () => { const Orders = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const [orders, setOrders] = useState<TOrder[]>([]); const [orders, setOrders] = useState<TOrder[]>([]);
const [isLoading, setIsLoading] = useState<boolean>(false);
const getOrders = useCallback(async () => { const getOrders = useCallback(async () => {
setIsLoading(true); const {data} = await axiosBurger.get("orders");
const {data} = await axiosBurger.get("orders.json");
setOrders(parseGetOrders(data).reverse()); setOrders(parseGetOrders(data).reverse());
setIsLoading(false);
}, []); }, []);
useEffect(() => { useEffect(() => {
...@@ -30,9 +28,7 @@ export const Orders = () => { ...@@ -30,9 +28,7 @@ export const Orders = () => {
}; };
return ( return (
<> <>
<Spinner show={isLoading}/>
{ {
orders.map(order => ( orders.map(order => (
<OrderItem <OrderItem
...@@ -46,3 +42,6 @@ export const Orders = () => { ...@@ -46,3 +42,6 @@ export const Orders = () => {
</> </>
); );
}; };
export default withSpinnerHandler(Orders, axiosBurger)
\ No newline at end of file
import React, { useState, FunctionComponent, useEffect } from 'react';
import { AxiosInstance, AxiosResponse, AxiosError } from 'axios';
import { Modal } from '@/components/UI/Modal/Modal';
const withSpinnerHandler = <T extends object>(WrappedComponent: FunctionComponent<T>, axios: AxiosInstance) => {
return (props: T) => {
const [error, setError] = useState<string>("");
const [show, setShow] = useState<boolean>(false)
const succesHandler = async (res: AxiosResponse<any, any>) => {
return res
};
const rejectHandler = (rej: AxiosError<any, any>) => {
setError(rej.message)
setShow(true)
return rej
};
const onClosedHandler = () => {
setShow(false)
};
useEffect(() => {
axios.interceptors.response.use(succesHandler, rejectHandler);
}, []);
return (
<>
<Modal show={show} onClosed={onClosedHandler}>
<h1>{error}</h1>
</Modal>
<WrappedComponent {...props} />
</>
);
};
};
export default withSpinnerHandler;
\ No newline at end of file
import { configureStore } from "@reduxjs/toolkit";
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
import { ingredientsSlice } from "./ingredients.slice";
export const store = configureStore({
reducer: {
ingredints: ingredientsSlice.reducer
}
});
type RootState = ReturnType<typeof store.getState>;
type AppDispatch = typeof store.dispatch;
export const useAppDispatch: () => AppDispatch = useDispatch
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
\ No newline at end of file
import { createSlice } from "@reduxjs/toolkit";
import { IngredientNames, Ingredients } from "@/interfaces/Ingredients";
const initialState: Ingredients = {
salad: 0,
meat: 0,
bacon: 0,
cheese: 0
};
export const ingredientsSlice = createSlice({
name: "ingredients",
initialState,
reducers: {
setIngredients(state, action) {
const {ingType, actionType} = action.payload as {ingType: IngredientNames, actionType: string}
if(actionType === "more") {
state[ingType] += 1
} else if(actionType === "less") {
if(state[ingType] > 0) {
state[ingType] -= 1
}
}
}
}
});
export const {setIngredients} = ingredientsSlice.actions;
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment