├── .gitignore ├── Gemfile ├── Gemfile.lock ├── README.md ├── README.rdoc ├── Rakefile ├── app ├── assets │ ├── cuisine.txt │ ├── descriptions.txt │ ├── hours.txt │ ├── images │ │ ├── .keep │ │ ├── boston.jpg │ │ ├── bread-food-plate-toast.jpg │ │ ├── bread-food-restaurant-people.jpg │ │ ├── burger-cheese-food-hamburger.jpg │ │ ├── chicago.jpg │ │ ├── city-restaurant-lunch-outside.jpg │ │ ├── city-restaurant-table-pavement.jpg │ │ ├── coffee-coffee-beans-afternoon-tea-40828.jpeg │ │ ├── coffee-cup-espresso-colorful.jpg │ │ ├── dinner-meal-table-wine.jpg │ │ ├── dinner-table-restaurant-dining-place-setting-51310.jpeg │ │ ├── eating-breakfast-food-dish.jpg │ │ ├── food-dinner-lemon-rice.jpg │ │ ├── food-dinner-steak-fork.jpg │ │ ├── food-healthy-hand-cooking.jpg │ │ ├── food-healthy-soup-leek.jpg │ │ ├── food-plate-restaurant-eating.jpg │ │ ├── food-plate-rucola-salad.jpg │ │ ├── food-plate-toast-restaurant.jpg │ │ ├── food-plate-wood-restaurant.jpg │ │ ├── food-prawn-asian.jpg │ │ ├── food-restaurant-camera-taking-photo.jpg │ │ ├── food-restaurant-eat-snack.jpg │ │ ├── food-restaurant-fruits-orange.jpg │ │ ├── food-restaurant-kitchen-meat-23086.jpg │ │ ├── food-salad-healthy-colorful.jpg │ │ ├── food-salad-healthy-lunch.jpg │ │ ├── food-salad-restaurant-person.jpg │ │ ├── food-vegetables-italian-restaurant.jpg │ │ ├── food.jpg │ │ ├── houston.jpg │ │ ├── italian-pizza-restaurant-italy.jpg │ │ ├── la.jpg │ │ ├── lifestyle-atmosphere-drink-eat-73399.jpeg │ │ ├── menu-restaurant-vintage-table.jpg │ │ ├── miami.jpg │ │ ├── mineral-water-lime-ice-mint-158821.jpeg │ │ ├── new-zealand-lake-mountain-landscape-37650.jpeg │ │ ├── night-76241.jpeg │ │ ├── nyc.jpg │ │ ├── pexels-photo (1).jpg │ │ ├── pexels-photo (2).jpg │ │ ├── pexels-photo (3).jpg │ │ ├── pexels-photo (4).jpg │ │ ├── pexels-photo (5).jpg │ │ ├── pexels-photo (6).jpg │ │ ├── pexels-photo (7).jpg │ │ ├── pexels-photo (8).jpg │ │ ├── pexels-photo-104884.jpeg │ │ ├── pexels-photo-104985.jpeg │ │ ├── pexels-photo-105066.jpeg │ │ ├── pexels-photo-106185.jpeg │ │ ├── pexels-photo-107527.jpeg │ │ ├── pexels-photo-109117.jpeg │ │ ├── pexels-photo-110435.jpeg │ │ ├── pexels-photo-110813.jpeg │ │ ├── pexels-photo-117514.jpeg │ │ ├── pexels-photo-119657.jpeg │ │ ├── pexels-photo-128641.jpeg │ │ ├── pexels-photo-128949.jpeg │ │ ├── pexels-photo-131925.jpeg │ │ ├── pexels-photo-134552.jpeg │ │ ├── pexels-photo-134686.jpeg │ │ ├── pexels-photo-136139.jpeg │ │ ├── pexels-photo-144432.jpeg │ │ ├── pexels-photo-169391.jpeg │ │ ├── pexels-photo-169628.jpeg │ │ ├── pexels-photo-177676.jpeg │ │ ├── pexels-photo-179130.jpeg │ │ ├── pexels-photo-185380.jpeg │ │ ├── pexels-photo-185383.jpeg │ │ ├── pexels-photo-185768.jpeg │ │ ├── pexels-photo-189188.jpeg │ │ ├── pexels-photo-191627.jpeg │ │ ├── pexels-photo-192527.jpeg │ │ ├── pexels-photo-192933.jpeg │ │ ├── pexels-photo-196299.jpeg │ │ ├── pexels-photo-196519.jpeg │ │ ├── pexels-photo-197973.jpeg │ │ ├── pexels-photo-198057.jpeg │ │ ├── pexels-photo-200401.jpeg │ │ ├── pexels-photo-201314.jpeg │ │ ├── pexels-photo-203213.jpeg │ │ ├── pexels-photo-205961.jpeg │ │ ├── pexels-photo-210557.jpeg │ │ ├── pexels-photo-213661.jpeg │ │ ├── pexels-photo-213939.jpeg │ │ ├── pexels-photo-218844.jpeg │ │ ├── pexels-photo-221143.jpeg │ │ ├── pexels-photo-225228.jpeg │ │ ├── pexels-photo-225236.jpeg │ │ ├── pexels-photo-225448.jpeg │ │ ├── pexels-photo-229493.jpeg │ │ ├── pexels-photo-230736.jpeg │ │ ├── pexels-photo-236887.jpeg │ │ ├── pexels-photo-237718.jpeg │ │ ├── pexels-photo-238306.jpeg │ │ ├── pexels-photo-239975.jpeg │ │ ├── pexels-photo-241556.jpeg │ │ ├── pexels-photo-24330.jpg │ │ ├── pexels-photo-24859.jpg │ │ ├── pexels-photo-251288.jpeg │ │ ├── pexels-photo-251599.jpeg │ │ ├── pexels-photo-257248.jpeg │ │ ├── pexels-photo-260771.jpeg │ │ ├── pexels-photo-260922.jpeg │ │ ├── pexels-photo-262918.jpeg │ │ ├── pexels-photo-262945.jpeg │ │ ├── pexels-photo-262946.jpeg │ │ ├── pexels-photo-262982.jpeg │ │ ├── pexels-photo-265903.jpeg │ │ ├── pexels-photo-265920.jpeg │ │ ├── pexels-photo-266174.jpeg │ │ ├── pexels-photo-26646.jpg │ │ ├── pexels-photo-26906.jpg │ │ ├── pexels-photo-269126.jpeg │ │ ├── pexels-photo-26981.jpg │ │ ├── pexels-photo-271475.jpeg │ │ ├── pexels-photo-273765.jpeg │ │ ├── pexels-photo-273920.jpeg │ │ ├── pexels-photo-27445.jpg │ │ ├── pexels-photo-27642.jpg │ │ ├── pexels-photo-276720.jpeg │ │ ├── pexels-photo-279260.jpeg │ │ ├── pexels-photo-279768.jpeg │ │ ├── pexels-photo-279813.jpeg │ │ ├── pexels-photo-279835.jpeg │ │ ├── pexels-photo-280121.jpeg │ │ ├── pexels-photo-286553.jpeg │ │ ├── pexels-photo-287975.jpeg │ │ ├── pexels-photo-290345.jpeg │ │ ├── pexels-photo-29346.jpg │ │ ├── pexels-photo-29612.jpg │ │ ├── pexels-photo-29613.jpg │ │ ├── pexels-photo-29682.jpg │ │ ├── pexels-photo-296888.jpeg │ │ ├── pexels-photo-297756.jpeg │ │ ├── pexels-photo-299347.jpeg │ │ ├── pexels-photo-299348.jpeg │ │ ├── pexels-photo-299351.jpeg │ │ ├── pexels-photo-299458.jpeg │ │ ├── pexels-photo-299550.jpeg │ │ ├── pexels-photo-300256.jpeg │ │ ├── pexels-photo-30227.jpg │ │ ├── pexels-photo-302746.jpeg │ │ ├── pexels-photo-302901.jpeg │ │ ├── pexels-photo-302902.jpeg │ │ ├── pexels-photo-30503.jpg │ │ ├── pexels-photo-305832.jpeg │ │ ├── pexels-photo-305972.jpeg │ │ ├── pexels-photo-306059.jpeg │ │ ├── pexels-photo-30868.jpg │ │ ├── pexels-photo-313700.jpeg │ │ ├── pexels-photo-316909.jpeg │ │ ├── pexels-photo-323910.jpeg │ │ ├── pexels-photo-331107.jpeg │ │ ├── pexels-photo-332784.jpeg │ │ ├── pexels-photo-336872.jpeg │ │ ├── pexels-photo-336930.jpeg │ │ ├── pexels-photo-338624.jpeg │ │ ├── pexels-photo-340996.jpeg │ │ ├── pexels-photo-341044.jpg │ │ ├── pexels-photo-341045.jpg │ │ ├── pexels-photo-341048.jpg │ │ ├── pexels-photo-343870.jpeg │ │ ├── pexels-photo-348517.jpeg │ │ ├── pexels-photo-357809.jpeg │ │ ├── pexels-photo-365459.jpeg │ │ ├── pexels-photo-38083.jpeg │ │ ├── pexels-photo-38106.jpeg │ │ ├── pexels-photo-388240.jpeg │ │ ├── pexels-photo-390658.jpeg │ │ ├── pexels-photo-52065.jpeg │ │ ├── pexels-photo-54296.jpeg │ │ ├── pexels-photo-55588.jpeg │ │ ├── pexels-photo-58801.jpeg │ │ ├── pexels-photo-59782.jpeg │ │ ├── pexels-photo-59943.jpeg │ │ ├── pexels-photo-60166.jpeg │ │ ├── pexels-photo-60257.jpeg │ │ ├── pexels-photo-60258.jpeg │ │ ├── pexels-photo-62097.jpeg │ │ ├── pexels-photo-64208.jpeg │ │ ├── pexels-photo-65123.jpeg │ │ ├── pexels-photo-66636.jpeg │ │ ├── pexels-photo-66637.jpeg │ │ ├── pexels-photo-66640.jpeg │ │ ├── pexels-photo-67468.jpeg │ │ ├── pexels-photo-68563.jpeg │ │ ├── pexels-photo-69482.jpeg │ │ ├── pexels-photo-69898.jpeg │ │ ├── pexels-photo-8298.jpg │ │ ├── pexels-photo-87224.jpeg │ │ ├── pexels-photo-90736.jpeg │ │ ├── pexels-photo-92090.jpeg │ │ ├── pexels-photo-92945.jpeg │ │ ├── pexels-photo-96619.jpeg │ │ ├── pexels-photo-99590.jpeg │ │ ├── pexels-photo.jpg │ │ ├── pizza-pizza-service-italian-eat-56014.jpeg │ │ ├── plate-white-fish-chilli.jpg │ │ ├── red-couple-night-romantic.jpg │ │ ├── red-lunch-green-knolling.jpg │ │ ├── restaurant-alcohol-bar-drinks.jpg │ │ ├── restaurant-building-urban-architecture-78086.jpeg │ │ ├── restaurant-coffee-chocolate-dessert.jpg │ │ ├── restaurant-coffee-cup-cappuccino (1).jpg │ │ ├── restaurant-coffee-cup-cappuccino.jpg │ │ ├── restaurant-coffee-cup-table.jpg │ │ ├── restaurant-drink-colorful-colourful.jpg │ │ ├── restaurant-glass-wine-glasses.jpg │ │ ├── restaurant-lighting-lobster-neon.jpg │ │ ├── restaurant-people-alcohol-bar.jpg │ │ ├── restaurant-people-feet-legs.jpg │ │ ├── restaurant-person-people-hand.jpg │ │ ├── restaurant-red-beans-coffee.jpg │ │ ├── restaurant-sidewalk-boardwalk-cafe.jpg │ │ ├── restaurant-street-bricks-house.jpg │ │ ├── restaurant-village-germany-chairs.jpg │ │ ├── restaurant-wine-glasses-served-51115.jpeg │ │ ├── restaurant.jpg │ │ ├── salad-healthy-diet-spinach.jpg │ │ ├── seattle.jpg │ │ ├── snow-restaurant-mountains-sky.jpg │ │ ├── spl1.jpg │ │ ├── spl2.jpg │ │ ├── spl3.jpg │ │ ├── table-covered-glass-cutlery-128875.jpeg │ │ ├── vegetables-italian-pizza-restaurant (1).jpg │ │ ├── vegetables-italian-pizza-restaurant.jpg │ │ ├── water-drink-glass-drinking.jpg │ │ └── wine.png │ ├── javascripts │ │ ├── api │ │ │ ├── cities.coffee │ │ │ ├── favorites.coffee │ │ │ ├── hours.coffee │ │ │ ├── reservations.coffee │ │ │ ├── restaurant.coffee │ │ │ ├── restaurants.coffee │ │ │ ├── reviews.coffee │ │ │ ├── seatings.coffee │ │ │ ├── sessions.coffee │ │ │ └── users.coffee │ │ ├── application.js │ │ ├── static_pages.coffee │ │ └── staticpages.coffee │ ├── reviews.txt │ └── stylesheets │ │ ├── _create.css │ │ ├── _css_reset.css │ │ ├── _form.css │ │ ├── _map.css │ │ ├── _navbar.css │ │ ├── api │ │ ├── _city.css │ │ ├── _review-form.css │ │ ├── _review_snippet.css │ │ ├── _snippet.css │ │ ├── cities.scss │ │ ├── favorite.css │ │ ├── favorites.scss │ │ ├── filter.css │ │ ├── hours.scss │ │ ├── manager.css │ │ ├── modal.css │ │ ├── photos-section.css │ │ ├── reservations.scss │ │ ├── restaurants.scss │ │ ├── reviews.scss │ │ ├── search-bar.css │ │ ├── seatings.scss │ │ ├── sessions.scss │ │ └── users.scss │ │ ├── application.css │ │ ├── footer.css │ │ ├── spinner.css │ │ ├── static_pages.scss │ │ └── staticpages.scss ├── controllers │ ├── api │ │ ├── cities_controller.rb │ │ ├── favorites_controller.rb │ │ ├── hours_controller.rb │ │ ├── manager_controller.rb │ │ ├── reservations_controller.rb │ │ ├── restaurants_controller.rb │ │ ├── reviews_controller.rb │ │ ├── seatings_controller.rb │ │ ├── sessions_controller.rb │ │ └── users_controller.rb │ ├── application_controller.rb │ ├── concerns │ │ └── .keep │ └── static_pages_controller.rb ├── helpers │ ├── api │ │ ├── cities_helper.rb │ │ ├── favorites_helper.rb │ │ ├── hours_helper.rb │ │ ├── reservations_helper.rb │ │ ├── restaurant_helper.rb │ │ ├── restaurants_helper.rb │ │ ├── reviews_helper.rb │ │ ├── seatings_helper.rb │ │ ├── sessions_helper.rb │ │ └── users_helper.rb │ ├── application_helper.rb │ ├── static_pages_helper.rb │ └── staticpages_helper.rb ├── mailers │ └── .keep ├── models │ ├── .keep │ ├── city.rb │ ├── concerns │ │ └── .keep │ ├── favorite.rb │ ├── hour.rb │ ├── photo.rb │ ├── rating.rb │ ├── reservation.rb │ ├── restaurant.rb │ ├── review.rb │ ├── seating.rb │ └── user.rb └── views │ ├── api │ ├── cities │ │ ├── index.json.jbuilder │ │ └── show.json.jbuilder │ ├── favorites │ │ ├── _show.json.jbuilder │ │ └── show.json.jbuilder │ ├── hours │ │ └── show.json.jbuilder │ ├── manager │ │ └── show.json.jbuilder │ ├── reservations │ │ ├── _show.json.jbuilder │ │ ├── index.json.jbuilder │ │ ├── search.json.jbuilder │ │ └── show.json.jbuilder │ ├── restaurants │ │ ├── _show.json.jbuilder │ │ ├── index.json.jbuilder │ │ ├── search.json.jbuilder │ │ ├── show.json.jbuilder │ │ └── update.json.jbuilder │ ├── reviews │ │ ├── index.json.jbuilder │ │ └── show.json.jbuilder │ ├── seatings │ │ ├── search.json.jbuilder │ │ └── show.json.jbuilder │ ├── sessions │ │ ├── _show.json.jbuilder │ │ └── show.json.jbuilder │ └── users │ │ └── show.json.jbuilder │ ├── layouts │ └── application.html.erb │ └── static_pages │ └── root.html.erb ├── bin ├── bundle ├── rails ├── rake ├── setup └── spring ├── config.ru ├── config ├── application.rb ├── boot.rb ├── database.yml ├── environment.rb ├── environments │ ├── development.rb │ ├── production.rb │ └── test.rb ├── initializers │ ├── assets.rb │ ├── backtrace_silencers.rb │ ├── cookies_serializer.rb │ ├── filter_parameter_logging.rb │ ├── inflections.rb │ ├── mime_types.rb │ ├── session_store.rb │ └── wrap_parameters.rb ├── locales │ └── en.yml ├── routes.rb └── secrets.yml ├── db ├── migrate │ ├── 20170418154103_create_users.rb │ ├── 20170420183553_create_restaurants.rb │ ├── 20170421172213_change_restaurant_description.rb │ ├── 20170421204517_change_restaurant_locations.rb │ ├── 20170422015529_create_cities.rb │ ├── 20170422155415_add_attachment_main_to_cities.rb │ ├── 20170422162826_remove_main_photo.rb │ ├── 20170423004640_create_photos.rb │ ├── 20170423004952_add_attachment_image_to_photos.rb │ ├── 20170423160955_add_zip_code.rb │ ├── 20170423185958_add_state_to_city.rb │ ├── 20170424150724_add_city_key_to_restaurants.rb │ ├── 20170424160012_change_city_name.rb │ ├── 20170428131133_create_reservations.rb │ ├── 20170428134339_change_seats_column.rb │ ├── 20170501225025_create_reviews.rb │ ├── 20170514222808_create_ratings.rb │ ├── 20170514223610_add_total_to_rating.rb │ ├── 20170517141246_fix_null_constraint_for_restaurant.rb │ ├── 20170517223455_create_favorites.rb │ ├── 20170911205416_add_location_to_city.rb │ ├── 20170925192045_refactor_city_name.rb │ ├── 20170925212533_rename_restaurant_columns.rb │ ├── 20170926192135_change_cities_latlng.rb │ ├── 20171031220719_create_hours.rb │ ├── 20171031221001_create_seatings.rb │ ├── 20171031221811_remove_hours_from_restaurant.rb │ ├── 20171031224113_change_seats_to_seatings_foreign_key.rb │ └── 20171202001715_add_seats_to_reservations.rb ├── schema.rb └── seeds.rb ├── docs ├── README.md ├── Wireframes │ ├── Available-reservations.png │ ├── Create-account-form.png │ ├── Favorites.png │ ├── Featured-location.png │ ├── Home.png │ ├── Navbar.png │ ├── Recommendations.png │ ├── Reservation-bar.png │ ├── Restaurant-view.png │ ├── Reviews.png │ ├── Sign-in-form.png │ └── User-reservations.png ├── api-endpoints.md ├── react-components.md ├── sample-state.md └── schema.md ├── frontend ├── actions │ ├── city_actions.js │ ├── favorites_actions.js │ ├── hours_actions.js │ ├── manager_actions.js │ ├── map_actions.js │ ├── modal_actions.js │ ├── reservations_actions.js │ ├── restaurant_actions.js │ ├── review_actions.js │ ├── search_actions.js │ ├── seating_actions.js │ ├── session_actions.js │ └── user_actions.js ├── components │ ├── app.jsx │ ├── city │ │ ├── city_index.jsx │ │ └── city_show.jsx │ ├── favorite │ │ └── favorite_box.jsx │ ├── manager │ │ ├── add_table.jsx │ │ ├── field.jsx │ │ ├── manager.jsx │ │ ├── manager_details.jsx │ │ ├── manager_hours.jsx │ │ ├── manager_li.jsx │ │ ├── manager_reservations.jsx │ │ ├── manager_reviews.jsx │ │ ├── manager_seats.jsx │ │ └── manager_side_bar.jsx │ ├── modal.jsx │ ├── navbar.jsx │ ├── restaurant │ │ ├── create_splash.jsx │ │ ├── photo_section.jsx │ │ ├── reservations.jsx │ │ ├── restaurant_create.jsx │ │ ├── restaurant_map.jsx │ │ ├── restaurant_show.jsx │ │ └── restaurant_snippet.jsx │ ├── review │ │ ├── review_form.jsx │ │ ├── review_snippet.jsx │ │ └── thank_you.jsx │ ├── root.jsx │ ├── search │ │ ├── date_bar.jsx │ │ ├── search_bar.jsx │ │ ├── search_box.jsx │ │ ├── seat_bar.jsx │ │ └── time_bar.jsx │ ├── session │ │ ├── session_form.jsx │ │ └── session_form_container.js │ └── user │ │ └── user_show.jsx ├── reducers │ ├── cities_reducer.js │ ├── favorites_reducer.js │ ├── hours_reducer.js │ ├── manager_reducer.js │ ├── modal_reducer.js │ ├── reservations_reducer.js │ ├── restaurants_reducer.js │ ├── reviews_reducer.js │ ├── root_reducer.js │ ├── search_reducer.js │ ├── seatings_reducer.js │ ├── session_reducer.js │ └── users_reducer.js ├── root.jsx ├── selectors │ ├── date_selectors.js │ ├── favorites_selector.js │ ├── manager_selectors.js │ ├── reservations_selectors.js │ ├── review_selectors.js │ ├── search_selector.js │ └── seatings_selectors.js ├── store │ └── store.js └── util │ ├── city_api_util.js │ ├── date_util.js │ ├── favorites_util.js │ ├── hours_api_util.js │ ├── manager_api_util.js │ ├── manager_util.jsx │ ├── map_util.js │ ├── reservations_api_util.js │ ├── restaurant_api_util.js │ ├── review_api_util.js │ ├── search_api_util.js │ ├── search_util.jsx │ ├── seatings_api_util.js │ ├── session_api_util.js │ └── user_api_util.js ├── lib ├── assets │ └── .keep └── tasks │ └── .keep ├── log └── .keep ├── package.json ├── public ├── 404.html ├── 422.html ├── 500.html ├── favicon.ico ├── images │ ├── hello-table-full.png │ ├── logo-3.png │ ├── red-wine.png │ ├── restaurant-show.png │ ├── spl1.jpg │ ├── spl2.jpg │ ├── spl3.jpg │ └── user-show.png └── robots.txt ├── test ├── controllers │ ├── .keep │ ├── api │ │ ├── cities_controller_test.rb │ │ ├── favorites_controller_test.rb │ │ ├── hours_controller_test.rb │ │ ├── reservations_controller_test.rb │ │ ├── restaurant_controller_test.rb │ │ ├── restaurants_controller_test.rb │ │ ├── reviews_controller_test.rb │ │ ├── seatings_controller_test.rb │ │ ├── sessions_controller_test.rb │ │ └── users_controller_test.rb │ ├── static_pages_controller_test.rb │ └── staticpages_controller_test.rb ├── fixtures │ ├── .keep │ ├── cities.yml │ ├── favorites.yml │ ├── hours.yml │ ├── photos.yml │ ├── ratings.yml │ ├── reservations.yml │ ├── restaurants.yml │ ├── reviews.yml │ ├── seatings.yml │ └── users.yml ├── helpers │ └── .keep ├── integration │ └── .keep ├── mailers │ └── .keep ├── models │ ├── .keep │ ├── city_test.rb │ ├── favorite_test.rb │ ├── hour_test.rb │ ├── photo_test.rb │ ├── rating_test.rb │ ├── reservation_test.rb │ ├── restaurant_test.rb │ ├── review_test.rb │ ├── seating_test.rb │ └── user_test.rb └── test_helper.rb ├── vendor └── assets │ ├── javascripts │ └── .keep │ └── stylesheets │ └── .keep └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile '~/.gitignore_global' 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore all logfiles and tempfiles. 11 | /log/* 12 | !/log/.keep 13 | /tmp 14 | node_modules/ 15 | bundle.js 16 | bundle.js.map 17 | .byebug_history 18 | .DS_Store 19 | npm-debug.log 20 | 21 | # Ignore application configuration 22 | /config/application.yml 23 | -------------------------------------------------------------------------------- /README.rdoc: -------------------------------------------------------------------------------- 1 | == README 2 | 3 | This README would normally document whatever steps are necessary to get the 4 | application up and running. 5 | 6 | Things you may want to cover: 7 | 8 | * Ruby version 9 | 10 | * System dependencies 11 | 12 | * Configuration 13 | 14 | * Database creation 15 | 16 | * Database initialization 17 | 18 | * How to run the test suite 19 | 20 | * Services (job queues, cache servers, search engines, etc.) 21 | 22 | * Deployment instructions 23 | 24 | * ... 25 | 26 | 27 | Please feel free to use a different markup language if you do not plan to run 28 | rake doc:app. 29 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require File.expand_path('../config/application', __FILE__) 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /app/assets/cuisine.txt: -------------------------------------------------------------------------------- 1 | Pizza 2 | Latin American 3 | Greek 4 | Bakery 5 | Modern American 6 | Kosher 7 | American 8 | Tapas 9 | Brazilian 10 | Sandwiches/Subs 11 | Mediterranean 12 | Diner 13 | Pakistani 14 | French 15 | Salads 16 | Donuts 17 | Vietnamese 18 | Japanese 19 | Seafood 20 | Tex-Mex 21 | Desserts/Ice Cream 22 | Cuban 23 | Tacos 24 | Soups 25 | Middle Eastern 26 | Mexican 27 | Steakhouse 28 | Indian 29 | English/Irish 30 | Buffet 31 | Hot Dogs/Sausages 32 | Dim Sum 33 | Chicken 34 | European 35 | Eastern European 36 | Asian 37 | Chinese 38 | Pub Food 39 | Organic 40 | Coffee 41 | Burgers 42 | Wine Bar 43 | Peruvian 44 | Sushi 45 | Tea 46 | Thai 47 | Spanish 48 | Vegetarian 49 | Bagels 50 | Smoothies 51 | Fast Food 52 | Noodle Shop 53 | Southern/Soul 54 | Italian 55 | Barbecue 56 | Delicatessen 57 | International 58 | Caribbean 59 | Breakfast/Brunch 60 | Turkish 61 | African 62 | Korean 63 | Gastropub 64 | German 65 | -------------------------------------------------------------------------------- /app/assets/hours.txt: -------------------------------------------------------------------------------- 1 | Mon Closed, Tue 11:30 am - 10:00 pm, Wed 11:30 am - 10:00 pm, Thu 11:30 am - 10:00 pm, Fri 11:30 am - 10:00 pm, Sat 11:30 am - 10:00 pm, Sun 11:30 am - 9:00 pm 2 | Mon 11:00 am - 10:30 pm, Tue 11:00 am - 10:30 pm, Wed 11:00 am - 10:30 pm, Thu 11:00 am - 10:30 pm, Fri 11:00 am - 11:30 pm, Sat 10:30 am - 11:30 pm, Sun 10:30 am - 10:00 pm 3 | Mon 5:30 pm - 10:30 pm, Tue Closed, Wed 5:30 pm - 10:30 pm, Thu 5:30 pm - 10:30 pm, Fri 5:30 pm - 10:30 pm, Sat 5:30 pm - 10:30 pm, Sun 11:00 am - 3:00 pm 4 | Mon 12:00 pm - 10:00 pm, Tue 12:00 pm - 10:00 pm, Wed 12:00 pm - 10:00 pm, Thu 12:00 pm - 10:00 pm, Fri 12:00 pm - 10:00 pm, Sat 12:00 pm - 10:00 pm, Sun 12:00 pm - 10:00 pm 5 | Mon Closed, Tue 4:00 pm - 12:00 am, Wed 4:00 pm - 12:00 am, Thu 4:00 pm - 12:00 am, Fri 4:00 pm - 1:00 am, Sat 2:00 pm - 1:00 am, Sun 11:00 am - 3:30 pm 6 | Mon 1:00 pm - 2:00 am, Tue 1:00 pm - 2:00 am, Wed 1:00 pm - 2:00 am, Thu 1:00 pm - 2:00 am, Fri 1:00 pm - 2:00 am, Sat 1:00 pm - 2:00 am, Sun 1:00 pm - 2:00 am 7 | -------------------------------------------------------------------------------- /app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/.keep -------------------------------------------------------------------------------- /app/assets/images/boston.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/boston.jpg -------------------------------------------------------------------------------- /app/assets/images/bread-food-plate-toast.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/bread-food-plate-toast.jpg -------------------------------------------------------------------------------- /app/assets/images/bread-food-restaurant-people.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/bread-food-restaurant-people.jpg -------------------------------------------------------------------------------- /app/assets/images/burger-cheese-food-hamburger.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/burger-cheese-food-hamburger.jpg -------------------------------------------------------------------------------- /app/assets/images/chicago.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/chicago.jpg -------------------------------------------------------------------------------- /app/assets/images/city-restaurant-lunch-outside.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/city-restaurant-lunch-outside.jpg -------------------------------------------------------------------------------- /app/assets/images/city-restaurant-table-pavement.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/city-restaurant-table-pavement.jpg -------------------------------------------------------------------------------- /app/assets/images/coffee-coffee-beans-afternoon-tea-40828.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/coffee-coffee-beans-afternoon-tea-40828.jpeg -------------------------------------------------------------------------------- /app/assets/images/coffee-cup-espresso-colorful.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/coffee-cup-espresso-colorful.jpg -------------------------------------------------------------------------------- /app/assets/images/dinner-meal-table-wine.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/dinner-meal-table-wine.jpg -------------------------------------------------------------------------------- /app/assets/images/dinner-table-restaurant-dining-place-setting-51310.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/dinner-table-restaurant-dining-place-setting-51310.jpeg -------------------------------------------------------------------------------- /app/assets/images/eating-breakfast-food-dish.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/eating-breakfast-food-dish.jpg -------------------------------------------------------------------------------- /app/assets/images/food-dinner-lemon-rice.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/food-dinner-lemon-rice.jpg -------------------------------------------------------------------------------- /app/assets/images/food-dinner-steak-fork.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/food-dinner-steak-fork.jpg -------------------------------------------------------------------------------- /app/assets/images/food-healthy-hand-cooking.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/food-healthy-hand-cooking.jpg -------------------------------------------------------------------------------- /app/assets/images/food-healthy-soup-leek.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/food-healthy-soup-leek.jpg -------------------------------------------------------------------------------- /app/assets/images/food-plate-restaurant-eating.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/food-plate-restaurant-eating.jpg -------------------------------------------------------------------------------- /app/assets/images/food-plate-rucola-salad.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/food-plate-rucola-salad.jpg -------------------------------------------------------------------------------- /app/assets/images/food-plate-toast-restaurant.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/food-plate-toast-restaurant.jpg -------------------------------------------------------------------------------- /app/assets/images/food-plate-wood-restaurant.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/food-plate-wood-restaurant.jpg -------------------------------------------------------------------------------- /app/assets/images/food-prawn-asian.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/food-prawn-asian.jpg -------------------------------------------------------------------------------- /app/assets/images/food-restaurant-camera-taking-photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/food-restaurant-camera-taking-photo.jpg -------------------------------------------------------------------------------- /app/assets/images/food-restaurant-eat-snack.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/food-restaurant-eat-snack.jpg -------------------------------------------------------------------------------- /app/assets/images/food-restaurant-fruits-orange.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/food-restaurant-fruits-orange.jpg -------------------------------------------------------------------------------- /app/assets/images/food-restaurant-kitchen-meat-23086.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/food-restaurant-kitchen-meat-23086.jpg -------------------------------------------------------------------------------- /app/assets/images/food-salad-healthy-colorful.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/food-salad-healthy-colorful.jpg -------------------------------------------------------------------------------- /app/assets/images/food-salad-healthy-lunch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/food-salad-healthy-lunch.jpg -------------------------------------------------------------------------------- /app/assets/images/food-salad-restaurant-person.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/food-salad-restaurant-person.jpg -------------------------------------------------------------------------------- /app/assets/images/food-vegetables-italian-restaurant.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/food-vegetables-italian-restaurant.jpg -------------------------------------------------------------------------------- /app/assets/images/food.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/food.jpg -------------------------------------------------------------------------------- /app/assets/images/houston.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/houston.jpg -------------------------------------------------------------------------------- /app/assets/images/italian-pizza-restaurant-italy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/italian-pizza-restaurant-italy.jpg -------------------------------------------------------------------------------- /app/assets/images/la.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/la.jpg -------------------------------------------------------------------------------- /app/assets/images/lifestyle-atmosphere-drink-eat-73399.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/lifestyle-atmosphere-drink-eat-73399.jpeg -------------------------------------------------------------------------------- /app/assets/images/menu-restaurant-vintage-table.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/menu-restaurant-vintage-table.jpg -------------------------------------------------------------------------------- /app/assets/images/miami.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/miami.jpg -------------------------------------------------------------------------------- /app/assets/images/mineral-water-lime-ice-mint-158821.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/mineral-water-lime-ice-mint-158821.jpeg -------------------------------------------------------------------------------- /app/assets/images/new-zealand-lake-mountain-landscape-37650.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/new-zealand-lake-mountain-landscape-37650.jpeg -------------------------------------------------------------------------------- /app/assets/images/night-76241.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/night-76241.jpeg -------------------------------------------------------------------------------- /app/assets/images/nyc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/nyc.jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo (1).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo (1).jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo (2).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo (2).jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo (3).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo (3).jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo (4).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo (4).jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo (5).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo (5).jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo (6).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo (6).jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo (7).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo (7).jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo (8).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo (8).jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-104884.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-104884.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-104985.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-104985.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-105066.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-105066.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-106185.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-106185.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-107527.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-107527.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-109117.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-109117.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-110435.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-110435.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-110813.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-110813.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-117514.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-117514.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-119657.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-119657.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-128641.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-128641.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-128949.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-128949.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-131925.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-131925.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-134552.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-134552.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-134686.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-134686.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-136139.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-136139.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-144432.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-144432.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-169391.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-169391.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-169628.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-169628.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-177676.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-177676.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-179130.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-179130.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-185380.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-185380.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-185383.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-185383.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-185768.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-185768.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-189188.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-189188.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-191627.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-191627.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-192527.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-192527.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-192933.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-192933.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-196299.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-196299.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-196519.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-196519.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-197973.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-197973.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-198057.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-198057.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-200401.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-200401.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-201314.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-201314.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-203213.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-203213.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-205961.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-205961.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-210557.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-210557.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-213661.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-213661.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-213939.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-213939.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-218844.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-218844.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-221143.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-221143.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-225228.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-225228.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-225236.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-225236.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-225448.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-225448.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-229493.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-229493.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-230736.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-230736.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-236887.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-236887.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-237718.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-237718.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-238306.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-238306.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-239975.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-239975.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-241556.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-241556.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-24330.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-24330.jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-24859.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-24859.jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-251288.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-251288.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-251599.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-251599.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-257248.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-257248.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-260771.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-260771.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-260922.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-260922.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-262918.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-262918.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-262945.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-262945.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-262946.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-262946.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-262982.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-262982.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-265903.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-265903.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-265920.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-265920.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-266174.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-266174.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-26646.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-26646.jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-26906.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-26906.jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-269126.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-269126.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-26981.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-26981.jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-271475.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-271475.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-273765.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-273765.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-273920.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-273920.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-27445.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-27445.jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-27642.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-27642.jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-276720.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-276720.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-279260.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-279260.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-279768.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-279768.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-279813.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-279813.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-279835.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-279835.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-280121.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-280121.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-286553.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-286553.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-287975.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-287975.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-290345.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-290345.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-29346.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-29346.jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-29612.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-29612.jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-29613.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-29613.jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-29682.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-29682.jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-296888.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-296888.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-297756.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-297756.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-299347.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-299347.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-299348.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-299348.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-299351.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-299351.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-299458.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-299458.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-299550.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-299550.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-300256.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-300256.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-30227.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-30227.jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-302746.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-302746.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-302901.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-302901.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-302902.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-302902.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-30503.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-30503.jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-305832.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-305832.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-305972.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-305972.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-306059.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-306059.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-30868.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-30868.jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-313700.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-313700.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-316909.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-316909.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-323910.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-323910.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-331107.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-331107.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-332784.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-332784.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-336872.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-336872.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-336930.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-336930.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-338624.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-338624.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-340996.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-340996.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-341044.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-341044.jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-341045.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-341045.jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-341048.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-341048.jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-343870.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-343870.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-348517.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-348517.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-357809.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-357809.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-365459.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-365459.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-38083.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-38083.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-38106.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-38106.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-388240.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-388240.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-390658.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-390658.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-52065.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-52065.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-54296.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-54296.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-55588.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-55588.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-58801.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-58801.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-59782.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-59782.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-59943.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-59943.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-60166.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-60166.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-60257.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-60257.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-60258.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-60258.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-62097.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-62097.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-64208.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-64208.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-65123.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-65123.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-66636.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-66636.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-66637.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-66637.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-66640.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-66640.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-67468.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-67468.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-68563.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-68563.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-69482.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-69482.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-69898.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-69898.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-8298.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-8298.jpg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-87224.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-87224.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-90736.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-90736.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-92090.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-92090.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-92945.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-92945.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-96619.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-96619.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo-99590.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo-99590.jpeg -------------------------------------------------------------------------------- /app/assets/images/pexels-photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pexels-photo.jpg -------------------------------------------------------------------------------- /app/assets/images/pizza-pizza-service-italian-eat-56014.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/pizza-pizza-service-italian-eat-56014.jpeg -------------------------------------------------------------------------------- /app/assets/images/plate-white-fish-chilli.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/plate-white-fish-chilli.jpg -------------------------------------------------------------------------------- /app/assets/images/red-couple-night-romantic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/red-couple-night-romantic.jpg -------------------------------------------------------------------------------- /app/assets/images/red-lunch-green-knolling.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/red-lunch-green-knolling.jpg -------------------------------------------------------------------------------- /app/assets/images/restaurant-alcohol-bar-drinks.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/restaurant-alcohol-bar-drinks.jpg -------------------------------------------------------------------------------- /app/assets/images/restaurant-building-urban-architecture-78086.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/restaurant-building-urban-architecture-78086.jpeg -------------------------------------------------------------------------------- /app/assets/images/restaurant-coffee-chocolate-dessert.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/restaurant-coffee-chocolate-dessert.jpg -------------------------------------------------------------------------------- /app/assets/images/restaurant-coffee-cup-cappuccino (1).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/restaurant-coffee-cup-cappuccino (1).jpg -------------------------------------------------------------------------------- /app/assets/images/restaurant-coffee-cup-cappuccino.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/restaurant-coffee-cup-cappuccino.jpg -------------------------------------------------------------------------------- /app/assets/images/restaurant-coffee-cup-table.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/restaurant-coffee-cup-table.jpg -------------------------------------------------------------------------------- /app/assets/images/restaurant-drink-colorful-colourful.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/restaurant-drink-colorful-colourful.jpg -------------------------------------------------------------------------------- /app/assets/images/restaurant-glass-wine-glasses.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/restaurant-glass-wine-glasses.jpg -------------------------------------------------------------------------------- /app/assets/images/restaurant-lighting-lobster-neon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/restaurant-lighting-lobster-neon.jpg -------------------------------------------------------------------------------- /app/assets/images/restaurant-people-alcohol-bar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/restaurant-people-alcohol-bar.jpg -------------------------------------------------------------------------------- /app/assets/images/restaurant-people-feet-legs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/restaurant-people-feet-legs.jpg -------------------------------------------------------------------------------- /app/assets/images/restaurant-person-people-hand.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/restaurant-person-people-hand.jpg -------------------------------------------------------------------------------- /app/assets/images/restaurant-red-beans-coffee.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/restaurant-red-beans-coffee.jpg -------------------------------------------------------------------------------- /app/assets/images/restaurant-sidewalk-boardwalk-cafe.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/restaurant-sidewalk-boardwalk-cafe.jpg -------------------------------------------------------------------------------- /app/assets/images/restaurant-street-bricks-house.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/restaurant-street-bricks-house.jpg -------------------------------------------------------------------------------- /app/assets/images/restaurant-village-germany-chairs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/restaurant-village-germany-chairs.jpg -------------------------------------------------------------------------------- /app/assets/images/restaurant-wine-glasses-served-51115.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/restaurant-wine-glasses-served-51115.jpeg -------------------------------------------------------------------------------- /app/assets/images/restaurant.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/restaurant.jpg -------------------------------------------------------------------------------- /app/assets/images/salad-healthy-diet-spinach.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/salad-healthy-diet-spinach.jpg -------------------------------------------------------------------------------- /app/assets/images/seattle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/seattle.jpg -------------------------------------------------------------------------------- /app/assets/images/snow-restaurant-mountains-sky.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/snow-restaurant-mountains-sky.jpg -------------------------------------------------------------------------------- /app/assets/images/spl1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/spl1.jpg -------------------------------------------------------------------------------- /app/assets/images/spl2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/spl2.jpg -------------------------------------------------------------------------------- /app/assets/images/spl3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/spl3.jpg -------------------------------------------------------------------------------- /app/assets/images/table-covered-glass-cutlery-128875.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/table-covered-glass-cutlery-128875.jpeg -------------------------------------------------------------------------------- /app/assets/images/vegetables-italian-pizza-restaurant (1).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/vegetables-italian-pizza-restaurant (1).jpg -------------------------------------------------------------------------------- /app/assets/images/vegetables-italian-pizza-restaurant.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/vegetables-italian-pizza-restaurant.jpg -------------------------------------------------------------------------------- /app/assets/images/water-drink-glass-drinking.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/water-drink-glass-drinking.jpg -------------------------------------------------------------------------------- /app/assets/images/wine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/assets/images/wine.png -------------------------------------------------------------------------------- /app/assets/javascripts/api/cities.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/api/favorites.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/api/hours.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/api/reservations.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/api/restaurant.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/api/restaurants.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/api/reviews.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/api/seatings.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/api/sessions.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/api/users.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 5 | // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // compiled file. 9 | // 10 | // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details 11 | // about supported directives. 12 | // 13 | //= require jquery 14 | //= require jquery_ujs 15 | //= require_tree . 16 | -------------------------------------------------------------------------------- /app/assets/javascripts/static_pages.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/staticpages.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/_css_reset.css: -------------------------------------------------------------------------------- 1 | body, main, div, section, a, input, li { 2 | margin: 0; 3 | padding: 0; 4 | border: 0; 5 | outline: 0; 6 | font: inherit; 7 | color: inherit; 8 | text-align: inherit; 9 | text-decoration: inherit; 10 | vertical-align: inherit; 11 | box-sizing: border-box; 12 | background: transparent; 13 | opacity: inherit; 14 | } 15 | 16 | main, section, div, footer { 17 | display: block; 18 | } 19 | 20 | ul { 21 | list-style: none; 22 | padding: 0; 23 | margin: 0; 24 | } 25 | 26 | a { 27 | text-decoration: none; 28 | } 29 | 30 | html { 31 | height: 100%; 32 | width: 100%; 33 | } 34 | 35 | body { 36 | background-color: whitesmoke; 37 | font-family: 'Open Sans', sans-serif; 38 | height: 100%; 39 | width: 100%; 40 | } 41 | 42 | #root { 43 | height: 100%; 44 | width: 100%; 45 | } 46 | 47 | .main-app { 48 | position: relative; 49 | height: 100%; 50 | width: 100%; 51 | } 52 | 53 | .group:after { 54 | content: ""; 55 | display: block; 56 | clear: both; 57 | } 58 | 59 | .errors { 60 | color: red; 61 | } 62 | 63 | #hidden { 64 | display: none; 65 | } 66 | -------------------------------------------------------------------------------- /app/assets/stylesheets/_map.css: -------------------------------------------------------------------------------- 1 | #map { 2 | max-width: 100%; 3 | height: 300px; 4 | } 5 | -------------------------------------------------------------------------------- /app/assets/stylesheets/api/_city.css: -------------------------------------------------------------------------------- 1 | .restaurants-index { 2 | display: flex; 3 | flex-direction: column; 4 | align-items: center; 5 | } 6 | 7 | .restaurants-index-splash { 8 | width: 100%; 9 | background-size: cover; 10 | height: 350px; 11 | background-image: url('/images/spl1.jpg'); 12 | background-position: center; 13 | display: flex; 14 | flex-direction: column; 15 | justify-content: flex-end; 16 | align-items: center; 17 | padding-bottom: 30px; 18 | } 19 | 20 | .restaurant-snippets { 21 | background: white; 22 | width: 80%; 23 | margin: 30px 0px; 24 | padding-bottom: 15px; 25 | border-bottom: 1px solid grey; 26 | border-radius: 7px; 27 | } 28 | 29 | .restaurants-index .search-bar { 30 | background: transparent; 31 | border:none; 32 | } 33 | 34 | .restaurants-index .seats-form { 35 | border: none; 36 | } 37 | 38 | .city-index-splash .search-bar { 39 | position: absolute; 40 | top: 70%; 41 | } 42 | 43 | .city-index-splash .restaurants-index-splash { 44 | position: relative; 45 | background-image: url('/images/spl3.jpg'); 46 | } 47 | -------------------------------------------------------------------------------- /app/assets/stylesheets/api/_review-form.css: -------------------------------------------------------------------------------- 1 | .review-form-container { 2 | position: absolute; 3 | z-index: 1; 4 | left: 30%; 5 | width: 40%; 6 | height: 40%; 7 | background: white; 8 | border-radius: 7px; 9 | border-bottom: 1px solid gainsboro; 10 | display: flex; 11 | flex-direction: column; 12 | justify-content: center; 13 | } 14 | 15 | .review-rating { 16 | flex: 5; 17 | display: flex; 18 | flex-direction: column; 19 | justify-content: center; 20 | } 21 | 22 | .overall-stars { 23 | display: flex; 24 | flex: 1; 25 | justify-content: flex-start; 26 | align-items: center; 27 | margin-left: 10px; 28 | font-size: 12px; 29 | color: gray; 30 | } 31 | 32 | .overall-stars h4 { 33 | vertical-align: middle; 34 | margin-right: 10px; 35 | } 36 | 37 | .rating-drop-section { 38 | flex: 1; 39 | display: flex; 40 | justify-content: space-between; 41 | margin: 5px; 42 | margin-left: 10px; 43 | } 44 | 45 | .rating-drop { 46 | display: inline-block; 47 | flex: 1; 48 | margin: 5px; 49 | } 50 | 51 | .review-form { 52 | display: flex; 53 | flex: 9; 54 | flex-direction: column; 55 | justify-content: center; 56 | } 57 | 58 | .review-details { 59 | align-self: center; 60 | height: 60%; 61 | width: 90%; 62 | resize: none; 63 | } 64 | 65 | .review-form .button { 66 | margin-top: 10px; 67 | } 68 | 69 | .thank-you-container { 70 | color: dimgray; 71 | justify-content: space-around; 72 | padding: 15px; 73 | } 74 | -------------------------------------------------------------------------------- /app/assets/stylesheets/api/_review_snippet.css: -------------------------------------------------------------------------------- 1 | .reviews-section { 2 | margin: 20px 0px; 3 | background: white; 4 | display: flex; 5 | flex-direction: column; 6 | border-radius: 7px; 7 | border-bottom: 1px solid lightgray; 8 | } 9 | 10 | .reviews-section .snippet-section { 11 | border: none; 12 | margin: 10px 0px; 13 | display: flex; 14 | } 15 | 16 | .review-snippet-main { 17 | flex: 8; 18 | display: flex; 19 | flex-direction: column; 20 | } 21 | 22 | .review-snippet-top-bar { 23 | flex: 1; 24 | } 25 | 26 | .review-snippet-top-bar ul { 27 | display: flex; 28 | justify-content: space-between; 29 | font-size: 12px; 30 | color: darkgray; 31 | } 32 | 33 | .review-details { 34 | flex: 6; 35 | font-size: 12px; 36 | color: gray; 37 | } 38 | 39 | .review-snippet-right-bar { 40 | flex: 2; 41 | margin-left: 10px; 42 | color: gray; 43 | font-size: 12px; 44 | font-weight: lighter; 45 | } 46 | 47 | .review-snippet-right-bar li{ 48 | margin: 3px 0px; 49 | } 50 | -------------------------------------------------------------------------------- /app/assets/stylesheets/api/_snippet.css: -------------------------------------------------------------------------------- 1 | .snippet-section { 2 | display: flex; 3 | border-bottom: 1px solid lightgrey; 4 | padding: 0px 10px 0px 10px; 5 | margin: 5px 0px; 6 | } 7 | 8 | .snippet-photo { 9 | max-height: 150px; 10 | flex: 3; 11 | margin: 15px 10px; 12 | } 13 | 14 | .snippet-img { 15 | width: 100%; 16 | height: 100%; 17 | border-radius: 5px; 18 | } 19 | 20 | .snippet-img img { 21 | width: 100%; 22 | height: 100%; 23 | object-fit: cover; 24 | border-radius: 7px; 25 | vertical-align: middle; 26 | } 27 | 28 | .snippet-img:hover { 29 | opacity: 0.7; 30 | transition-duration: 0.5s; 31 | } 32 | 33 | .snippet-info { 34 | display: flex; 35 | flex-direction: column; 36 | flex: 6; 37 | margin: 15px 10px; 38 | } 39 | 40 | .detail-fade { 41 | color: gray; 42 | } 43 | 44 | .snippet-price { 45 | flex: 2; 46 | margin: 15px 10px; 47 | } 48 | 49 | .snippet-review { 50 | flex: 6; 51 | margin: 15px 10px; 52 | font-size: 12px; 53 | color: gray; 54 | } 55 | 56 | .snippet-section a:hover { 57 | color: lightgray; 58 | } 59 | 60 | .no-hover * { 61 | cursor: default !important; 62 | } 63 | -------------------------------------------------------------------------------- /app/assets/stylesheets/api/favorite.css: -------------------------------------------------------------------------------- 1 | .favorite-box { 2 | display: flex; 3 | justify-content: flex-start; 4 | } 5 | 6 | .favorite-box h5 { 7 | margin: 5px 0px; 8 | } 9 | 10 | .favorite-box h5:hover { 11 | cursor: pointer; 12 | } 13 | 14 | .favorite-box div { 15 | align-items: center; 16 | margin: 0 5px; 17 | } 18 | 19 | .favorited { 20 | color: #FF8787; 21 | } 22 | 23 | .not-favorite { 24 | color: gray; 25 | } 26 | -------------------------------------------------------------------------------- /app/assets/stylesheets/api/favorites.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the api/favorites controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/api/filter.css: -------------------------------------------------------------------------------- 1 | .filter { 2 | display: flex; 3 | justify-content: space-between; 4 | margin: 10px; 5 | } 6 | 7 | .filter-list { 8 | display: flex; 9 | justify-content: space-around; 10 | align-items: center; 11 | border-bottom: 1px solid gainsboro; 12 | flex: 2; 13 | } 14 | 15 | .filter-item { 16 | font-size: 2vw; 17 | font-weight: 100; 18 | color: #009080; 19 | } 20 | 21 | .filter-item:hover { 22 | cursor: pointer; 23 | color: mediumaquamarine; 24 | border-bottom: 1px solid #A70303; 25 | } 26 | 27 | .active-filter { 28 | color: #008080; 29 | font-weight: bold; 30 | border-bottom: 1px solid #F13737; 31 | } 32 | 33 | .page-list { 34 | display: flex; 35 | flex: 1; 36 | height: 3vw; 37 | justify-content: space-around; 38 | align-items: center; 39 | border-bottom: 1px solid gainsboro; 40 | } 41 | 42 | .page-list .highlight { 43 | font-size: 1.5vw; 44 | } 45 | 46 | .clickable:hover { 47 | opacity: 0.5; 48 | cursor: pointer; 49 | } 50 | -------------------------------------------------------------------------------- /app/assets/stylesheets/api/hours.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the api/hours controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/api/manager.css: -------------------------------------------------------------------------------- 1 | .editable-input { 2 | border: 1px solid black; 3 | border-radius: 3px; 4 | padding: 1px 5px; 5 | } 6 | 7 | .horizontal { 8 | display: flex; 9 | justify-content: flex-start; 10 | align-items: center; 11 | margin: 2px 5px; 12 | width: 100%; 13 | } 14 | 15 | .manager-text { 16 | margin: 0px 5px; 17 | } 18 | 19 | .manager-highlight { 20 | color: #D41010; 21 | } 22 | 23 | .editable-text { 24 | margin: 0px 5px; 25 | padding: 2px; 26 | border: 1px solid gainsboro; 27 | border-radius: 3px; 28 | color: #D41010; 29 | background-color: whitesmoke; 30 | } 31 | 32 | .editable-text:hover { 33 | cursor: pointer; 34 | border: 1px solid #D41010; 35 | } 36 | 37 | .manager-add-table { 38 | align-items: center; 39 | justify-content: space-between; 40 | } 41 | 42 | .user-show-nav .button { 43 | width: fit-content; 44 | height: fit-content; 45 | } 46 | 47 | .manager-date { 48 | padding: 0px 15px; 49 | } 50 | -------------------------------------------------------------------------------- /app/assets/stylesheets/api/modal.css: -------------------------------------------------------------------------------- 1 | .modal { 2 | z-index: 10; 3 | height: 100%; 4 | width: 100%; 5 | display: flex; 6 | flex-direction: column; 7 | justify-content: center; 8 | position: fixed; 9 | left: 0px; 10 | top: 0px; 11 | background-color: rgb(0,0,0); 12 | background-color: rgba(0,0,0, 0.2); 13 | overflow-x: hidden; 14 | } 15 | 16 | .overlay { 17 | height: 100%; 18 | width: 100%; 19 | display: fixed; 20 | left: 0px; 21 | top: 0px; 22 | background-color: rgba(0,0,0,0.1); 23 | } 24 | -------------------------------------------------------------------------------- /app/assets/stylesheets/api/photos-section.css: -------------------------------------------------------------------------------- 1 | .show-section { 2 | display: flex; 3 | flex-direction: column; 4 | justify-content: center; 5 | padding-bottom: 15px; 6 | } 7 | 8 | .section-img { 9 | display: inline-block; 10 | max-height: 230px; 11 | } 12 | 13 | .section-img img { 14 | display: inline-block; 15 | width: 99%; 16 | height: 99%; 17 | object-fit: cover; 18 | } 19 | -------------------------------------------------------------------------------- /app/assets/stylesheets/api/reviews.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the api/reviews controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | 5 | .reviews-section-bar h1 { 6 | padding-left: 20px; 7 | border-bottom: gainsboro; 8 | font-size: 24px; 9 | } 10 | 11 | .review-top { 12 | display: flex; 13 | flex-direction: column; 14 | border-top: 1px solid gainsboro; 15 | border-bottom: 1px solid gainsboro; 16 | padding: 10px 0px; 17 | } 18 | 19 | .review-details { 20 | margin: 10px; 21 | } 22 | 23 | .review-overalls { 24 | display: flex; 25 | justify-content: space-between; 26 | } 27 | 28 | .rating-stars { 29 | flex: 7; 30 | display: flex; 31 | flex-direction: column; 32 | } 33 | 34 | .overall { 35 | font-size: 20px; 36 | } 37 | 38 | .rating { 39 | flex: 2; 40 | font-size: 24px; 41 | margin: 10px 30px; 42 | } 43 | 44 | .review-averages { 45 | display: flex; 46 | justify-content: space-around; 47 | } 48 | 49 | .avg-scores { 50 | display: flex; 51 | flex-direction: column; 52 | justify-content: space-around; 53 | } 54 | 55 | .review-type { 56 | font-size: 12px; 57 | color: gray; 58 | } 59 | 60 | .review-score { 61 | font-size: 14px; 62 | font-weight: bold; 63 | } 64 | -------------------------------------------------------------------------------- /app/assets/stylesheets/api/seatings.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the api/seatings controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/api/sessions.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the api/sessions controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the 9 | * compiled file so the styles you add here take precedence over styles defined in any styles 10 | * defined in the other CSS/SCSS files in this directory. It is generally better to create a new 11 | * file per style scope. 12 | * 13 | *= require_tree . 14 | *= require_self 15 | *= _css_reset 16 | *= _navbar.css 17 | *= _form.css 18 | *= _map.css 19 | */ 20 | -------------------------------------------------------------------------------- /app/assets/stylesheets/footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | height: 30px; 3 | margin-top: 20px; 4 | background-color: white; 5 | padding: 15px; 6 | } 7 | 8 | .footer-links { 9 | vertical-align: middle; 10 | display: flex; 11 | color: gray; 12 | } 13 | 14 | .footer-links li { 15 | margin: 0px 10px; 16 | } 17 | 18 | .footer a:hover { 19 | font-weight: bold; 20 | font-size: 16px; 21 | color: darkgray; 22 | } 23 | -------------------------------------------------------------------------------- /app/assets/stylesheets/spinner.css: -------------------------------------------------------------------------------- 1 | .spinner-cover { 2 | z-index: 11; 3 | height: 100%; 4 | width: 100%; 5 | position: fixed; 6 | top: 0px; 7 | left: 0px; 8 | background-color: rgb(0,0,0); 9 | background-color: rgba(0,0,0,0.0); 10 | display: flex; 11 | flex-direction: column; 12 | justify-content: center; 13 | } 14 | 15 | .spinner-container { 16 | align-self: center; 17 | max-width: 30%; 18 | max-height: 30%; 19 | } 20 | -------------------------------------------------------------------------------- /app/assets/stylesheets/static_pages.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the StaticPages controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/staticpages.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the staticpages controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/controllers/api/cities_controller.rb: -------------------------------------------------------------------------------- 1 | class Api::CitiesController < ApplicationController 2 | 3 | def index 4 | @cities = City.all 5 | end 6 | 7 | def show 8 | @city = City.find_city(city_params) 9 | render "api/cities/show" 10 | end 11 | 12 | private 13 | def city_params 14 | params.permit(:id, :page, :per_page) 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /app/controllers/api/favorites_controller.rb: -------------------------------------------------------------------------------- 1 | class Api::FavoritesController < ApplicationController 2 | 3 | def create 4 | @favorite = Favorite.new(favorite_params) 5 | 6 | if @favorite.save 7 | render "api/favorites/show" 8 | else 9 | render @favorite.errors.full_messages, status: 422 10 | end 11 | end 12 | 13 | def destroy 14 | @favorite = Favorite.find(params[:id]) 15 | @favorite.destroy 16 | render 'api/favorites/show' 17 | end 18 | 19 | private 20 | def favorite_params 21 | params.require(:favorite).permit(:user_id, :restaurant_id) 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /app/controllers/api/hours_controller.rb: -------------------------------------------------------------------------------- 1 | class Api::HoursController < ApplicationController 2 | def show 3 | @hour = Hour.find(params[:id]) 4 | render 'api/hours/show' 5 | end 6 | 7 | def update 8 | @hour = Hour.find(params[:hour][:id]) 9 | 10 | if @hour.update(hour_params) 11 | render 'api/hours/show' 12 | else 13 | render json: @hour.erros.full_messages 14 | end 15 | end 16 | 17 | private 18 | def hour_params 19 | params.require(:hour).permit(:id, :day, :open, :close, :restaurant_id) 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /app/controllers/api/manager_controller.rb: -------------------------------------------------------------------------------- 1 | class Api::ManagerController < ApplicationController 2 | def show 3 | @restaurant = Restaurant.find_manager_restaurant(params[:id]) 4 | 5 | if @restaurant && logged_in? 6 | render 'api/manager/show' 7 | else 8 | render json: @restaurant.errors.full_messages 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/controllers/api/reservations_controller.rb: -------------------------------------------------------------------------------- 1 | class Api::ReservationsController < ApplicationController 2 | def index 3 | @reservations = Reservation.find_all_reservations( 4 | params[:query][:date], 5 | params[:query][:id] 6 | ) 7 | 8 | render 'api/reservations/index' 9 | end 10 | 11 | def create 12 | @reservation = Reservation.new(reservation_params) 13 | 14 | if @reservation.save 15 | render 'api/reservations/show' 16 | else 17 | render json: {base: @reservation.errors.full_messages }, status: 422 18 | end 19 | end 20 | 21 | def show 22 | @reservation = Reservation.find(params[:id]) 23 | render 'api/reservations/show' 24 | end 25 | 26 | def search 27 | query = params[:query] 28 | time = query[:time].to_i 29 | @reservations = Reservation.search_reservations( 30 | query[:date], 31 | query[:time].to_i, 32 | query[:seats_id], 33 | query[:restaurant_id] 34 | ) 35 | 36 | render 'api/reservations/search' 37 | end 38 | 39 | def destroy 40 | @reservation = Reservation.find(params[:id]) 41 | @reservation.destroy 42 | render 'api/reservations/show' 43 | end 44 | 45 | private 46 | def reservation_params 47 | params.require(:reservation).permit(:user_id, :restaurant_id, :time, :date, :seating_id, :seats) 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /app/controllers/api/reviews_controller.rb: -------------------------------------------------------------------------------- 1 | class Api::ReviewsController < ApplicationController 2 | def index 3 | data = Review.find_all(params) 4 | @reviews = data[0] 5 | @params = data[1] 6 | end 7 | 8 | def create 9 | @review = Review.new(review_params) 10 | 11 | if @review.save 12 | render 'api/reviews/show' 13 | else 14 | render json: @review.errors.full_messages, status: 422 15 | end 16 | end 17 | 18 | def show 19 | @review = Review.find_review(params[:id]) 20 | end 21 | 22 | def destroy 23 | review = Review.find(params[:id]) 24 | review.destroy 25 | render 26 | end 27 | 28 | private 29 | def review_params 30 | params.require(:review).permit(:reservation_id, :rating, 31 | :details, :food, :service, :ambiance, :value) 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /app/controllers/api/seatings_controller.rb: -------------------------------------------------------------------------------- 1 | class Api::SeatingsController < ApplicationController 2 | def create 3 | @seating = Seating.new(seating_params) 4 | 5 | if @seating.save 6 | render 'api/seatings/show' 7 | else 8 | render json: @seating.errors.full_messages, status: 409 9 | end 10 | end 11 | 12 | def show 13 | @seating = Seating.find(params[:id]) 14 | render 'api/seatings/show' 15 | end 16 | 17 | def search 18 | @seatings = Seating.availabilities(params[:query]) 19 | 20 | render 'api/seatings/search' 21 | end 22 | 23 | def update 24 | @seating = Seating.find(params[:id]) 25 | 26 | if @seating.update(seating_params) 27 | render 'api/seatings/show' 28 | else 29 | render json: @seating.errors.full_messages, status: 422 30 | end 31 | end 32 | 33 | def destroy 34 | @seating = Seating.find(params["id"]) 35 | Seating.destroy(params["id"]) 36 | render 'api/seatings/show' 37 | end 38 | 39 | private 40 | def seating_params 41 | params.permit(:restaurant_id, :id, :seats, :max_tables) 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /app/controllers/api/sessions_controller.rb: -------------------------------------------------------------------------------- 1 | class Api::SessionsController < ApplicationController 2 | def create 3 | @user = User.find_by_credentials( 4 | params[:user][:email], 5 | params[:user][:password] 6 | ) 7 | 8 | if @user && @user.is_password?(params[:user][:password]) 9 | login(@user) 10 | render 'api/sessions/show' 11 | else 12 | render json: ["Incorrect login. Please log in"], status: 422 13 | end 14 | end 15 | 16 | def destroy 17 | logout(current_user) 18 | render json: {} 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /app/controllers/api/users_controller.rb: -------------------------------------------------------------------------------- 1 | class Api::UsersController < ApplicationController 2 | def create 3 | @user = User.new(user_params) 4 | 5 | if @user.save 6 | login(@user) 7 | 8 | render "api/users/show" 9 | else 10 | render json: @user.errors.full_messages, status: 422 11 | end 12 | end 13 | 14 | def show 15 | @user = User.find_user(params[:id]) 16 | 17 | if @user && @user == current_user 18 | render "api/users/show" 19 | else 20 | render json: @user.errors.full_messages, status: 422 21 | end 22 | end 23 | 24 | private 25 | def user_params 26 | params.require(:user).permit(:username, :email, :password) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | # Prevent CSRF attacks by raising an exception. 3 | # For APIs, you may want to use :null_session instead. 4 | protect_from_forgery with: :exception 5 | helper_method :current_user, :current_session, :logged_in? 6 | 7 | def current_user 8 | user = User.find_by(session_token: session[:session_token]) 9 | end 10 | 11 | def current_session 12 | user = User.find_session(session[:session_token]) 13 | end 14 | 15 | def logged_in? 16 | !!current_user 17 | end 18 | 19 | def login(user) 20 | user.session_token = user.reset_session_token! 21 | session[:session_token] = user.session_token 22 | end 23 | 24 | def logout(user) 25 | user.session_token = user.reset_session_token! 26 | session[:session_token] = nil 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /app/controllers/static_pages_controller.rb: -------------------------------------------------------------------------------- 1 | class StaticPagesController < ApplicationController 2 | def root 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/helpers/api/cities_helper.rb: -------------------------------------------------------------------------------- 1 | module Api::CitiesHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/api/favorites_helper.rb: -------------------------------------------------------------------------------- 1 | module Api::FavoritesHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/api/hours_helper.rb: -------------------------------------------------------------------------------- 1 | module Api::HoursHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/api/reservations_helper.rb: -------------------------------------------------------------------------------- 1 | module Api::ReservationsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/api/restaurant_helper.rb: -------------------------------------------------------------------------------- 1 | module Api::RestaurantHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/api/restaurants_helper.rb: -------------------------------------------------------------------------------- 1 | module Api::RestaurantsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/api/reviews_helper.rb: -------------------------------------------------------------------------------- 1 | module Api::ReviewsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/api/seatings_helper.rb: -------------------------------------------------------------------------------- 1 | module Api::SeatingsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/api/sessions_helper.rb: -------------------------------------------------------------------------------- 1 | module Api::SessionsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/api/users_helper.rb: -------------------------------------------------------------------------------- 1 | module Api::UsersHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/static_pages_helper.rb: -------------------------------------------------------------------------------- 1 | module StaticPagesHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/staticpages_helper.rb: -------------------------------------------------------------------------------- 1 | module StaticpagesHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/mailers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/mailers/.keep -------------------------------------------------------------------------------- /app/models/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/models/.keep -------------------------------------------------------------------------------- /app/models/city.rb: -------------------------------------------------------------------------------- 1 | class City < ActiveRecord::Base 2 | validates :name, presence: true, uniqueness: true 3 | 4 | scope :search_city, -> (query) { where("lower(name) ~ ?", query) } 5 | scope :with_associations, -> (id) { includes(restaurants: [:photos, :ratings, :reviews]) } 6 | 7 | has_many :restaurants 8 | has_many :ratings, through: :restaurants 9 | has_many :reviews, through: :restaurants 10 | has_many :photos, through: :restaurants 11 | has_attached_file :image, default_url: "wine.jpg" 12 | validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/ 13 | 14 | attr_accessor :pages, :page, :per_page 15 | 16 | def self.find_city(params) 17 | city = City.with_associations(params[:id]) 18 | city.per_page = params[:per_page] ? params[:per_page] : 10 19 | 20 | if params[:page] 21 | city.page = params[:page] 22 | end 23 | 24 | city 25 | end 26 | 27 | def self.in_bounds(latLng) 28 | x = where("lat + 2 > ? AND lat - 2 < ? AND lng + 2 > ? AND lng -2 < ?", 29 | latLng["lat"], latLng["lat"], latLng["lng"], latLng["lng"] 30 | ) 31 | 32 | x.first.id 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/app/models/concerns/.keep -------------------------------------------------------------------------------- /app/models/favorite.rb: -------------------------------------------------------------------------------- 1 | class Favorite < ActiveRecord::Base 2 | validates :user_id, :restaurant_id, presence: true 3 | 4 | belongs_to :user 5 | belongs_to :restaurant 6 | end 7 | -------------------------------------------------------------------------------- /app/models/hour.rb: -------------------------------------------------------------------------------- 1 | class Hour < ActiveRecord::Base 2 | belongs_to :restaurant 3 | end 4 | -------------------------------------------------------------------------------- /app/models/photo.rb: -------------------------------------------------------------------------------- 1 | class Photo < ActiveRecord::Base 2 | validates :restaurant, presence: true 3 | 4 | belongs_to :restaurant 5 | 6 | has_attached_file :image, default_url: "wine.jpg" 7 | validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/ 8 | end 9 | -------------------------------------------------------------------------------- /app/models/rating.rb: -------------------------------------------------------------------------------- 1 | class Rating < ActiveRecord::Base 2 | validates :restaurant, presence: true 3 | validates :restaurant, uniqueness: true 4 | before_create :set_defaults 5 | 6 | belongs_to :restaurant, inverse_of: :rating 7 | 8 | def set_defaults 9 | self.total = 0 10 | self.rating = 0 11 | self.food = 0 12 | self.service = 0 13 | self.ambiance = 0 14 | self.value = 0 15 | end 16 | 17 | def add_review(review) 18 | self.total += 1 19 | self.rating += review.rating 20 | self.food += review.food 21 | self.service += review.service 22 | self.ambiance += review.ambiance 23 | self.value += review.value 24 | self.save 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /app/models/reservation.rb: -------------------------------------------------------------------------------- 1 | class Reservation < ActiveRecord::Base 2 | validates :user_id, :restaurant_id, presence: true 3 | before_save :ensure_available 4 | 5 | scope :find_all_reservations, -> (date, id) { includes(:user).where(date: date, restaurant_id: id) } 6 | scope :find_reservation, -> (id) { includes(:restaurants, :photos, :ratings).find(id) } 7 | 8 | belongs_to :user 9 | belongs_to :restaurant 10 | belongs_to :seating 11 | has_one :review, inverse_of: :reservation 12 | 13 | def self.search_reservations(date, time, seats_id, restaurant_id) 14 | Reservation 15 | .joins(:seating) 16 | .where("date = ?", date) 17 | .where("time BETWEEN ? AND ?", (time - 200), (time + 200)) 18 | .where("seating_id = ?", seats_id) 19 | .where("seatings.restaurant_id = ?", restaurant_id) 20 | .references(:seatings) 21 | end 22 | 23 | def ensure_available 24 | x = Reservation 25 | .where("date = ?", self.date) 26 | .where("time = ?", self.time) 27 | .where("seating_id = ?", self.seating_id) 28 | .count 29 | x < Seating.find(self.seating_id).max_tables 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /app/models/review.rb: -------------------------------------------------------------------------------- 1 | class Review < ActiveRecord::Base 2 | validates :reservation_id, :rating, presence: true 3 | before_save :add_to_rating 4 | 5 | scope :find_review, -> (id) { includes(:rating, :user, :reservation).find(id) } 6 | 7 | belongs_to :reservation 8 | has_one :restaurant, through: :reservation 9 | has_one :user, through: :reservation 10 | 11 | def self.get_pages(id, per_page) 12 | (Review.joins(:reservation).where(:reservations => { :restaurant_id => id }).count / per_page.to_i) + 1 13 | end 14 | 15 | def add_to_rating 16 | self.restaurant.rating.add_review(self) 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /app/views/api/cities/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | @cities.each do |city| 2 | json.set! city.id do 3 | json.id city.id 4 | json.name city.name 5 | json.image_url asset_path(city.image.url) 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/views/api/cities/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | count = @city.restaurants.count 2 | json.extract! @city, :id, :name, :page, :per_page 3 | json.pages count / @city.per_page.to_i + (count % @city.per_page.to_i > 0 ? 1 : 0) 4 | json.image_url asset_path(@city.image.url) 5 | json.restaurants @city.restaurants.map do |restaurant| 6 | json.extract! restaurant, :id, :name, :cuisine, :address, :location 7 | json.ratings do 8 | json.extract! restaurant.rating, :total, :rating, :food, :service, :ambiance, :value 9 | if restaurant.reviews.count > 0 10 | json.details restaurant.reviews[rand(restaurant.reviews.count)].details 11 | end 12 | end 13 | json.image restaurant.photos.first.nil? ? asset_path(@city.image.url) : asset_path(restaurant.photos.first.image.url) 14 | end 15 | -------------------------------------------------------------------------------- /app/views/api/favorites/_show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! favorite, :id, :user_id, :restaurant_id 2 | json.restaurant do 3 | json.image favorite.restaurant.photos.first.nil? ? asset_path(favorite.restaurant.city.image.url) : asset_path(favorite.restaurant.photos.first.image.url) 4 | json.extract! favorite.restaurant, :id, :name, :cuisine, :address, :location 5 | json.ratings do 6 | json.extract! favorite.restaurant.rating, :total, :rating, :food, :service, :ambiance, :value 7 | json.details favorite.restaurant.reviews.first.nil? ? "Be the first to review!" : favorite.restaurant.reviews.sample.details 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/views/api/favorites/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! 'api/favorites/show', favorite: @favorite 2 | -------------------------------------------------------------------------------- /app/views/api/hours/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! @hour, :id, :day, :open, :close, :restaurant_id 2 | -------------------------------------------------------------------------------- /app/views/api/manager/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! 'api/restaurants/show', restaurant: @restaurant 2 | -------------------------------------------------------------------------------- /app/views/api/reservations/_show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.id reservation.id 2 | json.reviewed reservation.review ? true : false 3 | json.extract! reservation, :time, :date, :seats 4 | json.restaurant do 5 | json.image reservation.restaurant.photos.first.nil? ? asset_path(reservation.restaurant.city.image.url) : asset_path(reservation.restaurant.photos.first.image.url) 6 | json.extract! reservation.restaurant, :id, :name, :cuisine, :address, :location 7 | json.ratings do 8 | json.extract! reservation.restaurant.rating, :total, :rating, :food, :service, :ambiance, :value 9 | json.details reservation.restaurant.reviews.length > 0 ? reservation.restaurant.reviews.sample.details : "Be the first to leave a review!" 10 | end 11 | end 12 | 13 | json.ignore_nil! 14 | json.username reservation.user.username 15 | -------------------------------------------------------------------------------- /app/views/api/reservations/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.ignore_nil! 2 | json.array! @reservations do |reservation| 3 | json.extract! reservation, :id, :time, :seats 4 | json.client reservation.user.username 5 | end 6 | -------------------------------------------------------------------------------- /app/views/api/reservations/search.json.jbuilder: -------------------------------------------------------------------------------- 1 | @reservations.each do |reservation| 2 | json.set! reservation.id do 3 | json.extract! reservation, :id, :time, :date 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/views/api/reservations/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! 'api/reservations/show', reservation: @reservation 2 | -------------------------------------------------------------------------------- /app/views/api/restaurants/_show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! restaurant, :id, :user_id, :name, :address, :location, 2 | :phone, :cuisine, :description, :hours, :site, :seatings 3 | json.ratings restaurant.rating, :total, :rating, :food, :service, :ambiance, :value 4 | json.reviews restaurant.reviews do |review| 5 | json.extract! review, :id, :reservation_id, :rating, :details, :food, :service, :ambiance, :value 6 | json.username review.user.username 7 | json.date review.reservation.date 8 | end 9 | json.images restaurant.photos.map { |photo| asset_path(photo.image.url) } 10 | -------------------------------------------------------------------------------- /app/views/api/restaurants/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! @params, :pages, :page, :per_page, :filter, :id 2 | json.restaurants @restaurants.map do |restaurant| 3 | json.extract! restaurant, :id, :name, :cuisine, :address, :location 4 | json.ratings do 5 | json.extract! restaurant.rating, :total, :rating, :food, :service, :ambiance, :value 6 | if !restaurant.sample_review.nil? 7 | json.details restaurant.sample_review.first.details 8 | end 9 | end 10 | json.image restaurant.photos.first.nil? ? asset_path(City.first.image.url) : asset_path(restaurant.photos.first.image.url) 11 | end 12 | -------------------------------------------------------------------------------- /app/views/api/restaurants/search.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.cities @cities.each do |city| 2 | json.extract! city, :name, :id, :state 3 | end 4 | json.restaurants @restaurants.each do |restaurant| 5 | json.set! restaurant.id do 6 | json.extract! restaurant, :name, :id, :address, :location 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /app/views/api/restaurants/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! 'api/restaurants/show', restaurant: @restaurant 2 | -------------------------------------------------------------------------------- /app/views/api/restaurants/update.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! @restaurant, :id, :user_id, :name, :address, :location, 2 | :phone, :cuisine, :description, :site 3 | -------------------------------------------------------------------------------- /app/views/api/reviews/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.ratings @reviews[0].restaurant.rating, :total, :rating, :food, :service, :ambiance, :value 2 | json.list @reviews do |review| 3 | json.extract! review, :id, :reservation_id, :rating, :details, :food, :service, :ambiance, :value 4 | json.username review.user.username 5 | json.date review.reservation.date 6 | end 7 | -------------------------------------------------------------------------------- /app/views/api/reviews/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! @review, :id, :reservation_id, :rating, :details, :food, :service, :ambiance, :value 2 | -------------------------------------------------------------------------------- /app/views/api/seatings/search.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.seatings @seatings 2 | -------------------------------------------------------------------------------- /app/views/api/seatings/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! @seating, :id, :seats, :max_tables, :restaurant_id 2 | -------------------------------------------------------------------------------- /app/views/api/sessions/_show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! user, :username, :id 2 | json.manager user.restaurant ? user.restaurant.id : false 3 | json.favorites user.favorites do |favorite| 4 | json.extract! favorite.restaurant, :id, :name 5 | end 6 | json.reservations user.reservations do |reservation| 7 | json.extract! reservation, :time, :date, :seats 8 | json.extract! reservation.restaurant, :id, :name 9 | end 10 | -------------------------------------------------------------------------------- /app/views/api/sessions/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! 'api/sessions/show', user: @user 2 | -------------------------------------------------------------------------------- /app/views/api/users/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! @user, :username, :id 2 | json.favorites do 3 | json.array! @user.favorites do |favorite| 4 | json.partial! 'api/favorites/show.json.jbuilder', favorite: favorite 5 | end 6 | end 7 | json.reservations do 8 | json.array! @user.reservations do |reservation| 9 | json.partial! 'api/reservations/show.json.jbuilder', reservation: reservation 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | HelloTable 5 | <%= stylesheet_link_tag 'application', media: 'all' %> 6 | <%= javascript_include_tag 'application' %> 7 | <%= javascript_include_tag "https://maps.googleapis.com/maps/api/js?key=#{ENV["google_maps_key"]}" %> 8 | <%= csrf_meta_tags %> 9 | 10 | 11 | 12 | 18 | 19 | 20 | 21 | <%= yield %> 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/views/static_pages/root.html.erb: -------------------------------------------------------------------------------- 1 |
2 | -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | APP_PATH = File.expand_path('../../config/application', __FILE__) 8 | require_relative '../config/boot' 9 | require 'rails/commands' 10 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | require_relative '../config/boot' 8 | require 'rake' 9 | Rake.application.run 10 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'pathname' 3 | 4 | # path to your application root. 5 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) 6 | 7 | Dir.chdir APP_ROOT do 8 | # This script is a starting point to setup your application. 9 | # Add necessary setup steps to this file: 10 | 11 | puts "== Installing dependencies ==" 12 | system "gem install bundler --conservative" 13 | system "bundle check || bundle install" 14 | 15 | # puts "\n== Copying sample files ==" 16 | # unless File.exist?("config/database.yml") 17 | # system "cp config/database.yml.sample config/database.yml" 18 | # end 19 | 20 | puts "\n== Preparing database ==" 21 | system "bin/rake db:setup" 22 | 23 | puts "\n== Removing old logs and tempfiles ==" 24 | system "rm -f log/*" 25 | system "rm -rf tmp/cache" 26 | 27 | puts "\n== Restarting application server ==" 28 | system "touch tmp/restart.txt" 29 | end 30 | -------------------------------------------------------------------------------- /bin/spring: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # This file loads spring without using Bundler, in order to be fast. 4 | # It gets overwritten when you run the `spring binstub` command. 5 | 6 | unless defined?(Spring) 7 | require 'rubygems' 8 | require 'bundler' 9 | 10 | lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read) 11 | spring = lockfile.specs.detect { |spec| spec.name == "spring" } 12 | if spring 13 | Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path 14 | gem 'spring', spring.version 15 | require 'spring/binstub' 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Rails.application 5 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require 'rails/all' 4 | 5 | # Require the gems listed in Gemfile, including any gems 6 | # you've limited to :test, :development, or :production. 7 | Bundler.require(*Rails.groups) 8 | 9 | module HelloTable 10 | class Application < Rails::Application 11 | 12 | config.paperclip_defaults = { 13 | :storage => :s3, 14 | :s3_protocol => :https, 15 | :s3_credentials => { 16 | :bucket => ENV["s3_bucket"], 17 | :access_key_id => ENV["s3_access_key_id"], 18 | :secret_access_key => ENV["s3_secret_access_key"], 19 | :s3_region => ENV["s3_region"] 20 | } 21 | } 22 | 23 | # Do not swallow errors in after_commit/after_rollback callbacks. 24 | config.active_record.raise_in_transactional_callbacks = true 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = '1.0' 5 | 6 | # Add additional assets to the asset load path 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | 9 | # Precompile additional assets. 10 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 11 | # Rails.application.config.assets.precompile += %w( search.js ) 12 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.action_dispatch.cookies_serializer = :json 4 | -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.session_store :cookie_store, key: '_HelloTable_session' 4 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] if respond_to?(:wrap_parameters) 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more, please read the Rails Internationalization guide 20 | # available at http://guides.rubyonrails.org/i18n.html. 21 | 22 | en: 23 | hello: "Hello world" 24 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | root "static_pages#root" 3 | namespace :api, defaults: { format: :json } do 4 | resources :users, only: [:create, :show] do 5 | resources :favorites, only: [:create, :show, :destroy] 6 | resources :manager, only: [:show, :update] 7 | end 8 | resources :hours, only: [:show, :update] 9 | resources :seatings, only: [:create, :show, :update, :destroy] do 10 | get "search", on: :collection 11 | end 12 | resource :session, only: [:create, :destroy] 13 | resources :restaurants, only: [:index, :create, :show, :update, :destroy] do 14 | get "search", on: :collection 15 | end 16 | resources :reviews, only: [:index, :create, :show, :destroy] 17 | resources :cities, only: [:index, :show] 18 | resources :reservations, only: [:index, :create, :show, :destroy] do 19 | get "search", on: :collection 20 | end 21 | resources :hours, only: [:show, :update] 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /config/secrets.yml: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rake secret` to generate a secure secret key. 9 | 10 | # Make sure the secrets in this file are kept private 11 | # if you're sharing your code publicly. 12 | 13 | development: 14 | secret_key_base: 50095cc48df4fc2719623c116365fa0ff396dcecde786387b5313283e6b4e67f72f0994e959c11f385756762c06b42a651a5f8f8319a5af1df6a57fa3d699499 15 | 16 | test: 17 | secret_key_base: ff94e2ca4ed5946c02e8cb50fa7919440e611cec3889c14b21c87dad9c20b626a1a0574bfac36ef3cce2a9f0d07c1cd5ea5014aff2138c32caa3f4ac8c607ffb 18 | 19 | # Do not keep production secrets in the repository, 20 | # instead read values from the environment. 21 | production: 22 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> 23 | -------------------------------------------------------------------------------- /db/migrate/20170418154103_create_users.rb: -------------------------------------------------------------------------------- 1 | class CreateUsers < ActiveRecord::Migration 2 | def change 3 | create_table :users do |t| 4 | t.string :username, null: false 5 | t.string :email, null: false 6 | t.string :password_digest, null: false 7 | t.string :session_token, null: false 8 | t.timestamps null: false 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20170420183553_create_restaurants.rb: -------------------------------------------------------------------------------- 1 | class CreateRestaurants < ActiveRecord::Migration 2 | def change 3 | create_table :restaurants do |t| 4 | t.integer :user_id, null: false 5 | t.string :restaurant_name, null: false 6 | t.string :cuisine 7 | t.string :restaurant_number, null: false 8 | t.text :description, null: false 9 | t.string :hours 10 | t.string :site 11 | t.string :location, null: false 12 | t.timestamps null: false 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /db/migrate/20170421172213_change_restaurant_description.rb: -------------------------------------------------------------------------------- 1 | class ChangeRestaurantDescription < ActiveRecord::Migration 2 | def change 3 | remove_column :restaurants, :description 4 | add_column :restaurants, :description, :text 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20170421204517_change_restaurant_locations.rb: -------------------------------------------------------------------------------- 1 | class ChangeRestaurantLocations < ActiveRecord::Migration 2 | def change 3 | remove_column :restaurants, :location 4 | add_column :restaurants, :street_address, :string 5 | add_column :restaurants, :city, :string 6 | add_column :restaurants, :state, :string 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /db/migrate/20170422015529_create_cities.rb: -------------------------------------------------------------------------------- 1 | class CreateCities < ActiveRecord::Migration 2 | def change 3 | create_table :cities do |t| 4 | t.string :city_name, null: false 5 | t.string :main_photo, null: false 6 | t.timestamps null: false 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20170422155415_add_attachment_main_to_cities.rb: -------------------------------------------------------------------------------- 1 | class AddAttachmentMainToCities < ActiveRecord::Migration 2 | def self.up 3 | change_table :cities do |t| 4 | t.attachment :image 5 | end 6 | end 7 | 8 | def self.down 9 | remove_attachment :cities, :main 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20170422162826_remove_main_photo.rb: -------------------------------------------------------------------------------- 1 | class RemoveMainPhoto < ActiveRecord::Migration 2 | def change 3 | remove_column :cities, :main_photo 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20170423004640_create_photos.rb: -------------------------------------------------------------------------------- 1 | class CreatePhotos < ActiveRecord::Migration 2 | def change 3 | create_table :photos do |t| 4 | t.integer :restaurant_id 5 | t.timestamps null: false 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /db/migrate/20170423004952_add_attachment_image_to_photos.rb: -------------------------------------------------------------------------------- 1 | class AddAttachmentImageToPhotos < ActiveRecord::Migration 2 | def self.up 3 | change_table :photos do |t| 4 | t.attachment :image 5 | end 6 | end 7 | 8 | def self.down 9 | remove_attachment :photos, :image 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20170423160955_add_zip_code.rb: -------------------------------------------------------------------------------- 1 | class AddZipCode < ActiveRecord::Migration 2 | def change 3 | add_column :restaurants, :zip, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20170423185958_add_state_to_city.rb: -------------------------------------------------------------------------------- 1 | class AddStateToCity < ActiveRecord::Migration 2 | def change 3 | add_column :cities, :state, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20170424150724_add_city_key_to_restaurants.rb: -------------------------------------------------------------------------------- 1 | class AddCityKeyToRestaurants < ActiveRecord::Migration 2 | def change 3 | add_column :restaurants, :city_id, :integer, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20170424160012_change_city_name.rb: -------------------------------------------------------------------------------- 1 | class ChangeCityName < ActiveRecord::Migration 2 | def change 3 | remove_column :restaurants, :city 4 | add_column :restaurants, :city_name, :string 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20170428131133_create_reservations.rb: -------------------------------------------------------------------------------- 1 | class CreateReservations < ActiveRecord::Migration 2 | def change 3 | create_table :reservations do |t| 4 | t.integer :user_id, null: false 5 | t.integer :restaurant_id, null: false 6 | t.integer :seats, null: false 7 | t.string :date, null: false 8 | t.integer :time, null: false 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20170428134339_change_seats_column.rb: -------------------------------------------------------------------------------- 1 | class ChangeSeatsColumn < ActiveRecord::Migration 2 | def change 3 | remove_column :reservations, :seats 4 | add_column :reservations, :seats, :string, null: false 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20170501225025_create_reviews.rb: -------------------------------------------------------------------------------- 1 | class CreateReviews < ActiveRecord::Migration 2 | def change 3 | create_table :reviews do |t| 4 | t.integer :reservation_id, null: false 5 | t.integer :rating, null: false 6 | t.text :details 7 | t.integer :food 8 | t.integer :service 9 | t.integer :ambiance 10 | t.integer :value 11 | t.timestamps null: false 12 | t.timestamps null: false 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /db/migrate/20170514222808_create_ratings.rb: -------------------------------------------------------------------------------- 1 | class CreateRatings < ActiveRecord::Migration 2 | def change 3 | create_table :ratings do |t| 4 | t.integer :restaurant_id 5 | t.integer :rating 6 | t.integer :food 7 | t.integer :service 8 | t.integer :ambiance 9 | t.integer :value 10 | t.timestamps null: false 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /db/migrate/20170514223610_add_total_to_rating.rb: -------------------------------------------------------------------------------- 1 | class AddTotalToRating < ActiveRecord::Migration 2 | def change 3 | add_column :ratings, :total, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20170517141246_fix_null_constraint_for_restaurant.rb: -------------------------------------------------------------------------------- 1 | class FixNullConstraintForRestaurant < ActiveRecord::Migration 2 | def change 3 | change_column :restaurants, :city_id, :integer, null: true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20170517223455_create_favorites.rb: -------------------------------------------------------------------------------- 1 | class CreateFavorites < ActiveRecord::Migration 2 | def change 3 | create_table :favorites do |t| 4 | t.integer :user_id, null: false 5 | t.integer :restaurant_id, null: false 6 | t.timestamps null: false 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20170911205416_add_location_to_city.rb: -------------------------------------------------------------------------------- 1 | class AddLocationToCity < ActiveRecord::Migration 2 | def change 3 | add_column :cities, :latLng, :string 4 | add_column :restaurants, :location, :string 5 | add_column :restaurants, :address, :string, null: false 6 | remove_column :restaurants, :street_address, :string 7 | remove_column :restaurants, :city_name, :string 8 | remove_column :restaurants, :state, :string 9 | remove_column :restaurants, :zip, :string 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20170925192045_refactor_city_name.rb: -------------------------------------------------------------------------------- 1 | class RefactorCityName < ActiveRecord::Migration 2 | def change 3 | rename_column :cities, :city_name, :name 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20170925212533_rename_restaurant_columns.rb: -------------------------------------------------------------------------------- 1 | class RenameRestaurantColumns < ActiveRecord::Migration 2 | def change 3 | rename_column :restaurants, :restaurant_name, :name 4 | rename_column :restaurants, :restaurant_number, :phone 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20170926192135_change_cities_latlng.rb: -------------------------------------------------------------------------------- 1 | class ChangeCitiesLatlng < ActiveRecord::Migration 2 | def change 3 | remove_column :cities, :latLng 4 | add_column :cities, :lat, :float, null: false 5 | add_column :cities, :lng, :float, null: false 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /db/migrate/20171031220719_create_hours.rb: -------------------------------------------------------------------------------- 1 | class CreateHours < ActiveRecord::Migration 2 | def change 3 | create_table :hours do |t| 4 | t.string :day, null: false 5 | t.integer :open, null: false 6 | t.integer :close, null: false 7 | t.integer :restaurant_id, null: false 8 | t.timestamps null: false 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20171031221001_create_seatings.rb: -------------------------------------------------------------------------------- 1 | class CreateSeatings < ActiveRecord::Migration 2 | def change 3 | create_table :seatings do |t| 4 | t.integer :restaurant_id, null: false 5 | t.integer :seats, null: false 6 | t.integer :max_tables, null: false 7 | t.timestamps null: false 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20171031221811_remove_hours_from_restaurant.rb: -------------------------------------------------------------------------------- 1 | class RemoveHoursFromRestaurant < ActiveRecord::Migration 2 | def change 3 | remove_column :restaurants, :hours 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20171031224113_change_seats_to_seatings_foreign_key.rb: -------------------------------------------------------------------------------- 1 | class ChangeSeatsToSeatingsForeignKey < ActiveRecord::Migration 2 | def change 3 | remove_column :reservations, :seats 4 | add_column :reservations, :seating_id, :integer, null: false 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20171202001715_add_seats_to_reservations.rb: -------------------------------------------------------------------------------- 1 | class AddSeatsToReservations < ActiveRecord::Migration 2 | def change 3 | add_column :reservations, :seats, :integer, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /docs/Wireframes/Available-reservations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/docs/Wireframes/Available-reservations.png -------------------------------------------------------------------------------- /docs/Wireframes/Create-account-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/docs/Wireframes/Create-account-form.png -------------------------------------------------------------------------------- /docs/Wireframes/Favorites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/docs/Wireframes/Favorites.png -------------------------------------------------------------------------------- /docs/Wireframes/Featured-location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/docs/Wireframes/Featured-location.png -------------------------------------------------------------------------------- /docs/Wireframes/Home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/docs/Wireframes/Home.png -------------------------------------------------------------------------------- /docs/Wireframes/Navbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/docs/Wireframes/Navbar.png -------------------------------------------------------------------------------- /docs/Wireframes/Recommendations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/docs/Wireframes/Recommendations.png -------------------------------------------------------------------------------- /docs/Wireframes/Reservation-bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/docs/Wireframes/Reservation-bar.png -------------------------------------------------------------------------------- /docs/Wireframes/Restaurant-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/docs/Wireframes/Restaurant-view.png -------------------------------------------------------------------------------- /docs/Wireframes/Reviews.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/docs/Wireframes/Reviews.png -------------------------------------------------------------------------------- /docs/Wireframes/Sign-in-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/docs/Wireframes/Sign-in-form.png -------------------------------------------------------------------------------- /docs/Wireframes/User-reservations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/docs/Wireframes/User-reservations.png -------------------------------------------------------------------------------- /docs/api-endpoints.md: -------------------------------------------------------------------------------- 1 |

API Endpoints

2 | 3 |

Root

4 | 5 | * GET / load React web application 6 | 7 |

Users

8 | 9 | * POST /api/users 10 | * PATCH /api/users 11 | 12 |

Session

13 | 14 | * POST /api/session 15 | * DELETE /api/session 16 | 17 |

Restaurants

18 | 19 | * GET /api/restaurants 20 | * POST /api/restaurants 21 | * GET /api/restaurants/:id 22 | * PATCH api/restaurants/:id 23 | * DELETE api/restaurants/:id 24 | 25 |

Reservations

26 | 27 | * GET /api/reservations 28 | * POST /api/reservations 29 | * GET /api/reservations/:id 30 | * DELETE api/reservations/:id 31 | 32 |

Reviews

33 | 34 | * GET /api/restaurants/reviews 35 | * POST /api/restaurants/reviews 36 | * GET /api/restaurants/reviews/:id 37 | * PATCH api/restaurants/reviews/:id 38 | * DELETE api/restaurants/reviews/:id 39 | 40 |

Favorites

41 | 42 | * GET /api/users/favorites 43 | * POST /api/users/favorites 44 | * DELETE api/users/favorites/:id 45 | -------------------------------------------------------------------------------- /docs/react-components.md: -------------------------------------------------------------------------------- 1 |

Component Hierarchy

2 | 3 |

AuthFormContainer

4 | 5 | * AuthForm 6 | 7 |

HomeContainer

8 | 9 | * Home 10 | * Navbar 11 | * RecommendationsItems 12 | 13 |

UsersContainer

14 | 15 | * ReservationsItems 16 | * RestaurantsItems 17 | * FavoritesItems 18 | 19 |

RestaurantsContainer

20 | 21 | * RestaurantsItem 22 | * ReviewsItem 23 | 24 |

ReviewsContainer

25 | 26 | * ReviewsItem 27 | 28 |

FavoritesContainer

29 | 30 | * FavoritesItems 31 | 32 |

RecommendationsContainer

33 | 34 | * RestaurantsItems 35 | * ReviewsItems 36 | 37 | 38 |

Routes

39 | 40 | | Path | Component | 41 | | --- | ---| 42 | | "/sign-up" | AuthFormContainer | 43 | | "/sign-in" | AuthFormContainer | 44 | | "/home" | HomeContainer | 45 | | "/restaurant/:reservation_id" | RestaurantsContainer | 46 | | "/favorites" | FavoritesContainer | 47 | | "/home/user" | UsersContainer | 48 | | "/city" | RecommendationsContainer | 49 | -------------------------------------------------------------------------------- /docs/sample-state.md: -------------------------------------------------------------------------------- 1 | ```{ 2 | currentUser: { 3 | id: userId, 4 | username: first name, 5 | } 6 | forms: { 7 | signUp: { errors: []}, 8 | signIn: { errors: []}, 9 | review: { errors: []}, 10 | } 11 | restaurants: { 12 | id: { 13 | user_id: id of owner, 14 | name: restaurant name, 15 | about: { 16 | style: type of dining, 17 | description: about text, 18 | hours: hours of operation, 19 | phone: restaurant phone number, 20 | siteLink: link to restaurant website, 21 | } 22 | location: (tentatively geolocation), 23 | photos: urls for photos, 24 | } 25 | } 26 | reservations: { 27 | id: { 28 | user: belongs to user, 29 | restaurant: belongs to restaurant, 30 | time: time, 31 | date: date, 32 | } 33 | } 34 | reviews: { 35 | id: { 36 | rating: { 37 | total: overall rating, 38 | food: food score, 39 | service: service score, 40 | ambiance: ambiance score, 41 | value: value score, 42 | noise: noise score, 43 | } 44 | date: user reservation date, 45 | location: user location, 46 | restaurant: restaurant_id, 47 | } 48 | } 49 | favorites: { 50 | restaurant: restaurant_id, 51 | } 52 | }``` 53 | -------------------------------------------------------------------------------- /frontend/actions/city_actions.js: -------------------------------------------------------------------------------- 1 | import * as CityAPIUtil from '../util/city_api_util'; 2 | 3 | export const RECEIVE_ALL_CITIES = 'RECEIVE_ALL_CITIES'; 4 | export const RECEIVE_ALL_RESTAURANTS = 'RECEIVE_ALL_RESTAURANTS'; 5 | // export const RECEIVE_CITY = 'RECEIVE_CITY'; 6 | 7 | export const fetchAllCities = () => dispatch => { 8 | return CityAPIUtil.fetchAllCities() 9 | .then((cities) => dispatch(receiveAllCities(cities))); 10 | } 11 | 12 | export const fetchCity = query => dispatch => { 13 | return CityAPIUtil.fetchCity(query) 14 | .then((restaurants) => dispatch(receiveAllRestaurants(restaurants))); 15 | } 16 | // export const fetchCity = cityId => dispatch => { 17 | // return CityAPIUtil.fetchCity(cityId) 18 | // .then((city) => dispatch(receiveCity(city))); 19 | // } 20 | 21 | const receiveAllCities = cities => ({ 22 | type: RECEIVE_ALL_CITIES, 23 | cities, 24 | }); 25 | 26 | const receiveAllRestaurants = restaurants => ({ 27 | type: RECEIVE_ALL_RESTAURANTS, 28 | restaurants, 29 | }); 30 | -------------------------------------------------------------------------------- /frontend/actions/favorites_actions.js: -------------------------------------------------------------------------------- 1 | import * as FavoritesAPIUtil from '../util/favorites_util'; 2 | 3 | export const RECEIVE_FAVORITES = 'RECEIVE_FAVORITES'; 4 | export const RECEIVE_FAVORITE = 'RECEIVE_FAVORITE'; 5 | export const REMOVE_FAVORITE = 'REMOVE_FAVORITE'; 6 | export const CLEAR_FAVORITES = 'CLEAR_FAVORITES'; 7 | 8 | export const receiveAllFavorites = favorites => dispatch => { 9 | return dispatch(receiveFavorites(favorites)); 10 | } 11 | 12 | export const addFavorite = newFavorite => dispatch => { 13 | return FavoritesAPIUtil.createFavorite(newFavorite) 14 | .then(favorite => dispatch(receiveFavorite(favorite))); 15 | } 16 | 17 | export const removeFavorite = favorite => dispatch => { 18 | return FavoritesAPIUtil.destroyFavorite(favorite) 19 | .then(dispatch(receiveRemoveFavorite(favorite))); 20 | } 21 | 22 | export const receiveFavorites = favorites => ({ 23 | type: RECEIVE_FAVORITES, 24 | favorites, 25 | }); 26 | 27 | const receiveFavorite = favorite => ({ 28 | type: RECEIVE_FAVORITE, 29 | favorite, 30 | }); 31 | 32 | const receiveRemoveFavorite = favorite => ({ 33 | type: REMOVE_FAVORITE, 34 | favorite 35 | }); 36 | -------------------------------------------------------------------------------- /frontend/actions/hours_actions.js: -------------------------------------------------------------------------------- 1 | import { resetCurrentModal } from './modal_actions'; 2 | import * as HoursAPIUtil from '../util/hours_api_util'; 3 | 4 | export const RECEIVE_HOUR = 'RECEIVE_HOUR'; 5 | export const RECEIVE_HOUR_ERRORS = 'RECEIVE_HOUR_ERRORS'; 6 | export const CLEAR_ERRORS = 'CLEAR_ERRORS'; 7 | 8 | export const updateHour = hours => dispatch => { 9 | return HoursAPIUtil.updateHour(hours) 10 | .then(updatedHour => dispatch(receiveHour(updatedHour)), 11 | error => dispatch(receiveErrors(error))) 12 | .then(() => dispatch(resetCurrentModal())); 13 | } 14 | 15 | export const setError = error => dispatch => { 16 | dispatch(resetCurrentModal()); 17 | return dispatch(receiveErrors(error)); 18 | } 19 | 20 | export const clearErrors = () => dispatch => { 21 | return dispatch(receiveClearErrrors()); 22 | } 23 | 24 | const receiveHour = hour => ({ 25 | type: RECEIVE_HOUR, 26 | hour, 27 | }); 28 | 29 | const receiveErrors = errors => ({ 30 | type: RECEIVE_HOUR_ERRORS, 31 | errors, 32 | }); 33 | 34 | const receiveClearErrrors = () => ({ 35 | type: CLEAR_ERRORS, 36 | }); 37 | -------------------------------------------------------------------------------- /frontend/actions/map_actions.js: -------------------------------------------------------------------------------- 1 | import * as MapUtil from '../util/map_util'; 2 | 3 | export const RECEIVE_MAP_DATA = 'RECEIVE_MAP_DATA'; 4 | 5 | export const fetchMapData = address => dispatch => { 6 | return MapUtil.fetchMapData(address) 7 | .then(data => { 8 | dispatch(receiveMapData(data))}); 9 | } 10 | 11 | const receiveMapData = data => ({ 12 | type: RECEIVE_MAP_DATA, 13 | data 14 | }); 15 | -------------------------------------------------------------------------------- /frontend/actions/modal_actions.js: -------------------------------------------------------------------------------- 1 | export const RECEIVE_CURRENT_MODAL = 'RECEIVE_CURRENT_MODAL'; 2 | export const RECEIVE_RESET_MODAL = 'RECEIVE_RESET_MODAL'; 3 | const RECEIVE_ERRORS = 'RECEIVE_ERRORS'; 4 | 5 | export const setCurrentModal = modal => dispatch => { 6 | dispatch(receiveCurrentModal(modal)); 7 | } 8 | 9 | export const resetCurrentModal = () => dispatch => { 10 | dispatch(receiveErrors([])); 11 | dispatch(receiveResetModal()); 12 | } 13 | 14 | const receiveCurrentModal = modal => ({ 15 | type: RECEIVE_CURRENT_MODAL, 16 | modal, 17 | }); 18 | 19 | const receiveResetModal = () => ({ 20 | type: RECEIVE_RESET_MODAL, 21 | }); 22 | 23 | const receiveErrors = errors => ({ 24 | type: RECEIVE_ERRORS, 25 | errors 26 | }) 27 | -------------------------------------------------------------------------------- /frontend/actions/search_actions.js: -------------------------------------------------------------------------------- 1 | import { hashHistory } from 'react-router'; 2 | import * as SearchAPIUtil from '../util/search_api_util'; 3 | 4 | export const RECEIVE_SEARCH = 'RECEIVE_SEARCH'; 5 | export const RECEIVE_SEARCH_PARAMS = 'RECEIVE_SEARCH_PARAMS'; 6 | export const RECEIVE_SEARCH_BOX_PARAMS = 'RECEIVE_SEARCH_BOX_PARAMS'; 7 | export const RECEIVE_FILTER = 'RECEIVE_FILTER'; 8 | 9 | export const searchRestaurants = (query, callback) => dispatch => { 10 | return SearchAPIUtil.searchRestaurants(query) 11 | .then((search) => dispatch(receiveSearch(search))); 12 | } 13 | 14 | export const filterResults = searchTerm => dispatch => { 15 | return dispatch(receiveFilter(searchTerm)); 16 | } 17 | 18 | export const setSearchParams = params => dispatch => { 19 | return dispatch(receiveSearchParams(params)); 20 | } 21 | 22 | export const setSearchBoxParams = params => dispatch => { 23 | return dispatch(receiveSearchBoxParams(params)); 24 | } 25 | 26 | const receiveSearch = search => ({ 27 | type: RECEIVE_SEARCH, 28 | search, 29 | }); 30 | 31 | const receiveSearchParams = params => ({ 32 | type: RECEIVE_SEARCH_PARAMS, 33 | params, 34 | }); 35 | 36 | const receiveSearchBoxParams = params => ({ 37 | type: RECEIVE_SEARCH_BOX_PARAMS, 38 | params, 39 | }); 40 | 41 | const receiveFilter = searchTerm => ({ 42 | type: RECEIVE_FILTER, 43 | searchTerm, 44 | }); 45 | -------------------------------------------------------------------------------- /frontend/actions/session_actions.js: -------------------------------------------------------------------------------- 1 | import * as SessionApiUtil from '../util/session_api_util'; 2 | import { hashHistory } from 'react-router'; 3 | 4 | export const RECEIVE_CURRENT_USER = 'RECEIVE_CURRENT_USER'; 5 | export const RECEIVE_ERRORS = 'RECEIVE_ERRORS'; 6 | export const LOGOUT = 'LOGOUT'; 7 | 8 | export const login = user => dispatch => { 9 | return SessionApiUtil.login(user) 10 | .then(newUser => dispatch(receiveCurrentUser(newUser)) 11 | , err => dispatch(receiveErrors(err.responseJSON))); 12 | }; 13 | 14 | export const signup = (user) => dispatch => { 15 | return SessionApiUtil.signup(user) 16 | .then((newUser) => dispatch(receiveCurrentUser(newUser)) 17 | , err => dispatch(receiveErrors(err.responseJSON))); 18 | }; 19 | 20 | export const logout = () => dispatch => { 21 | return SessionApiUtil.logout() 22 | .then(() => dispatch(logOutUser())); 23 | }; 24 | 25 | const receiveCurrentUser = (user) => ({ 26 | type: RECEIVE_CURRENT_USER, 27 | user 28 | }); 29 | 30 | export const receiveErrors = errors => ({ 31 | type: RECEIVE_ERRORS, 32 | errors, 33 | }); 34 | 35 | const logOutUser = () => ({ 36 | type: LOGOUT, 37 | }); 38 | -------------------------------------------------------------------------------- /frontend/actions/user_actions.js: -------------------------------------------------------------------------------- 1 | import * as UserAPIUtil from '../util/user_api_util'; 2 | import { resetCurrentModal } from './modal_actions'; 3 | import { RECEIVE_USER_RESERVATIONS, receiveUserReservations } from './reservations_actions'; 4 | import { RECEIVE_FAVORITES, receiveFavorites } from './favorites_actions'; 5 | 6 | export const RECEIVE_USER = 'RECEIVE_USER'; 7 | export const RESET_USER = 'RESET_USER'; 8 | export const RECEIVE_ERRORS = 'RECEIVE_ERRORS'; 9 | 10 | export const fetchUser = id => dispatch => { 11 | return UserAPIUtil.getUser(id) 12 | .then(user => { 13 | dispatch(receiveUserReservations(user.reservations)); 14 | dispatch(receiveUser(user)); 15 | }, err => dispatch(receiveErrors(err.responseJSON))) 16 | .then(() => dispatch(resetCurrentModal())); 17 | } 18 | 19 | export const resetUser = () => dispatch => { 20 | return dispatch(receiveResetUser()); 21 | } 22 | 23 | const receiveUser = user => ({ 24 | type: RECEIVE_USER, 25 | user, 26 | }); 27 | 28 | const receiveResetUser = () => ({ 29 | type: RESET_USER, 30 | }); 31 | 32 | const receiveErrors = errors => ({ 33 | type: RECEIVE_ERRORS, 34 | errors, 35 | }); 36 | -------------------------------------------------------------------------------- /frontend/components/app.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router'; 3 | import { connect } from 'react-redux'; 4 | import Navbar from './navbar'; 5 | import Modal from './modal'; 6 | 7 | const App = (props) => { 8 | 9 | const Footer = () => { 10 | return ( 11 | 18 | ) 19 | } 20 | 21 | return ( 22 |
23 | 24 | 25 | { props.children } 26 |
28 | ) 29 | } 30 | 31 | export default App; 32 | -------------------------------------------------------------------------------- /frontend/components/manager/field.jsx: -------------------------------------------------------------------------------- 1 | import * as ManagerUtil from '../../util/manager_util'; 2 | 3 | export default ({ targeted, id, text, change, click }) => { 4 | if (targeted) { 5 | return ManagerUtil.createInput({ 6 | cName: 'editable-input', 7 | placeHolder: text, 8 | changeHandler: change, 9 | key: id, 10 | id 11 | }); 12 | } else { 13 | return ManagerUtil.createSpan({ 14 | key: id, 15 | cName: 'editable-text', 16 | text: text, 17 | clickHandler: click, 18 | }); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /frontend/components/manager/manager_li.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import * as ManagerUtil from '../../util/manager_util'; 3 | 4 | export default ({ article, id, targeted, cName, remove, save, click }) => { 5 | let alternate; 6 | 7 | if (targeted) { 8 | alternate = ManagerUtil.getEditButtons({ 9 | onSave: save, 10 | onCancel: click, 11 | cName: 'horizontal'}); 12 | } else if (remove) { 13 | alternate = ( 14 |
15 | { ManagerUtil.createButton('Remove', remove) } 16 |
17 | ); 18 | } else { 19 | alternate = ManagerUtil.getBlankArticle('horizontal'); 20 | } 21 | 22 | const newLi = ( 23 |
  • 24 | { article } 25 | { alternate } 26 |
  • 27 | ); 28 | 29 | return newLi; 30 | } 31 | -------------------------------------------------------------------------------- /frontend/components/manager/manager_reviews.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'react-redux'; 3 | import * as ManagerUtil from '../../util/manager_util'; 4 | import ReviewSnippet from '../review/review_snippet'; 5 | 6 | class ManagerReviews extends React.Component { 7 | getReviewsList() { 8 | return this.props.reviews.map(review => ); 9 | } 10 | 11 | getReviewsSection() { 12 | const reviewsList = this.getReviewsList(); 13 | 14 | return ManagerUtil.createSection({ 15 | id: 'Reviews', 16 | title: 'Reviews', 17 | liElements: reviewsList, 18 | }); 19 | } 20 | 21 | render() { 22 | const reviewsSection = this.getReviewsSection(); 23 | 24 | return reviewsSection; 25 | } 26 | } 27 | 28 | const mapStateToProps = state => ({ 29 | reviews: state.reviews.reviews, 30 | }); 31 | 32 | export default connect(mapStateToProps)(ManagerReviews); 33 | -------------------------------------------------------------------------------- /frontend/components/manager/manager_side_bar.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Sticky, StickyContainer } from 'react-sticky'; 3 | 4 | export default ({ sections, handleClick }) => { 5 | const bar = sections.map((el, idx) =>{ 6 | return ( 7 |
    11 |

    { el }

    12 |
    13 | ); 14 | }); 15 | 16 | return ( 17 | 18 | { bar } 19 | 20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /frontend/components/restaurant/create_splash.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router'; 3 | import Modal from '../modal'; 4 | 5 | const CreateRestaurantSplash = ({setCurrentModal}) => { 6 | return ( 7 |
    8 |
    9 | 10 |
    11 |
    12 | ) 13 | } 14 | 15 | export default CreateRestaurantSplash; 16 | -------------------------------------------------------------------------------- /frontend/components/restaurant/photo_section.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const PhotoSection = ({photos}) => { 4 | if (photos.length > 0) { 5 | return ( 6 |
    7 |
    8 |

    Restaurant Photos

    9 |
    10 | 17 |
    18 | ) 19 | } else { 20 | return (
    ); 21 | } 22 | } 23 | 24 | export default PhotoSection; 25 | -------------------------------------------------------------------------------- /frontend/components/review/review_snippet.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router'; 3 | import ReactStars from 'react-stars'; 4 | 5 | const RestaurantSnippet = ({review}) => { 6 | const stars = (); 11 | 12 | return ( 13 |
    14 |
    15 |
    16 |
      17 |
    • { stars }
    • 18 |
    • Reviewed by: { review.username }
    • 19 |
    • Reviewed on: { review.date }
    • 20 |
    21 |
    22 |
    23 | {review.details} 24 |
    25 |
    26 |
    27 |
      28 |
    • Rating: {review.rating}
    • 29 |
    • Food: {review.food}
    • 30 |
    • Service: {review.service}
    • 31 |
    • Ambiance: {review.ambiance}
    • 32 |
    • Value: {review.value}
    • 33 |
    34 |
    35 |
    36 | ) 37 | } 38 | 39 | export default RestaurantSnippet; 40 | -------------------------------------------------------------------------------- /frontend/components/review/thank_you.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const ThankYou = ({ resetCurrentModal }) => { 4 | const text = 'Thank you. Your review has been submitted.'; 5 | 6 | return ( 7 |
    8 | { text } 9 | 10 |
    11 | ); 12 | } 13 | 14 | export default ThankYou; 15 | -------------------------------------------------------------------------------- /frontend/components/root.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Provider } from 'react-redux'; 3 | import { Router, Route, IndexRoute, hashHistory } from 'react-router'; 4 | import NavbarContainer from './navbar'; 5 | import sessionFormContainer from './session/session_form_container'; 6 | import configureStore from '../store/store'; 7 | import App from './app'; 8 | import restaurantContainer from './restaurant/restaurant_show'; 9 | import restaurantCreate from './restaurant/restaurant_create'; 10 | import CityIndex from './city/city_index'; 11 | import CityShow from './city/city_show'; 12 | import UserShow from './user/user_show'; 13 | import ReviewForm from './review/review_form'; 14 | import ManagerShow from './manager/manager'; 15 | import Modal from './modal'; 16 | 17 | const Root = ({store}) => { 18 | 19 | return( 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | ); 32 | }; 33 | 34 | export default Root; 35 | -------------------------------------------------------------------------------- /frontend/components/search/date_bar.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default ({ minValue, defaultDate, handleChange }) => { 4 | return ( 5 | 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /frontend/components/session/session_form_container.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { login, signup, receiveErrors } from '../../actions/session_actions'; 3 | import SessionForm from './session_form'; 4 | import { resetCurrentModal, setCurrentModal } from '../../actions/modal_actions'; 5 | 6 | const mapStateToProps = (state) => { 7 | return ({ 8 | current_user: state.session.current_user, 9 | logged_in: Boolean(state.session.current_user), 10 | errors: state.session.errors, 11 | formType: state.modal.type, 12 | }); 13 | }; 14 | 15 | const mapDispatchToProps = (dispatch) => { 16 | return ({ 17 | login: (user) => dispatch(login(user)), 18 | signup: (user) => dispatch(signup(user)), 19 | receiveErrors: (errors) => dispatch(receiveErrors(errors)), 20 | resetCurrentModal: () => dispatch(resetCurrentModal()), 21 | setCurrentModal: modal => dispatch(setCurrentModal(modal)), 22 | }); 23 | }; 24 | 25 | export default connect(mapStateToProps, mapDispatchToProps)(SessionForm); 26 | -------------------------------------------------------------------------------- /frontend/reducers/cities_reducer.js: -------------------------------------------------------------------------------- 1 | import { merge } from 'lodash'; 2 | import { RECEIVE_ALL_CITIES, RECEIVE_CITY } from '../actions/city_actions'; 3 | 4 | const _nullCities = { 5 | city: { 6 | name: "", 7 | image_url: "", 8 | restaurants: [], 9 | } 10 | } 11 | 12 | const CitiesReducer = (state = _nullCities, action) => { 13 | Object.freeze(state); 14 | switch (action.type) { 15 | case RECEIVE_ALL_CITIES: 16 | return merge({}, state, action.cities); 17 | case RECEIVE_CITY: 18 | return merge({}, state, { city: action.city }); 19 | default: 20 | return state; 21 | } 22 | } 23 | 24 | export default CitiesReducer; 25 | -------------------------------------------------------------------------------- /frontend/reducers/favorites_reducer.js: -------------------------------------------------------------------------------- 1 | import { RECEIVE_FAVORITE, REMOVE_FAVORITE, RECEIVE_FAVORITES, CLEAR_FAVORITES } from '../actions/favorites_actions'; 2 | import { RECEIVE_USER } from '../actions/user_actions'; 3 | import { LOGOUT } from '../actions/session_actions'; 4 | import * as FavoritesSelector from '../selectors/favorites_selector'; 5 | import { merge } from 'lodash'; 6 | 7 | const _nullFavorites = {} 8 | 9 | const FavoritesReducer = (state = _nullFavorites, action) => { 10 | Object.freeze(state) 11 | switch (action.type) { 12 | case RECEIVE_FAVORITES: 13 | return FavoritesSelector.faves(action.favorites); 14 | case RECEIVE_USER: 15 | return FavoritesSelector.faves(action.user.favorites); 16 | case RECEIVE_FAVORITE: 17 | const favorite = FavoritesSelector.fave(action.favorite); 18 | return merge({}, state, favorite); 19 | case REMOVE_FAVORITE: 20 | let newState = merge({}, state); 21 | delete newState[action.favorite.id]; 22 | return newState; 23 | case LOGOUT: 24 | return _nullFavorites 25 | default: 26 | return state; 27 | } 28 | } 29 | 30 | export default FavoritesReducer; 31 | -------------------------------------------------------------------------------- /frontend/reducers/hours_reducer.js: -------------------------------------------------------------------------------- 1 | import { merge } from 'lodash'; 2 | import { RECEIVE_HOURS } from '../actions/manager_actions'; 3 | import { RECEIVE_HOUR, RECEIVE_HOUR_ERRORS, CLEAR_ERRORS } from '../actions/hours_actions'; 4 | import * as ManagerSelector from '../selectors/manager_selectors'; 5 | 6 | const _nullHours = Object.freeze([]); 7 | 8 | const HoursReducer = (state = _nullHours, action) => { 9 | Object.freeze(state); 10 | switch (action.type) { 11 | case RECEIVE_HOURS: 12 | return action.hours; 13 | case RECEIVE_HOUR: 14 | return ManagerSelector.mergeHours(state, action.hour); 15 | case RECEIVE_HOUR_ERRORS: 16 | const hourErrors = merge([], state); 17 | hourErrors.errors = action.errors.responseJSON; 18 | return hourErrors; 19 | case CLEAR_ERRORS: 20 | const clearErrors = merge([], state); 21 | clearErrors.errors = []; 22 | return clearErrors; 23 | default: 24 | return state; 25 | } 26 | } 27 | 28 | export default HoursReducer; 29 | -------------------------------------------------------------------------------- /frontend/reducers/manager_reducer.js: -------------------------------------------------------------------------------- 1 | import { merge } from 'lodash'; 2 | import { 3 | RECEIVE_MANAGER_RESTAURANT, 4 | RECEIVE_UPDATED_HOURS, 5 | RECEIVE_UPDATED_SEATING, 6 | RECEIVE_SEATING, 7 | RECEIVE_REMOVE_SEATING, 8 | RECEIVE_ERRORS, 9 | CLEAR_ERRORS, 10 | } from '../actions/manager_actions'; 11 | import * as ManagerSelector from '../selectors/manager_selectors'; 12 | 13 | const _nullRestaurant = Object.freeze({ 14 | errors: [], 15 | }); 16 | 17 | const ManagerReducer = (state = _nullRestaurant, action) => { 18 | Object.freeze(state); 19 | switch (action.type) { 20 | case RECEIVE_MANAGER_RESTAURANT: 21 | return merge({}, state, action.restaurant); 22 | default: 23 | return state; 24 | } 25 | } 26 | 27 | export default ManagerReducer; 28 | -------------------------------------------------------------------------------- /frontend/reducers/modal_reducer.js: -------------------------------------------------------------------------------- 1 | import { RECEIVE_CURRENT_MODAL, RECEIVE_RESET_MODAL } from '../actions/modal_actions'; 2 | 3 | const _nullModal = { 4 | type: '', 5 | hidden: true, 6 | } 7 | 8 | const ModalReducer = (state = _nullModal, action) => { 9 | Object.freeze(state); 10 | 11 | switch (action.type) { 12 | case RECEIVE_CURRENT_MODAL: 13 | return action.modal; 14 | case RECEIVE_RESET_MODAL: 15 | return _nullModal; 16 | default: 17 | return state; 18 | } 19 | } 20 | 21 | export default ModalReducer; 22 | -------------------------------------------------------------------------------- /frontend/reducers/reviews_reducer.js: -------------------------------------------------------------------------------- 1 | import { merge } from 'lodash'; 2 | import { RECEIVE_ALL_REVIEWS, 3 | RECEIVE_REVIEW, 4 | RECEIVE_DESTROY, 5 | } from '../actions/review_actions'; 6 | 7 | const _nullReviews = ({ 8 | reviews: [], 9 | ratings: {}, 10 | }); 11 | 12 | const ReviewsReducer = (state = _nullReviews, action) => { 13 | Object.freeze(state); 14 | switch (action.type) { 15 | case RECEIVE_ALL_REVIEWS: 16 | const reviews = action.restaurant.reviews; 17 | const ratings = action.restaurant.ratings; 18 | return Object.assign({}, state, { reviews, ratings }); 19 | case RECEIVE_REVIEW: 20 | let newState = Object.assign({}, state) 21 | if (!(newState.reviews.includes(action.review))) { 22 | newState.reviews.push(action.review); 23 | } 24 | return newState; 25 | case RECEIVE_DESTROY: 26 | let desState = Object.assign({}, state) 27 | desState = desState.filter((rev) => rev.id !== action.id) 28 | return desState; 29 | default: 30 | return state; 31 | } 32 | } 33 | 34 | export default ReviewsReducer; 35 | -------------------------------------------------------------------------------- /frontend/reducers/root_reducer.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux'; 2 | import SessionReducer from './session_reducer'; 3 | import RestaurantsReducer from './restaurants_reducer'; 4 | import CitiesReducer from './cities_reducer'; 5 | import SearchReducer from './search_reducer'; 6 | import ReservationsReducer from './reservations_reducer'; 7 | import ReviewsReducer from './reviews_reducer'; 8 | import ModalReducer from './modal_reducer'; 9 | import FavoritesReducer from './favorites_reducer'; 10 | import ManagerReducer from './manager_reducer'; 11 | import SeatingsReducer from './seatings_reducer'; 12 | import HoursReducer from './hours_reducer'; 13 | import UserReducer from './users_reducer'; 14 | 15 | export default combineReducers({ 16 | session: SessionReducer, 17 | user: UserReducer, 18 | restaurants: RestaurantsReducer, 19 | cities: CitiesReducer, 20 | search: SearchReducer, 21 | reservations: ReservationsReducer, 22 | reviews: ReviewsReducer, 23 | modal: ModalReducer, 24 | favorites: FavoritesReducer, 25 | manager: ManagerReducer, 26 | seatings: SeatingsReducer, 27 | hours: HoursReducer, 28 | }); 29 | -------------------------------------------------------------------------------- /frontend/reducers/seatings_reducer.js: -------------------------------------------------------------------------------- 1 | import { merge } from 'lodash'; 2 | import { 3 | RECEIVE_SEATING, 4 | RECEIVE_REMOVE_SEATING, 5 | RECEIVE_SEATING_ERRORS, 6 | CLEAR_ERRORS 7 | } from '../actions/seating_actions'; 8 | import { RECEIVE_SEATINGS } from '../actions/manager_actions'; 9 | import * as SeatingsSelector from '../selectors/seatings_selectors'; 10 | 11 | const _nullSeatings = Object.freeze([]); 12 | 13 | const SeatingsReducer = (state = _nullSeatings, action) => { 14 | Object.freeze(state); 15 | switch (action.type) { 16 | case RECEIVE_SEATINGS: 17 | return SeatingsSelector.sortSeating(action.seating); 18 | case RECEIVE_SEATING: 19 | return SeatingsSelector.mergeSeating(state, action.seating); 20 | case RECEIVE_REMOVE_SEATING: 21 | return SeatingsSelector.removeSeating(state, action.seating); 22 | case RECEIVE_SEATING_ERRORS: 23 | return SeatingsSelector.mergeErrors(state, action.errors); 24 | case CLEAR_ERRORS: 25 | return SeatingsSelector.mergeErrors(state, []); 26 | default: 27 | return state; 28 | } 29 | } 30 | 31 | export default SeatingsReducer; 32 | -------------------------------------------------------------------------------- /frontend/reducers/session_reducer.js: -------------------------------------------------------------------------------- 1 | import { merge } from 'lodash'; 2 | import { RECEIVE_ADD_USER_RESERVATION } from '../actions/reservations_actions'; 3 | import * as ReservationsSelector from '../selectors/reservations_selectors'; 4 | import { 5 | RECEIVE_CURRENT_USER, 6 | RECEIVE_ERRORS, 7 | LOGOUT 8 | } from '../actions/session_actions'; 9 | 10 | const _nullUser = Object.freeze({ 11 | currentUser: { 12 | reservations: [], 13 | favorites: [], 14 | }, 15 | errors: [], 16 | }); 17 | 18 | const SessionReducer = (state = _nullUser, action) => { 19 | Object.freeze(state); 20 | switch(action.type) { 21 | case RECEIVE_CURRENT_USER: 22 | const currentUser = action.user; 23 | return merge({}, state, { currentUser }); 24 | case RECEIVE_ADD_USER_RESERVATION: 25 | const user = merge({}, state); 26 | user.currentUser.reservations.push(ReservationsSelector.formatUserReservation(action.reservation)); 27 | return user; 28 | case RECEIVE_ERRORS: 29 | const errors = action.errors; 30 | const newState = merge({}, state); 31 | newState.errors = errors; 32 | return newState; 33 | case LOGOUT: 34 | return _nullUser; 35 | default: 36 | return state; 37 | } 38 | }; 39 | 40 | export default SessionReducer; 41 | -------------------------------------------------------------------------------- /frontend/reducers/users_reducer.js: -------------------------------------------------------------------------------- 1 | import { merge } from 'lodash'; 2 | import { RECEIVE_USER, RESET_USER } from '../actions/user_actions'; 3 | 4 | const _nullUser = Object.freeze({}); 5 | 6 | const UserReducer = (state = _nullUser, action) => { 7 | Object.freeze(state); 8 | switch (action.type) { 9 | case RECEIVE_USER: 10 | return merge({}, state, action.user); 11 | case RESET_USER: 12 | return _nullUser; 13 | default: 14 | return state; 15 | } 16 | } 17 | 18 | export default UserReducer; 19 | -------------------------------------------------------------------------------- /frontend/root.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import Root from './components/root'; 4 | import configureStore from './store/store'; 5 | import { merge } from 'lodash'; 6 | import { faves } from './selectors/favorites_selector'; 7 | 8 | document.addEventListener('DOMContentLoaded', () => { 9 | let preloadedState = { 10 | session: { currentUser: {}, errors: [] }, 11 | reservations: { userReservations: [], restaurantReservations: [], currentReservation: {}}, 12 | }; 13 | 14 | if (window.currentUser) { 15 | preloadedState = merge( 16 | {}, preloadedState, { 17 | session: { currentUser: window.currentUser, errors: []}, 18 | favorites: faves(window.currentUser.favorites), 19 | reservations: { userReservations: window.currentUser.reservations }, 20 | } 21 | ); 22 | } 23 | 24 | const store = configureStore(preloadedState); 25 | const root = document.getElementById('root'); 26 | ReactDOM.render(, root); 27 | }); 28 | -------------------------------------------------------------------------------- /frontend/selectors/date_selectors.js: -------------------------------------------------------------------------------- 1 | import * as DateUtil from '../util/date_util'; 2 | 3 | export const setUpcoming = reservation => { 4 | const curDate = new Date(); 5 | const newDate = new Date(reservation.date + ' ' + DateUtil.timeToString(reservation.time)); 6 | 7 | return newDate > curDate; 8 | } 9 | -------------------------------------------------------------------------------- /frontend/selectors/favorites_selector.js: -------------------------------------------------------------------------------- 1 | export const faves = favorites => { 2 | let favs = {}; 3 | 4 | favorites.forEach(fav => { 5 | favs[fav.id] = fav; 6 | }); 7 | 8 | return favs; 9 | } 10 | 11 | export const fave = favorite => { 12 | return {[favorite.id]: favorite}; 13 | } 14 | -------------------------------------------------------------------------------- /frontend/selectors/manager_selectors.js: -------------------------------------------------------------------------------- 1 | import { merge } from 'lodash'; 2 | 3 | export const mergeHours = (state, hour) => { 4 | let hours = merge([], state); 5 | hours = hours.map(el => el.id === hour.id ? hour : el); 6 | 7 | return hours; 8 | } 9 | -------------------------------------------------------------------------------- /frontend/selectors/reservations_selectors.js: -------------------------------------------------------------------------------- 1 | import { merge } from 'lodash'; 2 | 3 | export const filterReservations = (state, id) => { 4 | const newState = merge({}, state); 5 | const arr = state.userReservations.filter(el => el.id !== id); 6 | newState.userReservations = arr; 7 | 8 | return newState; 9 | } 10 | 11 | export const formatUserReservation = reservation => { 12 | return ({ 13 | id: reservation.restaurant.id, 14 | name: reservation.restaurant.name, 15 | date: reservation.date, 16 | time: reservation.time, 17 | seats: reservation.seats, 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /frontend/selectors/review_selectors.js: -------------------------------------------------------------------------------- 1 | export const mergeReview = (reservations, review)=> { 2 | if (reservations[0]) { 3 | const idx = reservations.indexOf(reservations.find(el => el.id === review.reservation_id)); 4 | reservations[idx].reviewed = true; 5 | } 6 | 7 | return reservations; 8 | } 9 | -------------------------------------------------------------------------------- /frontend/selectors/search_selector.js: -------------------------------------------------------------------------------- 1 | export const searchSelector = restaurants => { 2 | return restaurants.map(res => { 3 | const id = Object.keys(res); 4 | return res[id]; 5 | }) 6 | }; 7 | 8 | export const restaurantFilter = (restaurants, searchTerm) => { 9 | return restaurants.filter(res => res.name.toLowerCase().indexOf(searchTerm) > -1); 10 | } 11 | 12 | export const cityFilter = (cities, searchTerm) => { 13 | return cities.filter(city => city.name.toLowerCase().indexOf(searchTerm) > -1); 14 | } 15 | -------------------------------------------------------------------------------- /frontend/selectors/seatings_selectors.js: -------------------------------------------------------------------------------- 1 | import { merge } from 'lodash'; 2 | 3 | export const mergeSeating = (state, seating) => { 4 | let newState = merge([], state); 5 | 6 | if (newState.find(el => el.id === seating.id)) { 7 | newState = newState.map(el => el.id === seating.id ? seating : el); 8 | } else { 9 | newState.push(seating); 10 | } 11 | 12 | return sortSeating(newState); 13 | } 14 | 15 | export const removeSeating = (state, seating) => { 16 | let newState = merge([], state); 17 | newState = newState.filter(el => el.id !== seating.id); 18 | 19 | return newState; 20 | } 21 | 22 | export const sortSeating = seating => seating.sort((a, b) => a.seats - b.seats); 23 | 24 | export const mergeErrors = (seating, errors) => { 25 | const newSeating = merge([], seating); 26 | newSeating.errors = errors.responseJSON; 27 | 28 | return newSeating; 29 | } 30 | -------------------------------------------------------------------------------- /frontend/store/store.js: -------------------------------------------------------------------------------- 1 | import { createStore, applyMiddleware } from 'redux'; 2 | import RootReducer from '../reducers/root_reducer'; 3 | import thunk from 'redux-thunk'; 4 | 5 | const configureStore = (preloadedState = {}) => ( 6 | createStore(RootReducer,preloadedState, applyMiddleware(thunk)) 7 | ) 8 | 9 | export default configureStore; 10 | -------------------------------------------------------------------------------- /frontend/util/city_api_util.js: -------------------------------------------------------------------------------- 1 | export const fetchAllCities = () => { 2 | return $.ajax({ 3 | method: 'GET', 4 | url: 'api/cities', 5 | }); 6 | } 7 | 8 | export const fetchCity = (query) => { 9 | return $.ajax({ 10 | method: 'GET', 11 | url: `api/restaurants`, 12 | data: query, 13 | }); 14 | } 15 | -------------------------------------------------------------------------------- /frontend/util/favorites_util.js: -------------------------------------------------------------------------------- 1 | export const createFavorite = favorite => { 2 | return $.ajax({ 3 | method: 'POST', 4 | url: `api/users/${favorite.user_id}/favorites`, 5 | data: { favorite }, 6 | }) 7 | } 8 | 9 | export const destroyFavorite = favorite => { 10 | return $.ajax({ 11 | method: 'DELETE', 12 | url: `api/users/${favorite.user_id}/favorites/${favorite.id}`, 13 | }) 14 | } 15 | -------------------------------------------------------------------------------- /frontend/util/hours_api_util.js: -------------------------------------------------------------------------------- 1 | export const fetchHour = id => { 2 | return $.ajax({ 3 | method: 'GET', 4 | url: `api/hours/${id}`, 5 | }); 6 | } 7 | 8 | export const updateHour = hour => { 9 | return $.ajax({ 10 | method: 'PATCH', 11 | url: `api/hours/${hour.id}`, 12 | data: { hour }, 13 | }); 14 | } 15 | -------------------------------------------------------------------------------- /frontend/util/manager_api_util.js: -------------------------------------------------------------------------------- 1 | export const getManagerRestaurant = id => { 2 | return $.ajax({ 3 | method: 'GET', 4 | url: `api/users/${id}/manager/${id}`, 5 | }); 6 | } 7 | 8 | export const updateRestaurant = restaurant => { 9 | return $.ajax({ 10 | method: 'PATCH', 11 | url: `api/restaurants/${restaurant.id}`, 12 | data: { restaurant }, 13 | }); 14 | } 15 | -------------------------------------------------------------------------------- /frontend/util/map_util.js: -------------------------------------------------------------------------------- 1 | export const fetchMapData = latLng => { 2 | return $.ajax({ 3 | method: 'GET', 4 | url: `http://maps.googleapis.com/maps/api/geocode/json?address=${address}`, 5 | }); 6 | } 7 | 8 | export const parseAddress = address => { 9 | address = address.split(', '); 10 | const street = address[0]; 11 | const city = [address[1], address[2]].join(', '); 12 | const country = address[3]; 13 | 14 | return { street, city, country }; 15 | } 16 | 17 | const parseLine = line => line.split(' ').join('+'); 18 | -------------------------------------------------------------------------------- /frontend/util/reservations_api_util.js: -------------------------------------------------------------------------------- 1 | export const fetchRestaurantReservations = (query) => { 2 | return $.ajax({ 3 | method: 'GET', 4 | url: 'api/seatings/search', 5 | data: { query } 6 | }); 7 | } 8 | 9 | export const fetchManagerRestaurantReservations = query => { 10 | return $.ajax({ 11 | method: 'GET', 12 | url: 'api/reservations', 13 | data: { query }, 14 | }); 15 | } 16 | 17 | export const createReservation = (reservation) => { 18 | return $.ajax({ 19 | method: 'POST', 20 | url: 'api/reservations', 21 | data: {reservation} 22 | }); 23 | } 24 | 25 | export const deleteReservation = (reservation_id) => { 26 | return $.ajax({ 27 | method: 'DELETE', 28 | url: 'api/restaurants/:restaurant_id/reservations/:id' 29 | }); 30 | } 31 | 32 | export const deleteUserReservation = id => { 33 | return $.ajax({ 34 | method: 'DELETE', 35 | url: `api/reservations/${id}`, 36 | }); 37 | } 38 | -------------------------------------------------------------------------------- /frontend/util/restaurant_api_util.js: -------------------------------------------------------------------------------- 1 | export const fetchAllRestaurants = (cityId) => { 2 | return $.ajax({ 3 | method: 'GET', 4 | url: `api/restaurants`, 5 | dataType: 'json', 6 | data: {cityId}, 7 | }); 8 | } 9 | 10 | export const createRestaurant = (restaurant) => { 11 | return $.ajax({ 12 | method: 'POST', 13 | url: 'api/restaurants', 14 | dataType: 'json', 15 | contentType: false, 16 | processData: false, 17 | data: restaurant, 18 | }); 19 | } 20 | 21 | export const fetchRestaurant = (id) => { 22 | return $.ajax({ 23 | method: 'GET', 24 | url: `api/restaurants/${id}` 25 | }); 26 | } 27 | 28 | export const updateRestaurant = (restaurant) => { 29 | return $.ajax({ 30 | method: 'PATCH', 31 | url: `api/restaurants/${restaurant.id}`, 32 | data: {restaurant} 33 | }); 34 | } 35 | 36 | export const deleteRestaurant = (id) => { 37 | return $.ajax({ 38 | method: 'DELETE', 39 | url: `api/restaurants/${id}` 40 | }); 41 | } 42 | -------------------------------------------------------------------------------- /frontend/util/review_api_util.js: -------------------------------------------------------------------------------- 1 | export const fetchAllReviews = (restaurant_id) => { 2 | return $.ajax({ 3 | method: 'GET', 4 | url: `/api/reviews`, 5 | data: {restaurant_id}, 6 | }) 7 | } 8 | 9 | export const fetchReview = (id) => { 10 | return $.ajax({ 11 | method: 'GET', 12 | url: `/api/reviews/${id}`, 13 | }) 14 | } 15 | 16 | export const createReview = (review) => { 17 | return $.ajax({ 18 | method: 'POST', 19 | url: `/api/reviews`, 20 | data: {review} 21 | }) 22 | } 23 | 24 | export const destroyReview = (id) => { 25 | return $.ajax({ 26 | method: 'DELETE', 27 | url: `/api/restaurants/:restaurant_id/reviews/${id}` 28 | }) 29 | } 30 | -------------------------------------------------------------------------------- /frontend/util/search_api_util.js: -------------------------------------------------------------------------------- 1 | export const searchRestaurants = (query) => { 2 | return $.ajax({ 3 | method: 'GET', 4 | url: 'api/restaurants/search', 5 | data: {query}, 6 | }) 7 | } 8 | -------------------------------------------------------------------------------- /frontend/util/seatings_api_util.js: -------------------------------------------------------------------------------- 1 | export const updateSeating = seating => { 2 | return $.ajax({ 3 | method: 'Patch', 4 | url: `api/seatings/${seating.id}`, 5 | data: seating, 6 | }); 7 | } 8 | 9 | export const createSeating = seating => { 10 | return $.ajax({ 11 | method: 'POST', 12 | url: 'api/seatings', 13 | data: seating, 14 | }) 15 | } 16 | 17 | export const removeSeating = id => { 18 | return $.ajax({ 19 | method: 'DELETE', 20 | url: `api/seatings/${id}`, 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /frontend/util/session_api_util.js: -------------------------------------------------------------------------------- 1 | export const signup = (user) => ( 2 | $.ajax({ 3 | method: 'POST', 4 | url: 'api/users', 5 | data: {user} 6 | }) 7 | ) 8 | 9 | export const login = (user) => ( 10 | $.ajax({ 11 | method: 'POST', 12 | url: 'api/session', 13 | data: {user} 14 | }) 15 | ) 16 | 17 | export const logout = () => ( 18 | $.ajax({ 19 | method: 'DELETE', 20 | url: 'api/session' 21 | }) 22 | ) 23 | -------------------------------------------------------------------------------- /frontend/util/user_api_util.js: -------------------------------------------------------------------------------- 1 | export const getUser = id => { 2 | return $.ajax({ 3 | method: 'GET', 4 | url: `api/users/${id}`, 5 | }); 6 | } 7 | -------------------------------------------------------------------------------- /lib/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/lib/assets/.keep -------------------------------------------------------------------------------- /lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/lib/tasks/.keep -------------------------------------------------------------------------------- /log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/log/.keep -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "HelloTable", 3 | "version": "1.0.0", 4 | "description": "== README", 5 | "main": "index.js", 6 | "directories": { 7 | "doc": "docs", 8 | "test": "test" 9 | }, 10 | "engines": { 11 | "node": "7.9.0", 12 | "npm": "4.2.0" 13 | }, 14 | "scripts": { 15 | "test": "echo \"Error: no test specified\" && exit 1", 16 | "webpack": "webpack --watch", 17 | "postinstall": "webpack" 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/zhuo-ch/HelloTable.git" 22 | }, 23 | "keywords": [], 24 | "author": "", 25 | "license": "ISC", 26 | "bugs": { 27 | "url": "https://github.com/zhuo-ch/HelloTable/issues" 28 | }, 29 | "homepage": "https://github.com/zhuo-ch/HelloTable#readme", 30 | "dependencies": { 31 | "babel-core": "^6.2.0", 32 | "babel-loader": "^6.2.0", 33 | "babel-preset-es2015": "^6.9.0", 34 | "babel-preset-react": "^6.1.18", 35 | "lodash": "^4.15.0", 36 | "react": "^0.14.2", 37 | "react-dom": "^0.14.2", 38 | "react-fontawesome": "^1.6.1", 39 | "react-redux": "^4.4.5", 40 | "react-router": "3.0.5", 41 | "react-scrollchor": "^2.2.0", 42 | "react-stars": "^2.1.0", 43 | "react-sticky": "^5.0.8", 44 | "redux": "^3.5.2", 45 | "redux-thunk": "^2.1.0", 46 | "webpack": "^2.3.3" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/public/favicon.ico -------------------------------------------------------------------------------- /public/images/hello-table-full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/public/images/hello-table-full.png -------------------------------------------------------------------------------- /public/images/logo-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/public/images/logo-3.png -------------------------------------------------------------------------------- /public/images/red-wine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/public/images/red-wine.png -------------------------------------------------------------------------------- /public/images/restaurant-show.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/public/images/restaurant-show.png -------------------------------------------------------------------------------- /public/images/spl1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/public/images/spl1.jpg -------------------------------------------------------------------------------- /public/images/spl2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/public/images/spl2.jpg -------------------------------------------------------------------------------- /public/images/spl3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/public/images/spl3.jpg -------------------------------------------------------------------------------- /public/images/user-show.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/public/images/user-show.png -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /test/controllers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/test/controllers/.keep -------------------------------------------------------------------------------- /test/controllers/api/cities_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class Api::CitiesControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/controllers/api/favorites_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class Api::FavoritesControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/controllers/api/hours_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class Api::HoursControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/controllers/api/reservations_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class Api::ReservationsControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/controllers/api/restaurant_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class Api::RestaurantControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/controllers/api/restaurants_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class Api::RestaurantsControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/controllers/api/reviews_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class Api::ReviewsControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/controllers/api/seatings_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class Api::SeatingsControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/controllers/api/sessions_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class Api::SessionsControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/controllers/api/users_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class Api::UsersControllerTest < ActionController::TestCase 4 | 5 | def create 6 | @user = User.new(user_params) 7 | 8 | if @user.save 9 | login(@user) 10 | render "api/users/show" 11 | else 12 | render json: @user.errors.full_messages, status: 422 13 | end 14 | end 15 | 16 | private 17 | def user_params 18 | params.require(:user).permit(:username, :password, :email) 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /test/controllers/static_pages_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class StaticPagesControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/controllers/staticpages_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class StaticpagesControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/fixtures/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/test/fixtures/.keep -------------------------------------------------------------------------------- /test/fixtures/cities.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/favorites.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/hours.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/photos.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/ratings.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/reservations.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/restaurants.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/reviews.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/seatings.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/users.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/helpers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/test/helpers/.keep -------------------------------------------------------------------------------- /test/integration/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/test/integration/.keep -------------------------------------------------------------------------------- /test/mailers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/test/mailers/.keep -------------------------------------------------------------------------------- /test/models/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/test/models/.keep -------------------------------------------------------------------------------- /test/models/city_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class CityTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/favorite_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class FavoriteTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/hour_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class HourTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/photo_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class PhotoTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/rating_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RatingTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/reservation_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ReservationTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/restaurant_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RestaurantTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/review_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ReviewTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/seating_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class SeatingTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/user_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class UserTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV['RAILS_ENV'] ||= 'test' 2 | require File.expand_path('../../config/environment', __FILE__) 3 | require 'rails/test_help' 4 | 5 | class ActiveSupport::TestCase 6 | # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. 7 | fixtures :all 8 | 9 | # Add more helper methods to be used by all tests here... 10 | end 11 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/vendor/assets/javascripts/.keep -------------------------------------------------------------------------------- /vendor/assets/stylesheets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuo-ch/HelloTable/0d7172a510a7dfb0f95fa99df4a32cc1c161a93a/vendor/assets/stylesheets/.keep -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | 4 | module.exports = { 5 | entry: './frontend/root.jsx', 6 | output: { 7 | path: path.resolve(__dirname, 'app', 'assets', 'javascripts'), 8 | filename: './bundle.js', 9 | }, 10 | module: { 11 | loaders: [ 12 | { 13 | test: [/\.jsx?$/], 14 | exclude: /(node_modules)/, 15 | loader: 'babel-loader', 16 | query: { 17 | presets: ['es2015', 'react'] 18 | } 19 | } 20 | ] 21 | }, 22 | devtool: 'source-map', 23 | resolve: { 24 | extensions: ['.js', '.jsx', '*'] 25 | }, 26 | plugins: [ 27 | new webpack.DefinePlugin({ 28 | 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) 29 | }), 30 | ] 31 | }; 32 | --------------------------------------------------------------------------------