+ autocomplete + thunk

This commit is contained in:
2020-07-21 19:39:56 +02:00
parent 29efa13410
commit 2bcbfef8ba
16 changed files with 255 additions and 38 deletions

View File

@@ -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 (
<div className="App">
<TopBar />
<div className="main-container">
<img src={logo} className="logo" alt="Menui logo" />
<SearchPanel />
<p className="darkParagraph">
Sprawdź co serwuje Twoja ulubiona restauracja.
</p>
<ThemeProvider theme={theme}>
<div className="App">
<TopBar />
<div className="main-container">
<img src={logo} className="logo" alt="Menui logo" />
<SearchPanel />
<p className="darkParagraph">
Sprawdź co serwuje Twoja ulubiona restauracja.
</p>
</div>
<Footer />
</div>
<Footer />
</div>
</ThemeProvider>
);
}

View File

@@ -1,6 +1,7 @@
@import "./Design.scss";
@import "./styles/TopBar.scss";
@import "./styles/SearchPanel.scss";
@import "./styles/Footer.scss";
.App {
padding: 0;

View File

@@ -0,0 +1 @@
import axios from "axios";

37
src/actions/index.js Normal file
View 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,
};
};

View File

@@ -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",

View File

@@ -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 (
<div className="searchPanel">
<CustomTextInput
color="primary"
id="search"
label="Miasto, nazwa lokalu,..."
type="search"
/>
<div className="btnContainer">
<ButtonSecondary text="Szukaj" />
</div>
export default function SearchPanel() {
let options = useSelector((store) => store.autocomplete);
const dispatch = useDispatch();
return (
<div className="searchPanel">
<Autocomplete
options={options}
style={{ width: 300 }}
noOptionsText="Brak podpowiedzi"
renderInput={(params) => (
<TextField
{...params}
label="Miasto, Nazwa lokalu, ..."
variant="outlined"
onInput={(event) => dispatch(fetchAutocomplete(event.target.value))}
/>
)}
/>
<div className="btnContainer">
<ButtonSecondary text="Szukaj" />
</div>
);
}
</div>
);
}

View File

@@ -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 (
<div className="topBar">
<img src={logo} className="topBarLogo" alt="Menui logo" />
<div>
<ButtonSecondary text="Dodaj Lokal" />
<ButtonSecondary text="Logowanie" />
<ButtonPrimary text="Dodaj Lokal" />
<ButtonPrimary text="Logowanie" />
</div>
</div>
);

View File

@@ -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(
<React.StrictMode>
<Provider store={store}>
<App />
</React.StrictMode>,
</Provider>,
document.getElementById("root")
);

22
src/reducers/appMode.js Normal file
View 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;

View 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
View 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;

View 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
View File

@@ -0,0 +1,9 @@
@import "../Design.scss";
.footer {
background-color: $main-color;
p {
color: white;
}
}

View File

@@ -1,8 +1,10 @@
@import "../Design.scss";
.topBar {
width: 100%;
display: flex;
justify-content: space-between;
background-color: #ebebeb;
background-color: $main-color;
}
.topBarLogo {