From 1d6cae188f4156b52498a54deee83204b3eac4f8 Mon Sep 17 00:00:00 2001 From: Alexandra Boyko Date: Tue, 14 Jan 2020 17:55:30 +0200 Subject: [PATCH 1/4] Restaurants cards + basic header --- package.json | 7 ++- public/images/logo.svg | 4 ++ public/images/place.svg | 4 ++ public/images/search.svg | 3 + public/index.html | 2 + src/App.js | 10 +++- src/components/Header/Header.js | 44 ++++++++++++++ src/components/Header/Header.scss | 29 +++++++++ src/components/input/Input.js | 55 +++++++++++++++++ src/components/input/Input.scss | 22 +++++++ .../restaurantCard/RestaurantCard.js | 37 ++++++++++++ .../restaurantCard/RestaurantCard.scss | 30 ++++++++++ .../RestaurantsListPage.js | 59 +++++++++++++++++++ .../RestaurantsListPage.scss | 5 ++ src/index.js | 9 ++- src/store/actions.js | 16 +++++ src/store/index.js | 28 +++++++++ src/store/selectors.js | 16 +++++ src/store/styles/extends.scss | 5 ++ src/store/styles/index.scss | 30 ++++++++++ 20 files changed, 412 insertions(+), 3 deletions(-) create mode 100644 public/images/logo.svg create mode 100644 public/images/place.svg create mode 100644 public/images/search.svg create mode 100644 src/components/Header/Header.js create mode 100644 src/components/Header/Header.scss create mode 100644 src/components/input/Input.js create mode 100644 src/components/input/Input.scss create mode 100644 src/components/restaurantCard/RestaurantCard.js create mode 100644 src/components/restaurantCard/RestaurantCard.scss create mode 100644 src/components/restaurantsListPage/RestaurantsListPage.js create mode 100644 src/components/restaurantsListPage/RestaurantsListPage.scss create mode 100644 src/store/actions.js create mode 100644 src/store/index.js create mode 100644 src/store/selectors.js create mode 100644 src/store/styles/extends.scss create mode 100644 src/store/styles/index.scss diff --git a/package.json b/package.json index 7bd01de..f05337b 100755 --- a/package.json +++ b/package.json @@ -7,11 +7,16 @@ "author": "Mate Academy", "license": "GPL-3.0", "dependencies": { + "node-sass": "^4.13.0", "prop-types": "^15.7.2", "react": "^16.8.6", "react-dom": "^16.8.6", + "react-redux": "^7.1.3", "react-router-dom": "^5.0.1", - "react-scripts": "3.0.1" + "react-scripts": "3.0.1", + "redux": "^4.0.5", + "redux-thunk": "^2.3.0", + "reselect": "^4.0.0" }, "devDependencies": { "@mate-academy/eslint-config-react": "*", diff --git a/public/images/logo.svg b/public/images/logo.svg new file mode 100644 index 0000000..7418753 --- /dev/null +++ b/public/images/logo.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/images/place.svg b/public/images/place.svg new file mode 100644 index 0000000..a2f570f --- /dev/null +++ b/public/images/place.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/images/search.svg b/public/images/search.svg new file mode 100644 index 0000000..7e37c73 --- /dev/null +++ b/public/images/search.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/index.html b/public/index.html index 4269d67..80fd8f0 100644 --- a/public/index.html +++ b/public/index.html @@ -4,6 +4,8 @@ React Uber eats + +
diff --git a/src/App.js b/src/App.js index d494a99..9aeb1e9 100644 --- a/src/App.js +++ b/src/App.js @@ -1,9 +1,17 @@ import React from 'react'; import './App.css'; +import RestaurantsListPage from + './components/restaurantsListPage/RestaurantsListPage'; +import Header from './components/Header/Header'; const App = () => ( +
-

React Uber eats

+
+
+ +
+
); diff --git a/src/components/Header/Header.js b/src/components/Header/Header.js new file mode 100644 index 0000000..f9a440b --- /dev/null +++ b/src/components/Header/Header.js @@ -0,0 +1,44 @@ +import React from 'react'; +import Input from '../input/Input'; +import './Header.scss'; + +const Header = () => ( +
+
+
+ Uber Eats +
+ {}} + placeholder="Address" + iconUrl="./images/place.svg" + /> + {}} + placeholder="Time" + /> +
+ {}} + placeholder="Search" + iconUrl="./images/search.svg" + className="header__search" + /> + + Sign in + +
+
+
+); + +export default Header; diff --git a/src/components/Header/Header.scss b/src/components/Header/Header.scss new file mode 100644 index 0000000..98a6eb3 --- /dev/null +++ b/src/components/Header/Header.scss @@ -0,0 +1,29 @@ +@import "../../store/styles/extends.scss"; + +.header { + padding: 28px 0; + + &__inner { + @extend %flex-row; + } + + &__delivery-info { + @extend %flex-row; + margin-left: 7vw; + } + + &__search { + margin-left: auto; + } + + &__link { + margin-left: 40px; + color: #1f1f1f; + padding: 13px 0; + white-space: nowrap; + + &:hover { + text-decoration: underline; + } + } +} diff --git a/src/components/input/Input.js b/src/components/input/Input.js new file mode 100644 index 0000000..e966e00 --- /dev/null +++ b/src/components/input/Input.js @@ -0,0 +1,55 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import './Input.scss'; + +const Input = ({ + iconUrl, + value, + onChange, + type, + placeholder, + name, + className, +}) => { + const rootClass = `control ${className}`; + + return ( +
+ {!!iconUrl + && ( + {placeholder} + )} + +
+ ); +}; + +Input.propTypes = { + value: PropTypes.string.isRequired, + onChange: PropTypes.func.isRequired, + name: PropTypes.string.isRequired, + iconUrl: PropTypes.string, + type: PropTypes.string, + placeholder: PropTypes.string, + className: PropTypes.string, +}; + +Input.defaultProps = { + iconUrl: '', + type: 'text', + placeholder: '', + className: '', +}; + +export default Input; diff --git a/src/components/input/Input.scss b/src/components/input/Input.scss new file mode 100644 index 0000000..2688a3d --- /dev/null +++ b/src/components/input/Input.scss @@ -0,0 +1,22 @@ +@import "../../store/styles/extends.scss"; + +.control { + @extend %flex-row; + + padding: 12px 16px; + border: 1px solid #e0e0e0; + + &__icon { + width: 14px; + height: 14px; + margin-right: 10px; + } + + &__input { + max-height: 24px; + } + + & + & { + margin-left: 20px; + } +} diff --git a/src/components/restaurantCard/RestaurantCard.js b/src/components/restaurantCard/RestaurantCard.js new file mode 100644 index 0000000..ba4e7dd --- /dev/null +++ b/src/components/restaurantCard/RestaurantCard.js @@ -0,0 +1,37 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import './RestaurantCard.scss'; + +export const RestaurantCard = ({ + imageUrl, + title, + categories, + etaRange, + uuid, +}) => ( +
+ {title} +

{title}

+
+ {categories.join(' • ')} +
+
{etaRange}
+
+); + +RestaurantCard.propTypes = { + imageUrl: PropTypes.string.isRequired, + title: PropTypes.string.isRequired, + categories: PropTypes.arrayOf(PropTypes.string), + etaRange: PropTypes.string, + uuid: PropTypes.string.isRequired, +}; + +RestaurantCard.defaultProps = { + categories: [], + etaRange: '', +}; diff --git a/src/components/restaurantCard/RestaurantCard.scss b/src/components/restaurantCard/RestaurantCard.scss new file mode 100644 index 0000000..397cce0 --- /dev/null +++ b/src/components/restaurantCard/RestaurantCard.scss @@ -0,0 +1,30 @@ +.restaurant-card { + $height: 367px; + + height: $height; + width: 100%; + cursor: pointer; + + &__img { + height: $height * 0.7; + width: 100%; + object-fit: cover; + } + + &__title { + margin: 12px 0 4px; + } + + &__categories { + font-size: 14px; + color: #757575; + margin-bottom: 4px; + } + + &__eta { + padding: 2px 8px; + background-color: #f5f5f5; + font-size: 14px; + display: inline-block; + } +} diff --git a/src/components/restaurantsListPage/RestaurantsListPage.js b/src/components/restaurantsListPage/RestaurantsListPage.js new file mode 100644 index 0000000..19c6516 --- /dev/null +++ b/src/components/restaurantsListPage/RestaurantsListPage.js @@ -0,0 +1,59 @@ +import React, { useEffect } from 'react'; +import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; +import { uploadRestaurants } from '../../store/actions'; +import { seleсtRestaurantsList } from '../../store/selectors'; +import { RestaurantCard } from '../restaurantCard/RestaurantCard'; +import './RestaurantsListPage.scss'; + +const RestaurantsListPage = ({ loadRestaurants, restaurantsData }) => { + useEffect(() => { + loadRestaurants(); + }, []); + + return ( +
+ {restaurantsData.map((restaurant) => { + const { + heroImageUrl, + title, + categories, + etaRange, + uuid, + } = restaurant; + + return ( + + ); + })} +
+ ); +}; + +const mapStateToProps = state => ({ + restaurantsData: seleсtRestaurantsList(state), +}); + +const mapDispatchToProps = dispatch => ({ + loadRestaurants: value => dispatch(uploadRestaurants(value)), +}); + +export default connect( + mapStateToProps, + mapDispatchToProps +)(RestaurantsListPage); + +RestaurantsListPage.propTypes = { + restaurantsData: PropTypes.arrayOf(PropTypes.shape({})), + loadRestaurants: PropTypes.func.isRequired, +}; + +RestaurantsListPage.defaultProps = { + restaurantsData: [], +}; diff --git a/src/components/restaurantsListPage/RestaurantsListPage.scss b/src/components/restaurantsListPage/RestaurantsListPage.scss new file mode 100644 index 0000000..a87ec4f --- /dev/null +++ b/src/components/restaurantsListPage/RestaurantsListPage.scss @@ -0,0 +1,5 @@ +.restaurants-list { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(348px, 1fr)); + gap: 40px 20px; +} diff --git a/src/index.js b/src/index.js index b597a44..703b9e4 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,12 @@ import React from 'react'; import ReactDOM from 'react-dom'; +import { Provider } from 'react-redux'; +import { store } from './store/index'; import App from './App'; -ReactDOM.render(, document.getElementById('root')); +ReactDOM.render( + + + , + document.getElementById('root') +); diff --git a/src/store/actions.js b/src/store/actions.js new file mode 100644 index 0000000..0b23521 --- /dev/null +++ b/src/store/actions.js @@ -0,0 +1,16 @@ +export const ACTION_TYPES = { + SAVE_RESTAURANTS: 'SAVE_RESTAURANTS', +}; + +const saveRestaurants = value => ({ + type: ACTION_TYPES.SAVE_RESTAURANTS, + payload: value, +}); + +export const uploadRestaurants = () => (dispatch) => { + fetch('https://mate-uber-eats-api.herokuapp.com/api/v1/restaurants') + .then(res => res.json()) + .then(({ data }) => { + dispatch(saveRestaurants(data)); + }); +}; diff --git a/src/store/index.js b/src/store/index.js new file mode 100644 index 0000000..44792fa --- /dev/null +++ b/src/store/index.js @@ -0,0 +1,28 @@ +import { createStore, compose, applyMiddleware } from 'redux'; +import thunk from 'redux-thunk'; +import { ACTION_TYPES } from './actions'; +import './styles/index.scss'; + +const comoseEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; +const middleWares = [thunk]; + +const initialState = { + restaurantsListData: null, +}; + +const reducer = (state = initialState, action) => { + switch (action.type) { + case ACTION_TYPES.SAVE_RESTAURANTS: + return { + ...state, + restaurantsListData: action.payload, + }; + default: + return state; + } +}; + +export const store = createStore( + reducer, + comoseEnhancers(applyMiddleware(...middleWares)) +); diff --git a/src/store/selectors.js b/src/store/selectors.js new file mode 100644 index 0000000..1e8cf76 --- /dev/null +++ b/src/store/selectors.js @@ -0,0 +1,16 @@ +import { createSelector } from 'reselect'; + +const rootSelector = state => state; + +export const seleсtRestaurantsList = createSelector( + rootSelector, + ({ restaurantsListData }) => { + if (!restaurantsListData) { + return []; + } + + const { feedItems, storesMap } = restaurantsListData; + + return feedItems.map(item => storesMap[item.uuid]); + } +); diff --git a/src/store/styles/extends.scss b/src/store/styles/extends.scss new file mode 100644 index 0000000..a2e1538 --- /dev/null +++ b/src/store/styles/extends.scss @@ -0,0 +1,5 @@ +%flex-row { + display: flex; + flex-flow: row nowrap; + align-items: center; +} diff --git a/src/store/styles/index.scss b/src/store/styles/index.scss new file mode 100644 index 0000000..c4e191b --- /dev/null +++ b/src/store/styles/index.scss @@ -0,0 +1,30 @@ +*, +::after, +::before { + box-sizing: border-box; +} + +body, +button, +a, +input { + font-family: Roboto, sans-serif; + font-size: 16px; + line-height: 1.5; +} + +input { + border: none; + background: transparent; + outline: none; +} + +a { + text-decoration: none; +} + +.content { + max-width: 1160px; + padding: 0 34px; + margin: 0 auto; +} From cef42ebe52fbb29add99408ffd2b2500f0280929 Mon Sep 17 00:00:00 2001 From: Alexandra Boyko Date: Tue, 14 Jan 2020 18:05:48 +0200 Subject: [PATCH 2/4] readme changed --- README.md | 22 +++++++++++----------- package.json | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 84c7a15..4cecd95 100644 --- a/README.md +++ b/README.md @@ -15,13 +15,13 @@ Base API url: https://mate-uber-eats-api.herokuapp.com/api/v1/ - use `redux-thunk` to handle async actions - create separate component for restaurant card - use https://mate-uber-eats-api.herokuapp.com/api/v1/restaurants endpoint to fetch data - - accept optional query parameter `location`: `london|kyiv` - - `RestaurantCard` should be clickable fully (not only the image) + - accept optional query parameter `location`: `london|kyiv` + - `RestaurantCard` should be clickable fully (not only the image) 2. Implement basic header markup 3. Implement footer 4. Add functionality and styles for mobile and tablet versions - `Location`, `Deliver now` and `Search` should be replaced whith buttons on the small screens. - Block with inputs should apper below the header after click on the button. + Block with inputs should apper below the header after click on the button. 5. Implement `RestaurantPage` - use `uuid` in the URL - fetch data from https://mate-uber-eats-api.herokuapp.com/api/v1/restaurants/:uuid @@ -57,7 +57,7 @@ Base API url: https://mate-uber-eats-api.herokuapp.com/api/v1/ - open basket sidebar when click on busket button, close on click outside or close icon - add item to basket when click submit in MenuItemModal - show list added items in basket - - add ability to change item count, remove item + - add ability to change item count, remove item - when user click edit on item - open MenuItemModal with additional remove button. After submit, edit current item instead of add new one - clear basket when user click order button 5. Restore user session after close-open tab @@ -69,27 +69,27 @@ Base API url: https://mate-uber-eats-api.herokuapp.com/api/v1/ ## Workflow - Fork the repository with task -- Clone forked repository +- Clone forked repository ```bash git clone git@github.com:/.git ``` - Run `npm install` to install dependencies. - Then develop -## Development mode +## Development mode - Run `npm start` to start development server on `http://localhost:3000` - When you run server the command line window will no longer be available for - writing commands until you stop server (`ctrl + c`). All other commands you + When you run server the command line window will no longer be available for + writing commands until you stop server (`ctrl + c`). All other commands you need to run in new command line window. - Follow [HTML, CSS styleguide](https://mate-academy.github.io/style-guides/htmlcss.html) - Follow [the simplified JS styleguide](https://mate-academy.github.io/style-guides/javascript-standard-modified) - run `npm run lint` to check code style -- When you finished add correct `homepage` to `package.json` and run `npm run deploy` +- When you finished add correct `homepage` to `package.json` and run `npm run deploy` - Add links to your demo in readme.md. - - `[DEMO LINK](https://.github.io//)` - this will be a + - `[DEMO LINK](https://aleksandra04.github.io/react_uber-eats/` - this will be a link to your index.html - Commit and push all recent changes. -- Create `Pull Request` from forked repo `()` to original repo +- Create `Pull Request` from forked repo `()` to original repo (`master`). - Add a link at `PR` to Google Spreadsheets. diff --git a/package.json b/package.json index f05337b..8263fc4 100755 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "homepage": "https://mate-academy.github.io/react_uber-eats", + "homepage": "https://aleksandra04.github.io/react_uber-eats", "name": "react_uber-eats", "version": "0.1.0", "private": true, From 39eb5511f583a3981426bea755c6204b814072c0 Mon Sep 17 00:00:00 2001 From: Alexandra Boyko Date: Thu, 16 Jan 2020 00:44:51 +0200 Subject: [PATCH 3/4] adaptive header and footer added --- package.json | 1 + public/images/app-store.png | Bin 0 -> 3656 bytes public/images/arrow.svg | 3 + public/images/facebook.svg | 3 + public/images/footer-logo.svg | 4 + public/images/google-play.png | Bin 0 -> 4112 bytes public/images/instagram.svg | 5 + public/images/twitter.svg | 3 + public/images/world.svg | 5 + public/images/x.svg | 3 + src/App.css | 6 +- src/App.js | 16 +- src/components/Header/Header.js | 171 ++++++++++++++---- src/components/Header/Header.scss | 63 ++++++- src/components/footer/Footer.js | 107 +++++++++++ src/components/footer/Footer.scss | 140 ++++++++++++++ src/components/input/Input.js | 72 ++++++-- src/components/input/Input.scss | 31 +++- .../restaurantCard/RestaurantCard.scss | 12 +- .../RestaurantsListPage.scss | 15 +- src/components/select/Select.js | 51 ++++++ src/components/select/Select.scss | 34 ++++ src/store/styles/index.scss | 19 +- src/store/styles/variables.scss | 6 + 24 files changed, 697 insertions(+), 73 deletions(-) create mode 100644 public/images/app-store.png create mode 100644 public/images/arrow.svg create mode 100644 public/images/facebook.svg create mode 100644 public/images/footer-logo.svg create mode 100644 public/images/google-play.png create mode 100644 public/images/instagram.svg create mode 100644 public/images/twitter.svg create mode 100644 public/images/world.svg create mode 100644 public/images/x.svg create mode 100644 src/components/footer/Footer.js create mode 100644 src/components/footer/Footer.scss create mode 100644 src/components/select/Select.js create mode 100644 src/components/select/Select.scss create mode 100644 src/store/styles/variables.scss diff --git a/package.json b/package.json index 8263fc4..c4667ca 100755 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "author": "Mate Academy", "license": "GPL-3.0", "dependencies": { + "classnames": "^2.2.6", "node-sass": "^4.13.0", "prop-types": "^15.7.2", "react": "^16.8.6", diff --git a/public/images/app-store.png b/public/images/app-store.png new file mode 100644 index 0000000000000000000000000000000000000000..6c2ff057d7a82875e0cf1889073a0b8bb08f873d GIT binary patch literal 3656 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 aw*LaBZifUW!g}Wb0000 + + diff --git a/public/images/facebook.svg b/public/images/facebook.svg new file mode 100644 index 0000000..22565b3 --- /dev/null +++ b/public/images/facebook.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/footer-logo.svg b/public/images/footer-logo.svg new file mode 100644 index 0000000..c3894d1 --- /dev/null +++ b/public/images/footer-logo.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/images/google-play.png b/public/images/google-play.png new file mode 100644 index 0000000000000000000000000000000000000000..b988c6fc6c7bda6b791001fa65940fd525d51c4d GIT binary patch literal 4112 zcmV+r5by7aP)*Xi-3l2nZsA_~?Y*I|wR#PoKbtNEHzRqVnjVJf%xhKzav7P#z!=h_r;z z9xViE2}K}~UN)IG|G-^0eV0(f{(R@l?!D*MGiTiAIy#yhc(zfn zU_t8LyLYsQheutfJbCi;Tf26x!!R6B+`M^{e*5jWTw)}>odk8xojXSkIAGxP>C@!m z;!@K|$f&2;Y$gXBFc1?HgCr%l3q3`UI7r2d7pJhWFuHQ(if+rBH!lgx*3Tf(5fKr( z4J6CJUw{2Yl7W%4volE;B}@jK%K(mpJ4GJ=#}+MGRL^tq;zf#ziqh>k7U#Hg=Z=2Q zpFh8n_k@H5%9i-eMMdcI=pLFH)q4_AODO z1TS2;kl%XiE!`d*9IVGmmd1q(7uG&v06cf@T)oD+b?eyQ-=E)m?>)VT@#Dv{pP!$l z@ABo#xpL*okMvzUistU_&fkCkeUQz@kz;EZyC2%j9zjF7;E5qz(5DHzc(^~3n{Cyq z6(2crgv*sHXSsP}P`>^4TlV($PIb(rNt5{f_uo&p4aNaOFut!}zn&X3XppQ=pFVwf z9J?BnC3`+oW57p_*V+9P=fkHa{e$VS9_cv5V1 zD~gM$OVJ)CiW*dvJpS90JX%#Gle38)CR(>{O^X&SqBCdCP_bggNDPDI0jN}|Qo6ro z%a$aDK<(PKQ@5WLh_TSuUw^IP2{>`$1c?z*?b@~V`?P7(s9U#gdLP*xHggWfI~N;> zk8DZKF0N!Mu$#im2o6KW;DQ5c_;>3p|p2f$<>)$F>s!*FYZAiQbL9hc~ z5M`G_Cle}o}75K_qmJmccxGVU2DTm|nTS(BIVwS%b8ZaLH6Ggh2C<-8P4PO}0i zX4PRz49mLuikbTI%P*_E3qElC_;DSi7hZTlQ%nE@1zrLm6~*8iX(x~~XHF_qs1OOM z)bBVJMwQZtkQ(D!_!}A;N*69%&~u~zty{OqP?N!Vu;1F?vID^9X3d&)_WnGF0d^(2 z-uUikD+6Kq7hOCjxs0k!Ih&WJq`CeS>wA`xV(;JOV{lHMJeg|y<;$1T?2kc935Yv} zVPteH247O#Os{qR{CUdGu%B~SHzld}4CH1lv5MrjW_EX?sD?$!Ji8@%PHav^OXnfe z!%b`)c!0>7aafU5y53x*NbghzqKUJoGxcs8K}VNJDmW}374veXtO8^aA;Mbebl|}v zYhlG2LQ?6*y%1CQ?-1k4Nz~_7AdR@Om-4tI(10!`YEwTKO9!BMh7I9? zL5(@W&z1QPspagK79i~~aqJ-%_Fd}1HLB#WNwtG~{qDQ(vJgTBBpXq+QfealU0#;T z=FdI%++$G{C415Pz+Zch{qxU1IW6GXKKbMm7B8tvF0f|J8kUObLwy#z71F!mgOc+N z=QKW(c#ta{B*ZkJf!F+L>ZKi&Coy$OnZwOY_1}n~9g9trKVRmmCbW$O3l`{#r7ynt zf~3BoML5j38Z~NYS_y#)Y3$RAUcGuz!-fsD4IDTSl~Iy1fU3Wb1Ga}1!!VMp{$d-( zHIY(sPCRla`qCkUv{(z zme0v0=@^k!_DHt)=@g>yh>R}{!3m0`xVmJ9VU6^R0@C_RFTJF4JA^Utf$P_=Cx0~2 zP@s!IP!pG}aUB9!O6>>UN(ynRt3YRgmjWS9&s#y0fnI{+&YnH1a=$&A2#g-U(twn} zM3HKZJJa*(lj;Pa`6KXW$#F|YxscvKDq2-u&IxFW$kQTU-_+RabbLY%F{>k97JhaB! zX3d%<+lN^E{PWMJYBDHylO#`1Ezt`}wZw7JD!6CQo|bdq+57kJuiFiTg@v(*KrA84 z!gpl$vdHzyZ45rJd-rbb+p%NERGdRXgO>e8sMGCYXj&=8k^oAFb6A)E!7CM7hm$x#~GuyOU`8DiM%EZM!T~P4EmLI5;@j zzUtMhYsEArFzexp#qdd9qRv|M!wh@#%{NKP{5pG(;UJ!W_0?DERZyS7b{zBJhac)T zA%yhWYp>Dd$&*#K-?V9ydJSYt$WY+1QdWXXmMls0=g-$#(AKS6Nr*Cu0ny;WgLP() z8#hkFVM>URQbWz3>nX+8EkPB?aF6Qj!=4P2$QUFV~Ps-@JSjT8s+=DCzUI1POfY&iH7w`~=g!GI2RspgannJsdw+*EX6_=#a0(N!F&Ar>#uqa zLo)4`~4 zN=#$6WCp}&8Az>TV7B`C`C0b)`}-@iHvn#dS&DiII0gXS0pInmkUeeKut5uX@JKjb490Rl zDS@IPyb^%rhbR{qOBAgEzR|XATbeLof`wn;{NPuR_`x$IoT~29wQE;>Pw0 zA&K`o@SMQ}5e{R?Rx(1_vSoGA5$^rtk3ZI9FfqoA8Dr@K0S(IxU=(}y?9tHp`|rQo zCD7Tfa{yL#5%+|68nJvS^^uwBDleB|5@H=!C0p^ibc*Vo+)K-DhGy9?0K8Zj2&$rZ zKzI=Afs(L6qehLQ&p!K1XXQ8Fd}CSbfmK_^iZKi_xQMu2^%lr{khx%GnYXvM<$Rd= zNSQGU0|Ej_h@~zzh7KViSo^@^2(e4^e&M}f1h@xy7U(kYe#p8oNLj_JufD20?5Cf8 zqN!7-YT65~f_pT8Y($8u@{$=dX5itTo0!6@zG>|07)O1*~5nq*MWieSi5$uzHFqN*oMJGn1HMA)2ELTP>@8tJdiYr zze-4vT6XBrL1!G?J5oQ)YAg!`iNhKWEC&D)gdw62Ts!)J++mg?mBqDTptx>YDKxI- zk)wR$wI@T-=RZ?D(SKY2qp*^ z(oO6Bq7S4>Wrc6>2OoT(gp%&1vJ&f)rLv-1Xew(h#W!lyNJ*@b%0k9Rs%j8Yq>V@u zu}U8OMYYw{@YruaW;lx{N%dUf#q?OwEYf{;$&9qmk|j%&q~m(x_4K@Ape$iTSLfqg zk}X*XINl2&imT1<+3wZnbm^{f{CmU#4k_P}Lo0OP?WG%X{XAamL=V>}(rWm*0Wt}3 zv6g{OuR&W7cg`Y6rCXPPW`ZmQ=acj~)qa_kIw+FP>LB8?cpNpnl=_Qx!_OFSpOQ*G z@OOZ5!~J4aeOmjGwZMRc7;~{=#U7$@9J$WJM=s%uERZDo|M+S zd2{tFqK9Z|Y79Ek;Hy`!+V$ceWg9kZn0h*q-dQ-B&BxiD%2w*pm11;n9A@=Ro(0c$OFPrBAq1X_cNqs2OI$KTOCQk z_dAJpKTC4>IFKs`96-nv5img%*1682qFok=*(@buZ;7EU_z{rfKXZAufKmjcca#xC zfsT3Eg@bp5&!7x#v1Fiq7$^Qc=jfVw6CZr(% O0000 + + + + diff --git a/public/images/twitter.svg b/public/images/twitter.svg new file mode 100644 index 0000000..9c8b7bd --- /dev/null +++ b/public/images/twitter.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/world.svg b/public/images/world.svg new file mode 100644 index 0000000..953d851 --- /dev/null +++ b/public/images/world.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/images/x.svg b/public/images/x.svg new file mode 100644 index 0000000..c784d0c --- /dev/null +++ b/public/images/x.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/App.css b/src/App.css index 8b13789..46ebe73 100644 --- a/src/App.css +++ b/src/App.css @@ -1 +1,5 @@ - +.page { + /* min-height: 100vh; */ + padding-top: 32px; + margin-bottom: 82px; +} diff --git a/src/App.js b/src/App.js index 9aeb1e9..a2d8750 100644 --- a/src/App.js +++ b/src/App.js @@ -3,16 +3,18 @@ import './App.css'; import RestaurantsListPage from './components/restaurantsListPage/RestaurantsListPage'; import Header from './components/Header/Header'; +import Footer from './components/footer/Footer'; const App = () => ( - -
+ <>
-
- -
-
-
+
+
+ +
+
+