diff --git a/package-lock.json b/package-lock.json
index b55ec57..04dbe61 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1366,6 +1366,18 @@
"react-transition-group": "^4.4.0"
}
},
+ "@material-ui/lab": {
+ "version": "4.0.0-alpha.56",
+ "resolved": "https://registry.npmjs.org/@material-ui/lab/-/lab-4.0.0-alpha.56.tgz",
+ "integrity": "sha512-xPlkK+z/6y/24ka4gVJgwPfoCF4RCh8dXb1BNE7MtF9bXEBLN/lBxNTK8VAa0qm3V2oinA6xtUIdcRh0aeRtVw==",
+ "requires": {
+ "@babel/runtime": "^7.4.4",
+ "@material-ui/utils": "^4.10.2",
+ "clsx": "^1.0.4",
+ "prop-types": "^15.7.2",
+ "react-is": "^16.8.0"
+ }
+ },
"@material-ui/styles": {
"version": "4.10.0",
"resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.10.0.tgz",
@@ -2571,6 +2583,37 @@
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz",
"integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA=="
},
+ "axios": {
+ "version": "0.19.2",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
+ "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
+ "requires": {
+ "follow-redirects": "1.5.10"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "follow-redirects": {
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
+ "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
+ "requires": {
+ "debug": "=3.1.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
"axobject-query": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
@@ -11266,6 +11309,18 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
+ "react-redux": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.0.tgz",
+ "integrity": "sha512-EvCAZYGfOLqwV7gh849xy9/pt55rJXPwmYvI4lilPM5rUT/1NxuuN59ipdBksRVSvz0KInbPnp4IfoXJXCqiDA==",
+ "requires": {
+ "@babel/runtime": "^7.5.5",
+ "hoist-non-react-statics": "^3.3.0",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.7.2",
+ "react-is": "^16.9.0"
+ }
+ },
"react-scripts": {
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.4.1.tgz",
@@ -11399,6 +11454,20 @@
"strip-indent": "^3.0.0"
}
},
+ "redux": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz",
+ "integrity": "sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==",
+ "requires": {
+ "loose-envify": "^1.4.0",
+ "symbol-observable": "^1.2.0"
+ }
+ },
+ "redux-thunk": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz",
+ "integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw=="
+ },
"regenerate": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz",
@@ -12905,6 +12974,11 @@
"util.promisify": "~1.0.0"
}
},
+ "symbol-observable": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
+ "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="
+ },
"symbol-tree": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
diff --git a/package.json b/package.json
index 5e14226..0c9435a 100644
--- a/package.json
+++ b/package.json
@@ -4,13 +4,18 @@
"private": true,
"dependencies": {
"@material-ui/core": "^4.11.0",
+ "@material-ui/lab": "^4.0.0-alpha.56",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
+ "axios": "^0.19.2",
"node-sass": "^4.14.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
- "react-scripts": "3.4.1"
+ "react-redux": "^7.2.0",
+ "react-scripts": "3.4.1",
+ "redux": "^4.0.5",
+ "redux-thunk": "^2.3.0"
},
"scripts": {
"start": "react-scripts start",
diff --git a/src/App.js b/src/App.js
index 321e12f..70672e3 100644
--- a/src/App.js
+++ b/src/App.js
@@ -4,20 +4,31 @@ import "./App.scss";
import TopBar from "./components/TopBar";
import Footer from "./components/Footer";
import SearchPanel from "./components/SearchPanel";
+import { createMuiTheme, ThemeProvider } from "@material-ui/core/styles";
+
+const theme = createMuiTheme({
+ palette: {
+ primary: {
+ main: "#0e8496",
+ },
+ },
+});
function App() {
return (
-
-
-
-

-
-
- Sprawdź co serwuje Twoja ulubiona restauracja.
-
+
+
+
+
+

+
+
+ Sprawdź co serwuje Twoja ulubiona restauracja.
+
+
+
-
-
+
);
}
diff --git a/src/App.scss b/src/App.scss
index f42847e..1fb5149 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -1,6 +1,7 @@
@import "./Design.scss";
@import "./styles/TopBar.scss";
@import "./styles/SearchPanel.scss";
+@import "./styles/Footer.scss";
.App {
padding: 0;
diff --git a/src/Services.js b/src/Services.js
index e69de29..d378720 100644
--- a/src/Services.js
+++ b/src/Services.js
@@ -0,0 +1 @@
+import axios from "axios";
diff --git a/src/actions/index.js b/src/actions/index.js
new file mode 100644
index 0000000..3c50ac4
--- /dev/null
+++ b/src/actions/index.js
@@ -0,0 +1,37 @@
+import axios from "axios";
+
+const autocomplete = (input) => {
+ return {
+ type: "AUTOCOMPLETE_ADD",
+ payload: input,
+ };
+};
+
+export const clearAutocomplete = () => {
+ return {
+ type: "AUTOCOMPLETE_CLEAR",
+ };
+};
+
+export const fetchAutocomplete = (input) => {
+ return function (dispatch) {
+ axios
+ .get("http://localhost:4000/search/autocomplete?string=" + input)
+ .then((response) => {
+ const cities = Array.from(response.data.cities);
+ const restaurants = Array.from(response.data.restaurants);
+ const options = cities.concat(restaurants);
+
+ dispatch(autocomplete(options));
+ })
+ .catch((err) => {
+ console.log(err);
+ });
+ };
+};
+
+export const setAppMode = (mode) => {
+ return {
+ type: mode,
+ };
+};
diff --git a/src/components/ButtonPrimary.js b/src/components/ButtonPrimary.js
index 57dc23a..bb1504e 100644
--- a/src/components/ButtonPrimary.js
+++ b/src/components/ButtonPrimary.js
@@ -4,12 +4,13 @@ import Button from "@material-ui/core/Button";
const StyledButton = withStyles({
root: {
- background: "none",
- color: "white",
+ background: "white",
+ color: "#0e8496",
margin: "16px 16px 16px 0px",
padding: "8px 12px 8px 12px",
- borderColor: "white",
- border: "solid 1px",
+ "&:hover": {
+ color: "white",
+ },
},
label: {
textTransform: "none",
diff --git a/src/components/SearchPanel.js b/src/components/SearchPanel.js
index abd92d1..d912c04 100644
--- a/src/components/SearchPanel.js
+++ b/src/components/SearchPanel.js
@@ -1,21 +1,33 @@
import React from "react";
import ButtonSecondary from "./ButtonSecondary";
-import CustomTextInput from "./CustomTextInput";
+import TextField from "@material-ui/core/TextField";
+import Autocomplete from "@material-ui/lab/Autocomplete";
+import { useSelector, useDispatch } from "react-redux";
+import { fetchAutocomplete } from "../actions";
-export default class SearchPanel extends React.Component {
- render() {
- return (
-
-
-
-
-
+export default function SearchPanel() {
+ let options = useSelector((store) => store.autocomplete);
+ const dispatch = useDispatch();
+
+ return (
+
+
(
+ dispatch(fetchAutocomplete(event.target.value))}
+ />
+ )}
+ />
+
+
+
- );
- }
+
+ );
}
diff --git a/src/components/TopBar.js b/src/components/TopBar.js
index 628c382..e5b7f4e 100644
--- a/src/components/TopBar.js
+++ b/src/components/TopBar.js
@@ -1,14 +1,14 @@
import React from "react";
-import ButtonSecondary from "./ButtonSecondary";
-import logo from "../public/logo_mint.svg";
+import ButtonPrimary from "./ButtonPrimary";
+import logo from "../public/logo_white.svg";
export default function TopBar() {
return (
-
-
+
+
);
diff --git a/src/index.js b/src/index.js
index 3125ee4..70eb46e 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,13 +1,19 @@
import React from "react";
import ReactDOM from "react-dom";
+import { Provider } from "react-redux";
import "./index.scss";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
+import rootReducer from "./reducers";
+import thunk from "redux-thunk";
+import { createStore, applyMiddleware } from "redux";
+
+const store = createStore(rootReducer, applyMiddleware(thunk));
ReactDOM.render(
-
+
- ,
+ ,
document.getElementById("root")
);
diff --git a/src/reducers/appMode.js b/src/reducers/appMode.js
new file mode 100644
index 0000000..a8e04dc
--- /dev/null
+++ b/src/reducers/appMode.js
@@ -0,0 +1,22 @@
+const appModeReducer = (state = "init", action) => {
+ switch (action.type) {
+ case "APP_INIT":
+ return (state = "init");
+ case "APP_SEARCH_RESULTS":
+ return (state = "search results");
+ case "APP_LOGIN":
+ return (state = "login");
+ case "APP_RESTAURANT":
+ return (state = "restaurant");
+ case "APP_DISH":
+ return (state = "dish");
+ case "APP_ADD_RESTAURANT":
+ return (state = "add restaurant");
+ case "APP_ADD_DISH":
+ return (state = "add dish");
+ default:
+ return state;
+ }
+};
+
+export default appModeReducer;
diff --git a/src/reducers/autoComplete.js b/src/reducers/autoComplete.js
new file mode 100644
index 0000000..87edb4e
--- /dev/null
+++ b/src/reducers/autoComplete.js
@@ -0,0 +1,12 @@
+const autoCompleteReducer = (state = [], action) => {
+ switch (action.type) {
+ case "AUTOCOMPLETE_ADD":
+ return action.payload;
+ case "AUTOCOMPLETE_CLEAR":
+ return (state = []);
+ default:
+ return state;
+ }
+};
+
+export default autoCompleteReducer;
diff --git a/src/reducers/index.js b/src/reducers/index.js
new file mode 100644
index 0000000..ad1a00c
--- /dev/null
+++ b/src/reducers/index.js
@@ -0,0 +1,12 @@
+import { combineReducers } from "redux";
+import autoCompleteReducer from "./autoComplete";
+import searchResults from "./searchResults";
+import appMode from "./appMode";
+
+const rootReducer = combineReducers({
+ autocomplete: autoCompleteReducer,
+ appMode: appMode,
+ searchResults: searchResults,
+});
+
+export default rootReducer;
diff --git a/src/reducers/searchResults.js b/src/reducers/searchResults.js
new file mode 100644
index 0000000..84fdc06
--- /dev/null
+++ b/src/reducers/searchResults.js
@@ -0,0 +1,12 @@
+const searchResults = (state = {}, action) => {
+ switch (action.type) {
+ case "SEARCH_RESULTS":
+ return action.payload;
+ case "SEARCH_CLEAR":
+ return (state = {});
+ default:
+ return state;
+ }
+};
+
+export default searchResults;
diff --git a/src/styles/Footer.scss b/src/styles/Footer.scss
new file mode 100644
index 0000000..7d1729d
--- /dev/null
+++ b/src/styles/Footer.scss
@@ -0,0 +1,9 @@
+@import "../Design.scss";
+
+.footer {
+ background-color: $main-color;
+
+ p {
+ color: white;
+ }
+}
diff --git a/src/styles/TopBar.scss b/src/styles/TopBar.scss
index 904783b..0c05ba9 100644
--- a/src/styles/TopBar.scss
+++ b/src/styles/TopBar.scss
@@ -1,8 +1,10 @@
+@import "../Design.scss";
+
.topBar {
width: 100%;
display: flex;
justify-content: space-between;
- background-color: #ebebeb;
+ background-color: $main-color;
}
.topBarLogo {