+ autocomplete + thunk
This commit is contained in:
74
package-lock.json
generated
74
package-lock.json
generated
@@ -1366,6 +1366,18 @@
|
|||||||
"react-transition-group": "^4.4.0"
|
"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": {
|
"@material-ui/styles": {
|
||||||
"version": "4.10.0",
|
"version": "4.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.10.0.tgz",
|
"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",
|
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz",
|
||||||
"integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA=="
|
"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": {
|
"axobject-query": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
|
"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",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
"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": {
|
"react-scripts": {
|
||||||
"version": "3.4.1",
|
"version": "3.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.4.1.tgz",
|
||||||
@@ -11399,6 +11454,20 @@
|
|||||||
"strip-indent": "^3.0.0"
|
"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": {
|
"regenerate": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz",
|
||||||
@@ -12905,6 +12974,11 @@
|
|||||||
"util.promisify": "~1.0.0"
|
"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": {
|
"symbol-tree": {
|
||||||
"version": "3.2.4",
|
"version": "3.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
|
||||||
|
|||||||
@@ -4,13 +4,18 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@material-ui/core": "^4.11.0",
|
"@material-ui/core": "^4.11.0",
|
||||||
|
"@material-ui/lab": "^4.0.0-alpha.56",
|
||||||
"@testing-library/jest-dom": "^4.2.4",
|
"@testing-library/jest-dom": "^4.2.4",
|
||||||
"@testing-library/react": "^9.5.0",
|
"@testing-library/react": "^9.5.0",
|
||||||
"@testing-library/user-event": "^7.2.1",
|
"@testing-library/user-event": "^7.2.1",
|
||||||
|
"axios": "^0.19.2",
|
||||||
"node-sass": "^4.14.1",
|
"node-sass": "^4.14.1",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"react-dom": "^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": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
|
|||||||
31
src/App.js
31
src/App.js
@@ -4,20 +4,31 @@ import "./App.scss";
|
|||||||
import TopBar from "./components/TopBar";
|
import TopBar from "./components/TopBar";
|
||||||
import Footer from "./components/Footer";
|
import Footer from "./components/Footer";
|
||||||
import SearchPanel from "./components/SearchPanel";
|
import SearchPanel from "./components/SearchPanel";
|
||||||
|
import { createMuiTheme, ThemeProvider } from "@material-ui/core/styles";
|
||||||
|
|
||||||
|
const theme = createMuiTheme({
|
||||||
|
palette: {
|
||||||
|
primary: {
|
||||||
|
main: "#0e8496",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<ThemeProvider theme={theme}>
|
||||||
<TopBar />
|
<div className="App">
|
||||||
<div className="main-container">
|
<TopBar />
|
||||||
<img src={logo} className="logo" alt="Menui logo" />
|
<div className="main-container">
|
||||||
<SearchPanel />
|
<img src={logo} className="logo" alt="Menui logo" />
|
||||||
<p className="darkParagraph">
|
<SearchPanel />
|
||||||
Sprawdź co serwuje Twoja ulubiona restauracja.
|
<p className="darkParagraph">
|
||||||
</p>
|
Sprawdź co serwuje Twoja ulubiona restauracja.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
<Footer />
|
</ThemeProvider>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
@import "./Design.scss";
|
@import "./Design.scss";
|
||||||
@import "./styles/TopBar.scss";
|
@import "./styles/TopBar.scss";
|
||||||
@import "./styles/SearchPanel.scss";
|
@import "./styles/SearchPanel.scss";
|
||||||
|
@import "./styles/Footer.scss";
|
||||||
|
|
||||||
.App {
|
.App {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
|||||||
37
src/actions/index.js
Normal file
37
src/actions/index.js
Normal file
@@ -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,
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -4,12 +4,13 @@ import Button from "@material-ui/core/Button";
|
|||||||
|
|
||||||
const StyledButton = withStyles({
|
const StyledButton = withStyles({
|
||||||
root: {
|
root: {
|
||||||
background: "none",
|
background: "white",
|
||||||
color: "white",
|
color: "#0e8496",
|
||||||
margin: "16px 16px 16px 0px",
|
margin: "16px 16px 16px 0px",
|
||||||
padding: "8px 12px 8px 12px",
|
padding: "8px 12px 8px 12px",
|
||||||
borderColor: "white",
|
"&:hover": {
|
||||||
border: "solid 1px",
|
color: "white",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
label: {
|
label: {
|
||||||
textTransform: "none",
|
textTransform: "none",
|
||||||
|
|||||||
@@ -1,21 +1,33 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ButtonSecondary from "./ButtonSecondary";
|
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 {
|
export default function SearchPanel() {
|
||||||
render() {
|
let options = useSelector((store) => store.autocomplete);
|
||||||
return (
|
const dispatch = useDispatch();
|
||||||
<div className="searchPanel">
|
|
||||||
<CustomTextInput
|
return (
|
||||||
color="primary"
|
<div className="searchPanel">
|
||||||
id="search"
|
<Autocomplete
|
||||||
label="Miasto, nazwa lokalu,..."
|
options={options}
|
||||||
type="search"
|
style={{ width: 300 }}
|
||||||
/>
|
noOptionsText="Brak podpowiedzi"
|
||||||
<div className="btnContainer">
|
renderInput={(params) => (
|
||||||
<ButtonSecondary text="Szukaj" />
|
<TextField
|
||||||
</div>
|
{...params}
|
||||||
|
label="Miasto, Nazwa lokalu, ..."
|
||||||
|
variant="outlined"
|
||||||
|
onInput={(event) => dispatch(fetchAutocomplete(event.target.value))}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="btnContainer">
|
||||||
|
<ButtonSecondary text="Szukaj" />
|
||||||
</div>
|
</div>
|
||||||
);
|
</div>
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ButtonSecondary from "./ButtonSecondary";
|
import ButtonPrimary from "./ButtonPrimary";
|
||||||
import logo from "../public/logo_mint.svg";
|
import logo from "../public/logo_white.svg";
|
||||||
|
|
||||||
export default function TopBar() {
|
export default function TopBar() {
|
||||||
return (
|
return (
|
||||||
<div className="topBar">
|
<div className="topBar">
|
||||||
<img src={logo} className="topBarLogo" alt="Menui logo" />
|
<img src={logo} className="topBarLogo" alt="Menui logo" />
|
||||||
<div>
|
<div>
|
||||||
<ButtonSecondary text="Dodaj Lokal" />
|
<ButtonPrimary text="Dodaj Lokal" />
|
||||||
<ButtonSecondary text="Logowanie" />
|
<ButtonPrimary text="Logowanie" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
10
src/index.js
10
src/index.js
@@ -1,13 +1,19 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
|
import { Provider } from "react-redux";
|
||||||
import "./index.scss";
|
import "./index.scss";
|
||||||
import App from "./App";
|
import App from "./App";
|
||||||
import * as serviceWorker from "./serviceWorker";
|
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(
|
ReactDOM.render(
|
||||||
<React.StrictMode>
|
<Provider store={store}>
|
||||||
<App />
|
<App />
|
||||||
</React.StrictMode>,
|
</Provider>,
|
||||||
document.getElementById("root")
|
document.getElementById("root")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
22
src/reducers/appMode.js
Normal file
22
src/reducers/appMode.js
Normal file
@@ -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;
|
||||||
12
src/reducers/autoComplete.js
Normal file
12
src/reducers/autoComplete.js
Normal file
@@ -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;
|
||||||
12
src/reducers/index.js
Normal file
12
src/reducers/index.js
Normal file
@@ -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;
|
||||||
12
src/reducers/searchResults.js
Normal file
12
src/reducers/searchResults.js
Normal file
@@ -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;
|
||||||
9
src/styles/Footer.scss
Normal file
9
src/styles/Footer.scss
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
@import "../Design.scss";
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
background-color: $main-color;
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
|
@import "../Design.scss";
|
||||||
|
|
||||||
.topBar {
|
.topBar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
background-color: #ebebeb;
|
background-color: $main-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.topBarLogo {
|
.topBarLogo {
|
||||||
|
|||||||
Reference in New Issue
Block a user