diff --git a/api/base/requirements.txt b/api/base/requirements.txt index d8e05d03..7e4bb917 100644 --- a/api/base/requirements.txt +++ b/api/base/requirements.txt @@ -19,7 +19,6 @@ pytz==2016.10 # graphene-django==1.3 git+https://github.com/graphql-python/graphene-django.git@2929d0866c800ae6efa8d35bb40548940a70c31f -graphene==1.4.1 git+git://github.com/RyanNoelk/recipe-scraper.git@1.0.7 # Will need these once I start supporting metric mesurments diff --git a/api/v1/list/schema.py b/api/v1/list/schema.py index b4680028..51df7fd9 100644 --- a/api/v1/list/schema.py +++ b/api/v1/list/schema.py @@ -31,7 +31,6 @@ def get_node(cls, id, context, info): class GroceryItemNode(DjangoObjectType): class Meta: model = GroceryItem - filter_fields = ['slug', 'list__id'] interfaces = (graphene.relay.Node, ) @classmethod diff --git a/docs/Running_without_Docker.md b/docs/Running_without_Docker.md index b3b20f4e..7e476dcd 100644 --- a/docs/Running_without_Docker.md +++ b/docs/Running_without_Docker.md @@ -1,7 +1,5 @@ ## Running OpenEats -#### Warning! This docs are outdated. The recommended way to install OpenEats is via docker. - * `git clone https://github.com/RyanNoelk/openeats.git` * `cd openeats/api` * `git checkout dev` diff --git a/env_dev.list b/env_dev.list index ea22ba3c..b46f1a6c 100644 --- a/env_dev.list +++ b/env_dev.list @@ -8,6 +8,7 @@ API_PORT=8000 DJANGO_SECRET_KEY=sdfsadfas32e98zsdvhhsnz6udvbksjdhfi4galshjfg DJANGO_SETTINGS_MODULE=base.settings DJANGO_DEBUG=True +ALLOWED_HOST='' # If you are serving content behind an HTTPS proxy, # Set this to `true`. diff --git a/env_stg.list b/env_stg.list index b6f40ce3..91bb21af 100644 --- a/env_stg.list +++ b/env_stg.list @@ -8,7 +8,7 @@ API_PORT=8000 DJANGO_SECRET_KEY=sdfsadfas32e98zsdvhhsnz6udvbksjdhfi4galshjfg DJANGO_SETTINGS_MODULE=base.settings DJANGO_DEBUG=False -ALLOWED_HOST=localhost +ALLOWED_HOST='' # If you are serving content behind an HTTPS proxy, # Set this to `true`. diff --git a/frontend/.babelrc b/frontend/.babelrc index 8b9271cd..ec58d223 100644 --- a/frontend/.babelrc +++ b/frontend/.babelrc @@ -1,7 +1,6 @@ { "presets": [ "es2015", - "stage-0", "react" ], "plugins": [ diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 255e40c7..7827ddc9 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,4 +1,4 @@ -FROM node:8.6.0-alpine +FROM node:8.3.0-alpine # Create app directory RUN mkdir /code diff --git a/frontend/jest_mocks/createComponentWithIntlAndRouter.js b/frontend/jest_mocks/createComponentWithIntlAndRouter.js deleted file mode 100644 index 2943f54c..00000000 --- a/frontend/jest_mocks/createComponentWithIntlAndRouter.js +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react'; -import renderer from 'react-test-renderer'; -import { IntlProvider } from 'react-intl'; -import { MemoryRouter } from 'react-router-dom' - -const createComponentWithIntl = (children, props = { locale: 'en' }) => { - return renderer.create( - - - { children } - - - ); -}; - -export default createComponentWithIntl; \ No newline at end of file diff --git a/frontend/jest_mocks/createComponentWithRouter.js b/frontend/jest_mocks/createComponentWithRouter.js deleted file mode 100644 index e65e77a3..00000000 --- a/frontend/jest_mocks/createComponentWithRouter.js +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; -import renderer from 'react-test-renderer'; -import { MemoryRouter } from 'react-router-dom' - -const createComponentWithRouter = ( children ) => { - return renderer.create( - - { children } - - ); -}; - -export default createComponentWithRouter; \ No newline at end of file diff --git a/frontend/locale/de.json b/frontend/locale/de.json index 9b6860e5..8067c476 100644 --- a/frontend/locale/de.json +++ b/frontend/locale/de.json @@ -1,10 +1,10 @@ { - "login.alert.unable_to_login": "Das Einloggen war nicht erfolgreich!", - "login.alert.confirm": "Bitte stellen Sie sicher, dass Ihr Benutzername und Passwort richtig sind.", "login.please_sign_in": "Bitte einloggen.", "login.username": "Benutzername", "login.password": "Passwort", "login.sign_in": "Einloggen", + "login.alert.unable_to_login": "Das Einloggen war nicht erfolgreich!", + "login.alert.confirm": "Bitte stellen Sie sicher, dass Ihr Benutzername und Passwort richtig sind.", "404.header": "Unsere Köche haben das Rezept in der Testküche versaut, bitte versuchen Sie etwas anderes.", "404.message": "Entschuldigung! Ein 404 Fehler ist aufgetreten, wir können nicht finden wonach Sie suchen.", "footer.credit": "Erstellt mit {link}", @@ -32,16 +32,14 @@ "nav.brand": "OpenEats", "nav.news": "News", "nav.recipes": "Rezepte durchsuchen", - "list.new-input-placeholder": "Was benötigen Sie noch?", - "list.error.message": "Something went wrong!", "grocery_list.my_lists": "Meine Listen", "grocery_list.footer": "Doppelklicken Sie auf einen Eintrag, um diesen zu verändern.", + "list.new-input-placeholder": "Was benötigen Sie noch?", "list.footer.items_left": "{itemCount, plural, =0 {Keine Einträge übrig} one {1 Eintrag übrig} other {{itemCount} Einträge übrig}}", "list.footer.all": "Alle", "list.footer.completed": "Fertig", "list.footer.active": "Offen", "list.footer.clear_completed": "Fertige Einträge löschen", - "list_header.confirm_delete": "Are you sure you want to delete this list?", "my_lists.no_lists": "Keine Listen vorhanden", "my_lists.new_list": "Erstelle eine neue Liste!", "new_list.header": "Erstelle eine neue Liste", @@ -96,17 +94,14 @@ "recipe.create.photo_label": "Foto", "recipe.create.photo_placeholder": "Foto", "recipe.create.submit": "Rezept anlegen", + "recipe.edit_recipe": "Rezept ändern", "recipe.servings": "Portionen", "recipe.prep_time": "Vorbereitungszeit", "recipe.cooking_time": "Kochzeit", - "recipe.minutes": "Minuten", - "recipe.recipe_ingredient_button.save": "Add To", - "recipe.recipe_ingredient_button.check_all": "Check All", - "recipe.recipe_ingredient_button.clear": "Clear", + "recipe.ingredients": "Zutaten", + "recipe.directions": "Anweisungen", "recipe.source": "Quelle", "recipe.created_by": "Erstellt von", "recipe.last_updated": "Letzte Bearbeitung", - "recipe.edit_recipe": "Rezept ändern", - "recipe.ingredients": "Zutaten", - "recipe.directions": "Anweisungen" -} \ No newline at end of file + "recipe.minutes": "Minuten" +} diff --git a/frontend/locale/en.json b/frontend/locale/en.json index 0f023f76..0953fa93 100644 --- a/frontend/locale/en.json +++ b/frontend/locale/en.json @@ -1,10 +1,10 @@ { - "login.alert.unable_to_login": "Unable to login!", - "login.alert.confirm": "Please confirm that the username and password are correct.", "login.please_sign_in": "Please sign in", "login.username": "Username", "login.password": "Password", "login.sign_in": "Sign in", + "login.alert.unable_to_login": "Unable to login!", + "login.alert.confirm": "Please confirm that the username and password are correct.", "404.header": "Our chef's ruined this recipe in the test kitchen, we suggest you try something else.", "404.message": "Sorry the page came back with a 404 error we can't find what you are looking for.", "footer.credit": "Created with {link}", @@ -32,16 +32,14 @@ "nav.brand": "OpenEats", "nav.news": "News", "nav.recipes": "Browse recipes", - "list.new-input-placeholder": "What else do you need?", - "list.error.message": "Something went wrong!", "grocery_list.my_lists": "My Lists", "grocery_list.footer": "Double Click to edit an item.", + "list.new-input-placeholder": "What else do you need?", "list.footer.items_left": "{itemCount, plural, =0 {No items} one {1 item left} other {{itemCount} items left}}", "list.footer.all": "All", "list.footer.completed": "Completed", "list.footer.active": "Active", "list.footer.clear_completed": "Clear completed", - "list_header.confirm_delete": "Are you sure you want to delete this list?", "my_lists.no_lists": "No lists to display", "my_lists.new_list": "Create a new list!", "new_list.header": "Create a new list", @@ -96,17 +94,14 @@ "recipe.create.photo_label": "Photo", "recipe.create.photo_placeholder": "Photo", "recipe.create.submit": "Submit recipe", + "recipe.edit_recipe": "Edit recipe", "recipe.servings": "Servings", "recipe.prep_time": "Prep time", "recipe.cooking_time": "Cooking time", - "recipe.minutes": "minutes", - "recipe.recipe_ingredient_button.save": "Add To", - "recipe.recipe_ingredient_button.check_all": "Check All", - "recipe.recipe_ingredient_button.clear": "Clear", + "recipe.ingredients": "Ingredients", + "recipe.directions": "Directions", "recipe.source": "Source", "recipe.created_by": "Created by", "recipe.last_updated": "Last edit", - "recipe.edit_recipe": "Edit recipe", - "recipe.ingredients": "Ingredients", - "recipe.directions": "Directions" -} \ No newline at end of file + "recipe.minutes": "minutes" +} diff --git a/frontend/locale/es.json b/frontend/locale/es.json index 465d2e38..dc4cb2da 100644 --- a/frontend/locale/es.json +++ b/frontend/locale/es.json @@ -1,10 +1,10 @@ { - "login.alert.unable_to_login": "Identificación fallida!", - "login.alert.confirm": "Asegurese de que su nombre de usuario y contraseña sean correctos.", "login.please_sign_in": "Identifiquese por favor", "login.username": "Nombre de usuario", "login.password": "Contraseña", "login.sign_in": "Identifiquese", + "login.alert.unable_to_login": "Identificación fallida!", + "login.alert.confirm": "Asegurese de que su nombre de usuario y contraseña sean correctos.", "404.header": "Nuestro chef no ha podido preparar esta receta, te sugerimos que intentes buscar otra cosa.", "404.message": "No hemos podido encontrar lo que buscas.", "footer.credit": "Creado con {link}", @@ -32,16 +32,14 @@ "nav.brand": "OpenEats", "nav.news": "Noticias", "nav.recipes": "Recetas", - "list.new-input-placeholder": "¿Qué necesito comprar?", - "list.error.message": "Something went wrong!", "grocery_list.my_lists": "Mis listas", "grocery_list.footer": "Haga doble click para modificar ", + "list.new-input-placeholder": "¿Qué necesito comprar?", "list.footer.items_left": "{itemCount, plural, =0 {No quedan productos} one {Queda un producto} other {Quedan {itemCount} productos}}", "list.footer.all": "Todos", "list.footer.completed": "Completados", "list.footer.active": "Pendientes", "list.footer.clear_completed": "Borrar completado", - "list_header.confirm_delete": "Are you sure you want to delete this list?", "my_lists.no_lists": "No hay listas para mostrar", "my_lists.new_list": "Crear una nueva lista", "new_list.header": "Crear una nueva lista", @@ -96,17 +94,14 @@ "recipe.create.photo_label": "Foto", "recipe.create.photo_placeholder": "Foto", "recipe.create.submit": "Guardar receta", + "recipe.edit_recipe": "Modificar receta", "recipe.servings": "Sirve", "recipe.prep_time": "Tiempo de preparación", "recipe.cooking_time": "Tiempo de cocción", - "recipe.minutes": "minutos", - "recipe.recipe_ingredient_button.save": "Add To", - "recipe.recipe_ingredient_button.check_all": "Check All", - "recipe.recipe_ingredient_button.clear": "Clear", + "recipe.ingredients": "Ingredientes", + "recipe.directions": "Instrucciones", "recipe.source": "La Fuento", "recipe.created_by": "Creado por", "recipe.last_updated": "Modificado", - "recipe.edit_recipe": "Modificar receta", - "recipe.ingredients": "Ingredientes", - "recipe.directions": "Instrucciones" -} \ No newline at end of file + "recipe.minutes": "minutos" +} diff --git a/frontend/modules/account/components/Alert.js b/frontend/modules/account/components/Alert.js deleted file mode 100644 index 758cd513..00000000 --- a/frontend/modules/account/components/Alert.js +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react' -import { - injectIntl, - defineMessages -} from 'react-intl'; - - -const Alert = ({ intl }) => { - const messages = defineMessages({ - title: { - id: 'login.alert.unable_to_login', - description: 'Fail to login header', - defaultMessage: 'Unable to login!', - }, - message: { - id: 'login.alert.confirm', - description: 'Fail to login message', - defaultMessage: 'Please confirm that the username and password are correct.', - } - }); - - return ( -
- { intl.formatMessage(messages.title) } - { intl.formatMessage(messages.message) } -
- ) -}; - -export default injectIntl(Alert) diff --git a/frontend/modules/account/components/Login.js b/frontend/modules/account/components/Login.js index d653de4f..bb50760a 100644 --- a/frontend/modules/account/components/Login.js +++ b/frontend/modules/account/components/Login.js @@ -5,10 +5,9 @@ import { defineMessages, formatMessage } from 'react-intl'; - +import { browserHistory } from 'react-router' import AuthActions from '../actions/AuthActions'; import AuthStore from '../stores/AuthStore'; -import Alert from './Alert' // Load in the base CSS require("./../css/login.scss"); @@ -20,36 +19,34 @@ function getAuthErrors() { }; } -class Login extends React.Component { - constructor(props) { - super(props); - - this.state = getAuthErrors(); - } +export default injectIntl(React.createClass({ + getInitialState: function() { + return getAuthErrors(); + }, - componentDidMount() { + componentDidMount: function() { if (AuthStore.isAuthenticated()) { - this.props.history.push('/'); + browserHistory.push('/'); } AuthStore.addChangeListener(this._onChange); - } + }, - componentWillUnmount() { + componentWillUnmount: function() { AuthStore.removeChangeListener(this._onChange); - } + }, - _onChange = () => { + _onChange: function() { this.setState(getAuthErrors()); - }; + }, - handleSubmit = e => { + handleSubmit: function(e) { e.preventDefault(); - let username = this.refs.username.value; - let pass = this.refs.pass.value; + var username = this.refs.username.value; + var pass = this.refs.pass.value; AuthActions.getToken(username, pass); - }; + }, + render: function() { - render() { const {formatMessage} = this.props.intl; const messages = defineMessages({ please_sign_in: { @@ -84,6 +81,29 @@ class Login extends React.Component { ) } -} +})); + +var Alert = injectIntl(React.createClass({ + render: function() { -export default injectIntl(Login) + const {formatMessage} = this.props.intl; + const messages = defineMessages({ + title: { + id: 'login.alert.unable_to_login', + description: 'Fail to login header', + defaultMessage: 'Unable to login!', + }, + message: { + id: 'login.alert.confirm', + description: 'Fail to login message', + defaultMessage: 'Please confirm that the username and password are correct.', + } + }); + + return ( +
+ { formatMessage(messages.title) } { formatMessage(messages.message) } +
+ ) + } +})); \ No newline at end of file diff --git a/frontend/modules/account/stores/AuthStore.js b/frontend/modules/account/stores/AuthStore.js index 5e8f9f15..a25012cf 100644 --- a/frontend/modules/account/stores/AuthStore.js +++ b/frontend/modules/account/stores/AuthStore.js @@ -1,7 +1,7 @@ import AppDispatcher from '../../common/AppDispatcher'; import AuthConstants from '../constants/AuthConstants'; import { EventEmitter } from 'events'; -import history from '../../common/history' +import { browserHistory } from 'react-router' const CHANGE_EVENT = 'change'; @@ -63,7 +63,7 @@ AuthStore.dispatchToken = AppDispatcher.register(action => { case AuthConstants.LOGIN_USER: setUser(action.user); AuthStore.emitChange(); - history.push('/'); + browserHistory.push('/'); break; case AuthConstants.LOGIN_ERROR: @@ -74,7 +74,7 @@ AuthStore.dispatchToken = AppDispatcher.register(action => { case AuthConstants.LOGOUT_USER: removeUser(); AuthStore.emitChange(); - history.push('/'); + browserHistory.push('/'); break; default: diff --git a/frontend/modules/base/components/404.js b/frontend/modules/base/components/404.js new file mode 100644 index 00000000..d0168066 --- /dev/null +++ b/frontend/modules/base/components/404.js @@ -0,0 +1,36 @@ +import React from 'react' +import { + injectIntl, + IntlProvider, + defineMessages, + formatMessage +} from 'react-intl'; + +require("../css/404.scss"); + +export default injectIntl(React.createClass({ + render: function() { + + const {formatMessage} = this.props.intl; + const messages = defineMessages({ + header: { + id: '404.header', + description: '404 Header', + defaultMessage: 'Our chef\'s ruined this recipe in the test kitchen, we suggest you try something else', + }, + message: { + id: '404.message', + description: '404 Message', + defaultMessage: 'Sorry the page came back with a 404 error we can\'t find what you are looking for', + } + }); + + return ( +
+

{formatMessage(messages.header)}

+ 404 image +

{formatMessage(messages.message)}

+
+ ); + } +})); diff --git a/frontend/modules/base/components/App.js b/frontend/modules/base/components/App.js new file mode 100644 index 00000000..7af7377d --- /dev/null +++ b/frontend/modules/base/components/App.js @@ -0,0 +1,14 @@ +import React from 'react' + +import Nav from '../../header/components/Nav' + +export default React.createClass({ + render: function() { + return ( +
+
+ ); + } +}); diff --git a/frontend/modules/base/components/Footer.js b/frontend/modules/base/components/Footer.js index bb1a1595..ffb2c516 100644 --- a/frontend/modules/base/components/Footer.js +++ b/frontend/modules/base/components/Footer.js @@ -38,4 +38,8 @@ class Footer extends React.Component{ } } +Footer.propTypes = { + intl: intlShape.isRequired, +}; + export default injectIntl(Footer); diff --git a/frontend/modules/base/components/Loading.js b/frontend/modules/base/components/Loading.js deleted file mode 100755 index 54b8d555..00000000 --- a/frontend/modules/base/components/Loading.js +++ /dev/null @@ -1,20 +0,0 @@ -"use strict"; - -import React from 'react' -import PropTypes from 'prop-types' -import Spinner from 'react-spinkit'; - -const Loading = ({ message }) => { - return ( -
-

{ message }

- -
- ); -}; - -Loading.propTypes = { - message: PropTypes.string, -}; - -export default Loading diff --git a/frontend/modules/base/components/NotFound.js b/frontend/modules/base/components/NotFound.js deleted file mode 100644 index 087a99f5..00000000 --- a/frontend/modules/base/components/NotFound.js +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react' -import { - injectIntl, - IntlProvider, - defineMessages, - formatMessage -} from 'react-intl'; - -require("../css/404.scss"); - -const NotFound = ({ intl }) => { - const messages = defineMessages({ - header: { - id: '404.header', - description: '404 Header', - defaultMessage: 'Our chef\'s ruined this recipe in the test kitchen, we suggest you try something else', - }, - message: { - id: '404.message', - description: '404 Message', - defaultMessage: 'Sorry the page came back with a 404 error we can\'t find what you are looking for', - } - }); - - return ( -
-

{ intl.formatMessage(messages.header) }

- 404 image -

{ intl.formatMessage(messages.message) }

-
- ); -}; - -export default injectIntl(NotFound) \ No newline at end of file diff --git a/frontend/modules/base/css/core.css b/frontend/modules/base/css/core.css index 9b8098b3..c538ca94 100644 --- a/frontend/modules/base/css/core.css +++ b/frontend/modules/base/css/core.css @@ -7,7 +7,7 @@ html { body { /* Margin bottom by footer height */ - margin-bottom: 80px; + margin-bottom: 60px; } .navbar { diff --git a/frontend/modules/browse/actions/BrowseActions.js b/frontend/modules/browse/actions/BrowseActions.js index 268a86bb..7ca44d39 100644 --- a/frontend/modules/browse/actions/BrowseActions.js +++ b/frontend/modules/browse/actions/BrowseActions.js @@ -1,6 +1,6 @@ import AppDispatcher from '../../common/AppDispatcher'; import Api from '../../common/Api'; -import history from '../../common/history' +import { browserHistory } from 'react-router' import DefaultFilters from '../constants/DefaultFilters' const BrowseActions = { @@ -29,7 +29,6 @@ const BrowseActions = { }, updateURL: function(filter) { - // TODO: use https://github.com/sindresorhus/query-string let encode_data = []; for (let key in filter) { if (filter[key]) { @@ -44,7 +43,7 @@ const BrowseActions = { path += '?' + encode_data.join('&'); } - history.push(path); + browserHistory.push(path); }, processLoadedRecipes: function(err, res) { diff --git a/frontend/modules/browse/components/Browse.js b/frontend/modules/browse/components/Browse.js index 93cb0a96..463804ab 100644 --- a/frontend/modules/browse/components/Browse.js +++ b/frontend/modules/browse/components/Browse.js @@ -1,8 +1,6 @@ import React from 'react' import classNames from 'classnames'; import SmoothCollapse from 'react-smooth-collapse'; -import queryString from 'query-string'; - import { injectIntl, IntlProvider, @@ -66,7 +64,7 @@ class Browse extends React.Component { CuisineStore.addChangeListener(this._onChangeCuisines); RatingStore.addChangeListener(this._onChangeRatings); - BrowseActions.browseInit(queryString.parse(this.props.location.search)); + BrowseActions.browseInit(this.props.location.query); } componentWillUnmount() { @@ -77,20 +75,18 @@ class Browse extends React.Component { } componentWillReceiveProps(nextProps) { - let query = queryString.parse(this.props.location.search); - let nextQuery = queryString.parse(nextProps.location.search); - if (query.offset !== nextQuery.offset) { - BrowseActions.loadRecipes(nextQuery); - } else if (query.offset !== nextQuery.offset) { - this.reloadData(nextQuery); - } else if (query.course !== nextQuery.course) { - this.reloadData(nextQuery); - } else if (query.cuisine !== nextQuery.cuisine) { - this.reloadData(nextQuery); - } else if (query.rating !== nextQuery.rating) { - this.reloadData(nextQuery); - } else if (query.search !== nextQuery.search) { - this.reloadData(nextQuery); + if (this.props.location.query.offset !== nextProps.location.query.offset) { + BrowseActions.loadRecipes(nextProps.location.query); + } else if (this.props.location.query.offset !== nextProps.location.query.offset) { + this.reloadData(nextProps.location.query); + } else if (this.props.location.query.course !== nextProps.location.query.course) { + this.reloadData(nextProps.location.query); + } else if (this.props.location.query.cuisine !== nextProps.location.query.cuisine) { + this.reloadData(nextProps.location.query); + } else if (this.props.location.query.rating !== nextProps.location.query.rating) { + this.reloadData(nextProps.location.query); + } else if (this.props.location.query.search !== nextProps.location.query.search) { + this.reloadData(nextProps.location.query); } } diff --git a/frontend/modules/browse/components/ListRecipes.js b/frontend/modules/browse/components/ListRecipes.js index 690b8acb..409c60b0 100644 --- a/frontend/modules/browse/components/ListRecipes.js +++ b/frontend/modules/browse/components/ListRecipes.js @@ -1,6 +1,6 @@ import React from 'react' import PropTypes from 'prop-types'; -import { Link } from 'react-router-dom' +import { Link } from 'react-router' import Ratings from '../../recipe/components/Ratings'; diff --git a/frontend/modules/browse/stores/BrowseStore.js b/frontend/modules/browse/stores/BrowseStore.js index 54c23e6e..18c0b563 100644 --- a/frontend/modules/browse/stores/BrowseStore.js +++ b/frontend/modules/browse/stores/BrowseStore.js @@ -48,4 +48,8 @@ class BrowseStore extends EventEmitter { } }; +BrowseStore.propTypes = { + AppDispatcher: React.PropTypes.objectOf(AppDispatcher).isRequired +}; + module.exports = new BrowseStore(AppDispatcher); \ No newline at end of file diff --git a/frontend/modules/browse/stores/FilterStores.js b/frontend/modules/browse/stores/FilterStores.js index 97310751..52b38dc4 100644 --- a/frontend/modules/browse/stores/FilterStores.js +++ b/frontend/modules/browse/stores/FilterStores.js @@ -57,6 +57,11 @@ class FilterStore extends EventEmitter { } }; +FilterStore.propTypes = { + AppDispatcher: React.PropTypes.objectOf(AppDispatcher).isRequired, + name: React.PropTypes.string.isRequired +}; + module.exports.CuisineStore = new FilterStore(AppDispatcher, 'cuisine'); module.exports.CourseStore = new FilterStore(AppDispatcher, 'course'); module.exports.RatingStore = new FilterStore(AppDispatcher, 'rating'); \ No newline at end of file diff --git a/frontend/modules/common/authCheckRedirect.js b/frontend/modules/common/authCheckRedirect.js deleted file mode 100644 index abb75bd7..00000000 --- a/frontend/modules/common/authCheckRedirect.js +++ /dev/null @@ -1,10 +0,0 @@ -import AuthStore from '../account/stores/AuthStore' -import history from './history' - -const authCheckRedirect = () => { - if (!AuthStore.isAuthenticated()) { - history.replace('/login'); - } -}; - -export default authCheckRedirect diff --git a/frontend/modules/common/bindIndexToActionCreators.js b/frontend/modules/common/bindIndexToActionCreators.js deleted file mode 100644 index fc2cba19..00000000 --- a/frontend/modules/common/bindIndexToActionCreators.js +++ /dev/null @@ -1,13 +0,0 @@ - -const bindActionCreator = (actionCreator, index) => - (...args) => actionCreator(...args, index); - -const bindIndexToActionCreators = (actionCreators, index) => { - let transformed = {}; - Object.keys(actionCreators).forEach(key => { - transformed[key] = bindActionCreator(actionCreators[key], index) - }); - return transformed; -}; - -export default bindIndexToActionCreators \ No newline at end of file diff --git a/frontend/modules/common/form/FormComponents.js b/frontend/modules/common/form/FormComponents.js index 0ec62ad6..eaffa140 100644 --- a/frontend/modules/common/form/FormComponents.js +++ b/frontend/modules/common/form/FormComponents.js @@ -150,18 +150,17 @@ class Checkbox extends BaseComponent { super(props); this.state = { - checked: !!this.props.checked + checked: this.props.checked || true }; } handleChange(event) { - let checked = !this.state.checked; this.setState({ - checked: checked + checked: this.state.checked === true ? 1 : 0 }); if(this.props.change) { - this.props.change(event.target.name, checked); + this.props.change(event.target.name, new_value); } } @@ -177,12 +176,13 @@ class Checkbox extends BaseComponent { return (
- - { this.props.placeholder } +
) diff --git a/frontend/modules/common/history.js b/frontend/modules/common/history.js deleted file mode 100644 index 3247f6c8..00000000 --- a/frontend/modules/common/history.js +++ /dev/null @@ -1,5 +0,0 @@ -import { createBrowserHistory } from 'history' - -export default createBrowserHistory({ - /* pass a configuration object here if needed */ -}) \ No newline at end of file diff --git a/frontend/modules/common/reducer.js b/frontend/modules/common/reducer.js deleted file mode 100644 index 2d0fd8e9..00000000 --- a/frontend/modules/common/reducer.js +++ /dev/null @@ -1,10 +0,0 @@ -import { combineReducers } from 'redux' -import { default as list } from '../list/reducers/GroceryListReducer' -import { default as recipe } from '../recipe/reducers/Reducer' - -const reducer = combineReducers({ - list, - recipe, -}); - -export default reducer diff --git a/frontend/modules/header/components/GroceryListMenuItem.js b/frontend/modules/header/components/GroceryListMenuItem.js index 53f7db41..d4cb97f3 100644 --- a/frontend/modules/header/components/GroceryListMenuItem.js +++ b/frontend/modules/header/components/GroceryListMenuItem.js @@ -33,7 +33,7 @@ class GroceryListMenuItem extends React.Component { id="basic-nav-dropdown"> { lists } {( this.props.data.length > 0 ? : null )} - + { formatMessage(messages.grocery_list) } diff --git a/frontend/modules/header/components/Nav.js b/frontend/modules/header/components/Nav.js index ecab1b84..620a9679 100644 --- a/frontend/modules/header/components/Nav.js +++ b/frontend/modules/header/components/Nav.js @@ -1,5 +1,5 @@ import React from 'react' -import { Link } from 'react-router-dom' +import { Link } from 'react-router' import { injectIntl, IntlProvider, @@ -10,6 +10,8 @@ import { Image, Navbar, Nav, NavDropdown, MenuItem, NavItem } from 'react-bootst import { LinkContainer } from 'react-router-bootstrap' import AuthStore from '../../account/stores/AuthStore'; +import { ListStore, CHANGE_EVENT } from '../../list/stores/ListStore'; +import ListActions from '../../list/actions/ListActions'; import { CreateRecipeMenuItem } from './CreateRecipeMenuItem' import { GroceryListMenuItem } from './GroceryListMenuItem' @@ -27,13 +29,15 @@ class NavBar extends React.Component { componentDidMount() { AuthStore.addChangeListener(this._onChange); + ListStore.addChangeListener(CHANGE_EVENT, this._onChange); if (AuthStore.isAuthenticated()) { - this.props.listActions.load(); + ListActions.init(); } } componentWillUnmount() { AuthStore.removeChangeListener(this._onChange); + ListStore.removeChangeListener(CHANGE_EVENT, this._onChange); } _getState() { @@ -42,12 +46,13 @@ class NavBar extends React.Component { // If it is we need to init the list store so the menu has teh users lists. if (this.hasOwnProperty('state')) { if (!this.state.authenticated && authenticated) { - this.props.listActions.load() + ListActions.init() } } return { authenticated: authenticated, + lists: ListStore.get_lists() || [] }; } @@ -97,7 +102,7 @@ class NavBar extends React.Component { : null )} {( this.state.authenticated ? - : null + : null )}