new look / search list / restaurant view
This commit is contained in:
@@ -5,6 +5,7 @@ import LogoMain from "./components/logoMain";
|
|||||||
import Footer from "./components/Footer";
|
import Footer from "./components/Footer";
|
||||||
import SearchPanel from "./components/SearchPanel";
|
import SearchPanel from "./components/SearchPanel";
|
||||||
import SearchResults from "./components/SearchResults";
|
import SearchResults from "./components/SearchResults";
|
||||||
|
import Restaurant from "./components/Restaurant";
|
||||||
import { createMuiTheme, ThemeProvider } from "@material-ui/core/styles";
|
import { createMuiTheme, ThemeProvider } from "@material-ui/core/styles";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
@@ -25,13 +26,16 @@ function App() {
|
|||||||
<TopBar />
|
<TopBar />
|
||||||
<div className="main-container">
|
<div className="main-container">
|
||||||
<LogoMain />
|
<LogoMain />
|
||||||
<SearchPanel />
|
{(appMode === "init" || appMode === "search results") && (
|
||||||
|
<SearchPanel />
|
||||||
|
)}
|
||||||
{appMode === "init" && (
|
{appMode === "init" && (
|
||||||
<p className="darkParagraph">
|
<p className="darkParagraph">
|
||||||
Sprawdź co serwuje Twoja ulubiona restauracja.
|
Sprawdź co serwuje Twoja ulubiona restauracja.
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
{appMode === "search results" && <SearchResults />}
|
{appMode === "search results" && <SearchResults />}
|
||||||
|
{appMode === "restaurant" && <Restaurant />}
|
||||||
</div>
|
</div>
|
||||||
<Footer />
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,13 +4,14 @@
|
|||||||
@import "./styles/Footer.scss";
|
@import "./styles/Footer.scss";
|
||||||
@import "./styles/SearchResults.scss";
|
@import "./styles/SearchResults.scss";
|
||||||
@import "./styles/Pictograms.scss";
|
@import "./styles/Pictograms.scss";
|
||||||
|
@import "./styles/Restaurant.scss";
|
||||||
|
|
||||||
.App {
|
.App {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: $bg-color;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
background-color: $bg-color;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@@ -41,4 +42,5 @@ p {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
flex-grow: 20;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,14 @@
|
|||||||
$main-color: #01c3a9;
|
$main-color: #eb9800;
|
||||||
$secondary-color: #307482;
|
$secondary-color: #307482;
|
||||||
$darker-color: #234f53;
|
$darker-color: #234f53;
|
||||||
$bg-color: #ffffff;
|
$bg-color: #ffffff;
|
||||||
$accents-color: #0e8496;
|
$accents-color: #0e8496;
|
||||||
$lighter-color: #00d1b5;
|
$lighter-color: #00d1b5;
|
||||||
|
|
||||||
|
/* $main-color: #01c3a9;
|
||||||
|
$secondary-color: #307482;
|
||||||
|
$darker-color: #234f53;
|
||||||
|
$bg-color: #ffffff;
|
||||||
|
$accents-color: #0e8496;
|
||||||
|
$lighter-color: #00d1b5;
|
||||||
|
*/
|
||||||
|
|||||||
@@ -68,3 +68,40 @@ export const setAppMode = (mode) => {
|
|||||||
type: mode,
|
type: mode,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const setRestaurant = (restaurant) => {
|
||||||
|
return {
|
||||||
|
type: "SET_RESTAURANT",
|
||||||
|
payload: restaurant,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const fetchRestaurant = (id) => {
|
||||||
|
return function (dispatch) {
|
||||||
|
axios
|
||||||
|
.get("http://localhost:4000/restaurant?restaurantId=" + id)
|
||||||
|
.then((response) => {
|
||||||
|
dispatch(setRestaurant(response.data));
|
||||||
|
dispatch(setAppMode("APP_RESTAURANT"));
|
||||||
|
dispatch(fetchAllDishes(id));
|
||||||
|
})
|
||||||
|
.catch((err) => console.log(err));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const setDishes = (data) => {
|
||||||
|
return {
|
||||||
|
type: "SET_DISHES",
|
||||||
|
payload: data,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const fetchAllDishes = (id) => {
|
||||||
|
return function (dispatch) {
|
||||||
|
axios
|
||||||
|
.get("http://localhost:4000/restaurant/dishes?restaurantId=" + id)
|
||||||
|
.then((response) => {
|
||||||
|
dispatch(setDishes(response.data));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,10 +1,31 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import Pictograms from "./Pictograms";
|
import Pictograms from "./Pictograms";
|
||||||
|
import { fetchRestaurant } from "../actions";
|
||||||
|
import { useDispatch } from "react-redux";
|
||||||
|
|
||||||
|
function extractTags(tags) {
|
||||||
|
var results = [];
|
||||||
|
for (let [key, value] of Object.entries(tags)) {
|
||||||
|
if (value === true) {
|
||||||
|
results.push(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
export default function CardRestaurant(props) {
|
export default function CardRestaurant(props) {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const img = props.imgUrl;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card-restaurant">
|
<div
|
||||||
<div className="card-img"></div>
|
onClick={() => dispatch(fetchRestaurant(props.id))}
|
||||||
|
className="card-restaurant"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="card-img"
|
||||||
|
style={{ backgroundImage: "url(" + img + ")" }}
|
||||||
|
></div>
|
||||||
<div className="card-info">
|
<div className="card-info">
|
||||||
<div className="title-info">
|
<div className="title-info">
|
||||||
<h1>{props.name}</h1>
|
<h1>{props.name}</h1>
|
||||||
@@ -13,26 +34,10 @@ export default function CardRestaurant(props) {
|
|||||||
<h3>Godziny otwarcia: {props.hours}</h3>
|
<h3>Godziny otwarcia: {props.hours}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div className="card-description">
|
<div className="card-description">
|
||||||
<p>
|
<p>{props.description}</p>
|
||||||
Jakiś krótki opis restauracji. Coś tam że jest przytulnie i
|
|
||||||
elegancko.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="card-pictograms">
|
<div className="card-pictograms">
|
||||||
<Pictograms
|
<Pictograms pictograms={extractTags(props.tags)} />
|
||||||
pictograms={[
|
|
||||||
"alcohol",
|
|
||||||
"card",
|
|
||||||
"delivery",
|
|
||||||
"glutenFree",
|
|
||||||
"vegan",
|
|
||||||
"vegetarian",
|
|
||||||
"eggs",
|
|
||||||
"gluten",
|
|
||||||
"lactose",
|
|
||||||
"lactoseFree",
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ function getImage(name) {
|
|||||||
switch (name) {
|
switch (name) {
|
||||||
case "alcohol":
|
case "alcohol":
|
||||||
return alcohol;
|
return alcohol;
|
||||||
case "card":
|
case "cardPayments":
|
||||||
return card;
|
return card;
|
||||||
case "delivery":
|
case "delivery":
|
||||||
return delivery;
|
return delivery;
|
||||||
@@ -36,7 +36,7 @@ function getImage(name) {
|
|||||||
return lactoseFree;
|
return lactoseFree;
|
||||||
case "peanuts":
|
case "peanuts":
|
||||||
return peanuts;
|
return peanuts;
|
||||||
case "pets":
|
case "petFriendly":
|
||||||
return pets;
|
return pets;
|
||||||
case "seaFood":
|
case "seaFood":
|
||||||
return seaFood;
|
return seaFood;
|
||||||
@@ -49,13 +49,18 @@ function getImage(name) {
|
|||||||
case "vegetarian":
|
case "vegetarian":
|
||||||
return vegetarian;
|
return vegetarian;
|
||||||
default:
|
default:
|
||||||
return false;
|
return card;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function (props) {
|
export default function (props) {
|
||||||
const pictograms = props.pictograms.map((pictogram) => (
|
const pictograms = props.pictograms.map((pictogram, index) => (
|
||||||
<img className="pictogram" src={getImage(pictogram)} alt={pictogram} />
|
<img
|
||||||
|
key={index}
|
||||||
|
className="pictogram"
|
||||||
|
src={getImage(pictogram)}
|
||||||
|
alt={pictogram}
|
||||||
|
/>
|
||||||
));
|
));
|
||||||
|
|
||||||
return <div className="pictograms-container">{pictograms}</div>;
|
return <div className="pictograms-container">{pictograms}</div>;
|
||||||
|
|||||||
32
src/components/Restaurant.js
Normal file
32
src/components/Restaurant.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import React from "react";
|
||||||
|
import Pictograms from "./Pictograms";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
|
export default function Restaurant(props) {
|
||||||
|
const restaurant = useSelector((state) => state.restaurant);
|
||||||
|
function extractTags(tags) {
|
||||||
|
var results = [];
|
||||||
|
for (let [key, value] of Object.entries(tags)) {
|
||||||
|
if (value === true) {
|
||||||
|
results.push(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="restaurant-container">
|
||||||
|
<div
|
||||||
|
className="restaurant-hero"
|
||||||
|
style={{ backgroundImage: "url(" + restaurant.imgUrl + ")" }}
|
||||||
|
>
|
||||||
|
<div className="restaurant-pictograms">
|
||||||
|
<Pictograms pictograms={extractTags(restaurant.tags)} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h1>{restaurant.name}</h1>
|
||||||
|
<p>{restaurant.city}</p>
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -7,15 +7,16 @@ export default function SearchResults() {
|
|||||||
const array = Array.from(results);
|
const array = Array.from(results);
|
||||||
var count = results.length;
|
var count = results.length;
|
||||||
const restaurants = array.map((restaurant) => (
|
const restaurants = array.map((restaurant) => (
|
||||||
<li key={restaurant._id}>
|
<CardRestaurant
|
||||||
<CardRestaurant
|
key={restaurant._id}
|
||||||
name={restaurant.name}
|
id={restaurant._id}
|
||||||
city={restaurant.city}
|
name={restaurant.name}
|
||||||
imgUrl={restaurant.imgUrl}
|
city={restaurant.city}
|
||||||
hours={restaurant.workingHours}
|
description={restaurant.description}
|
||||||
tags={restaurant.tags}
|
imgUrl={restaurant.imgUrl}
|
||||||
/>
|
hours={restaurant.workingHours}
|
||||||
</li>
|
tags={restaurant.tags}
|
||||||
|
/>
|
||||||
));
|
));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -24,7 +25,7 @@ export default function SearchResults() {
|
|||||||
<p>Znaleziono: {count}</p>
|
<p>Znaleziono: {count}</p>
|
||||||
<hr />
|
<hr />
|
||||||
</div>
|
</div>
|
||||||
<ul>{restaurants}</ul>
|
{restaurants}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
src/public/photo.jpg
Normal file
BIN
src/public/photo.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 174 KiB |
14
src/reducers/dishes.js
Normal file
14
src/reducers/dishes.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
const dishes = (state = [], action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case "SET_DISHES":
|
||||||
|
return (state = action.payload);
|
||||||
|
case "ADD_DISH":
|
||||||
|
return [...state, action.payload];
|
||||||
|
case "CLEAR_DISHES":
|
||||||
|
return (state = []);
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default dishes;
|
||||||
@@ -3,12 +3,16 @@ import autoCompleteReducer from "./autoComplete";
|
|||||||
import searchResults from "./searchResults";
|
import searchResults from "./searchResults";
|
||||||
import appMode from "./appMode";
|
import appMode from "./appMode";
|
||||||
import searchQuery from "./searchQuery";
|
import searchQuery from "./searchQuery";
|
||||||
|
import restaurant from "./restaurant";
|
||||||
|
import dishes from "./dishes";
|
||||||
|
|
||||||
const rootReducer = combineReducers({
|
const rootReducer = combineReducers({
|
||||||
autocomplete: autoCompleteReducer,
|
autocomplete: autoCompleteReducer,
|
||||||
appMode: appMode,
|
appMode: appMode,
|
||||||
searchResults: searchResults,
|
searchResults: searchResults,
|
||||||
searchQuery: searchQuery,
|
searchQuery: searchQuery,
|
||||||
|
restaurant: restaurant,
|
||||||
|
dishes: dishes,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default rootReducer;
|
export default rootReducer;
|
||||||
|
|||||||
12
src/reducers/restaurant.js
Normal file
12
src/reducers/restaurant.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
const restaurant = (state = {}, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case "SET_RESTAURANT":
|
||||||
|
return (state = action.payload);
|
||||||
|
case "CLEAR_RESTAURANT":
|
||||||
|
return (state = {});
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default restaurant;
|
||||||
36
src/styles/Restaurant.scss
Normal file
36
src/styles/Restaurant.scss
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
.restaurant-container {
|
||||||
|
min-width: 100vw;
|
||||||
|
height: 100%;
|
||||||
|
h1 {
|
||||||
|
font-weight: 100;
|
||||||
|
font-size: 3rem;
|
||||||
|
margin: 16px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
margin: 6px;
|
||||||
|
color: $secondary-color;
|
||||||
|
}
|
||||||
|
hr {
|
||||||
|
border: solid 1px $main-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.restaurant-hero {
|
||||||
|
width: 100%;
|
||||||
|
height: 400px;
|
||||||
|
background-size: cover;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.restaurant-pictograms {
|
||||||
|
background-color: white;
|
||||||
|
width: fit-content;
|
||||||
|
padding: 4px;
|
||||||
|
margin: 20px;
|
||||||
|
border-radius: 50px;
|
||||||
|
.pictograms-container {
|
||||||
|
margin: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,23 +4,27 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.card-restaurant {
|
.card-restaurant {
|
||||||
|
border: solid 1px rgb(224, 224, 224);
|
||||||
|
border-radius: 25px;
|
||||||
margin: 20px 0px 20px 0px;
|
margin: 20px 0px 20px 0px;
|
||||||
color: $secondary-color;
|
color: $secondary-color;
|
||||||
min-width: 70vw;
|
max-width: 70vw;
|
||||||
min-height: 200px;
|
min-height: 200px;
|
||||||
display: flex;
|
display: flex;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
transition: all 0.25s;
|
||||||
&:hover {
|
&:hover {
|
||||||
color: $main-color;
|
background-color: #fcfcfc;
|
||||||
|
border-color: rgba(241, 177, 38, 0.87);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-img {
|
.card-img {
|
||||||
width: 180px;
|
min-width: 180px;
|
||||||
height: 180px;
|
height: 180px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
border-radius: 100px;
|
border-radius: 18px;
|
||||||
background-image: url("../public/cat.jpg");
|
//border-radius: 100px;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +55,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.card-pictograms {
|
.card-pictograms {
|
||||||
margin-bottom: 4px;
|
margin-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.results-count {
|
.results-count {
|
||||||
|
|||||||
Reference in New Issue
Block a user