diff --git a/modules/common/config.js b/modules/common/config.js index dee7b8d8..f60a4305 100644 --- a/modules/common/config.js +++ b/modules/common/config.js @@ -26,4 +26,5 @@ export const serverURLs = { list_item: apiUrl + '/list/items/', bulk_list_item: apiUrl + '/list/bulk_item/', menu_item: apiUrl + '/menu/menu-item/', + menu_stats: apiUrl + '/menu/menu-stats/', }; diff --git a/modules/index.js b/modules/index.js index a36b65e1..2f7b8c18 100644 --- a/modules/index.js +++ b/modules/index.js @@ -18,7 +18,7 @@ import List from './list/containers/List' import Browse from './browse/containers/Browse' import Form from './recipe_form/containers/Form' import RecipeView from './recipe/components/RecipeView' -import Menu from './menu/components/Menu' +import Menu from './menu/containers/Menu' // Load required polyfills import { @@ -60,8 +60,7 @@ const main = ( - - + diff --git a/modules/menu/actions/MenuItemActions.js b/modules/menu/actions/MenuItemActions.js index 6cc6f0e2..201bf12b 100644 --- a/modules/menu/actions/MenuItemActions.js +++ b/modules/menu/actions/MenuItemActions.js @@ -3,10 +3,20 @@ import { serverURLs } from '../../common/config' import MenuItemConstants from '../constants/MenuItemConstants'; import StatusConstants from '../constants/StatusConstants'; -export const load = () => { +export const loadStats = () => { return (dispatch) => { request() - .get(serverURLs.menu_item) + .get(serverURLs.menu_stats) + .then(res => dispatch({ + type: MenuItemConstants.MENU_ITEM_LOAD_STATS, data: res.body + })) + } +}; + +export const loadItems = () => { + return (dispatch) => { + request() + .get(serverURLs.menu_item + '?complete=false') .then(res => dispatch({ type: MenuItemConstants.MENU_ITEM_LOAD, data: res.body.results })) @@ -69,6 +79,18 @@ export const save = (id, data) => { } }; +export const completeMenuItem = (id) => { + return (dispatch) => { + request() + .patch(serverURLs.menu_item + id + '/' ) + .send({complete: true}) + .then(res => dispatch({ + type: MenuItemConstants.MENU_ITEM_COMPLETE, + id: id + })) + } +}; + export const remove = (id) => { return (dispatch) => { dispatch({ diff --git a/modules/menu/actions/RecipeListActions.js b/modules/menu/actions/RecipeListActions.js index 97643938..730589d6 100644 --- a/modules/menu/actions/RecipeListActions.js +++ b/modules/menu/actions/RecipeListActions.js @@ -10,7 +10,7 @@ export const fetchRecipeList = (searchTerm) => { titles.push({ value: parseInt(recipe.id, 10), label: recipe.title }); return recipe; }); - return { options: titles }; + return titles; }) .catch(err => []) }; diff --git a/modules/menu/actions/validation.js b/modules/menu/actions/validation.js index e7ea10f3..9ed966be 100644 --- a/modules/menu/actions/validation.js +++ b/modules/menu/actions/validation.js @@ -12,5 +12,4 @@ export const menuItemValidation = [ { name: 'menu', validators: [double] }, { name: 'recipe', validators: [double] }, { name: 'start_date', validators: [isDate] }, - { name: 'end_date', validators: [isDate] }, ]; diff --git a/modules/menu/components/FullMenu.js b/modules/menu/components/FullMenu.js new file mode 100644 index 00000000..56b0a33c --- /dev/null +++ b/modules/menu/components/FullMenu.js @@ -0,0 +1,65 @@ +import React from 'react' +import PropTypes from 'prop-types' +import moment from 'moment' +import OnTheMenu from './OnTheMenu' + +const FullMenu = ({ menuItems, completeMenuItem, editMenuItem }) => { + let nextWeek = moment().add(1, 'week').startOf('week').format('MMMM D'); + let thisWeek = moment().startOf('week').format('MMMM D'); + let lastWeek = moment().subtract(1, 'week').startOf('week').format('MMMM D'); + + let groups = menuItems.reduce((acc, menuItem) => { + let date = menuItem.start_date; + let weekStart = moment(date).startOf('week').format('MMMM D'); + let weekEnd = moment(date).endOf('week').format('MMMM D'); + + let title = weekStart + ' - ' + weekEnd; + if (thisWeek === weekStart) { + title = 'This Week (' + title + ')' + } else if (nextWeek === weekStart) { + title = 'Next Week (' + title + ')' + } else if (lastWeek === weekStart) { + title = 'Last Week (' + title + ')' + } + + if (typeof acc[title] === 'undefined') { + acc[title] = []; + } + acc[title].push(menuItem); + return acc; + }, {}); + + if (menuItems.length > 0) { + return ( +
+ {Object.keys(groups).map((key) => ( +
+

{key}

+ +
+ ))} +
+ ) + } + + return ( +
+
+

Nothings on the Menu

+ editMenuItem(0)}>Add one now +
+
+ ) +}; + +FullMenu.propTypes = { + menuItems: PropTypes.array.isRequired, + completeMenuItem: PropTypes.func.isRequired, + editMenuItem: PropTypes.func.isRequired, +}; + +export default FullMenu \ No newline at end of file diff --git a/modules/menu/components/Menu.js b/modules/menu/components/Menu.js deleted file mode 100644 index a2d1e216..00000000 --- a/modules/menu/components/Menu.js +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react' -import Calendar from '../containers/Calendar' -import Status from '../containers/Status' - -require('react-big-calendar/lib/css/react-big-calendar.css'); -require('../css/rbc-calendar.scss'); - -const Menu = (location) => ( -
-
-
- -
-
- -
-
-
-); - -export default Menu \ No newline at end of file diff --git a/modules/menu/components/MenuLayout.js b/modules/menu/components/MenuLayout.js new file mode 100644 index 00000000..7bfe5c14 --- /dev/null +++ b/modules/menu/components/MenuLayout.js @@ -0,0 +1,34 @@ +import React from 'react' + +import Tabs from '../components/Tabs' +import Status from '../containers/Status' + +require("../css/menu.scss"); + +class MenuLayout extends React.Component { + render() { + return ( +
+
+
+ +
+
+
+
+ +
+
+ {this.props.children} +
+
+
+ ) + } +} + +export default MenuLayout \ No newline at end of file diff --git a/modules/menu/components/OnTheMenu.js b/modules/menu/components/OnTheMenu.js new file mode 100644 index 00000000..5a2ccdee --- /dev/null +++ b/modules/menu/components/OnTheMenu.js @@ -0,0 +1,40 @@ +import React from 'react' +import PropTypes from 'prop-types' +import ListRecipes from '../../browse/components/ListRecipes' + +const OnTheMenu = ({ menuItems, completeMenuItem, editMenuItem }) => ( + {return {...x.recipe_data, menuItemId: x.id}})} + footer={(recipe) => ( +
+
+ +
+
+ +
+
+ )} + /> +); + +OnTheMenu.propTypes = { + menuItems: PropTypes.array.isRequired, + completeMenuItem: PropTypes.func.isRequired, + editMenuItem: PropTypes.func.isRequired, +}; + +export default OnTheMenu diff --git a/modules/menu/components/RecipeEvent.js b/modules/menu/components/RecipeEvent.js deleted file mode 100644 index 47077c58..00000000 --- a/modules/menu/components/RecipeEvent.js +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { Link } from 'react-router-dom' - -const RecipeEvent = ({ event, title, isAllDay }) => ( -
- - { event.recipe_data.title } - - -
-); - -RecipeEvent.propTypes = { - event: PropTypes.object.isRequired, - title: PropTypes.string, - isAllDay: PropTypes.bool, -}; - -export default RecipeEvent \ No newline at end of file diff --git a/modules/menu/components/Stats.js b/modules/menu/components/Stats.js new file mode 100644 index 00000000..a2b5ba0e --- /dev/null +++ b/modules/menu/components/Stats.js @@ -0,0 +1,31 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { Link } from 'react-router-dom' +import moment from 'moment' + +const RecipeEvent = ({ stats }) => ( + + + + + + + + + + {stats.map(row => ( + + + + + + ))} + +
RecipeCountLast Made
{row.title}{row.num_menuitems}{moment(row.last_made).format('ddd, MMMM D, YYYY')}
+); + +RecipeEvent.propTypes = { + stats: PropTypes.array.isRequired, +}; + +export default RecipeEvent \ No newline at end of file diff --git a/modules/menu/components/StatusBar.js b/modules/menu/components/StatusBar.js index b1e6ac1f..4f6d46a4 100644 --- a/modules/menu/components/StatusBar.js +++ b/modules/menu/components/StatusBar.js @@ -1,7 +1,5 @@ import React from 'react' -require('../css/rbc-calendar-alert.scss'); - const Status = ({ alert, message, close }) => { if (message.length > 1) { let cssClass = "alert alert-info alert-dismissible"; diff --git a/modules/menu/components/Tabs.js b/modules/menu/components/Tabs.js new file mode 100644 index 00000000..356fbf6a --- /dev/null +++ b/modules/menu/components/Tabs.js @@ -0,0 +1,24 @@ +import React from 'react' +import PropTypes from 'prop-types' +import TC from '../constants/TabConstants.js' + +const Tab = ({ changeTab, activeTab, onMenuItemShow }) => ( +
    +
  • changeTab(TC.OnTheMenu)} className={activeTab === TC.OnTheMenu ? "active" : ""}> + On The Menu +
  • +
  • changeTab(TC.Stats)} className={activeTab === TC.Stats ? "active" : ""}> + History +
  • +
  • onMenuItemShow(0)}> + New Menu Item +
  • +
+); + +Tab.propTypes = { + changeTab: PropTypes.func, + activeTab: PropTypes.string, +}; + +export default Tab \ No newline at end of file diff --git a/modules/menu/components/UpComingRecipes.js b/modules/menu/components/UpComingRecipes.js new file mode 100644 index 00000000..493c0362 --- /dev/null +++ b/modules/menu/components/UpComingRecipes.js @@ -0,0 +1,62 @@ +import React from 'react' +import PropTypes from 'prop-types' +import moment from 'moment' +import OnTheMenu from './OnTheMenu' + +const FullMenu = ({ menuItems, completeMenuItem, editMenuItem }) => { + let nextWeek = moment().add(1, 'week').startOf('week').format('MMMM D'); + let thisWeek = moment().startOf('week').format('MMMM D'); + let lastWeek = moment().subtract(1, 'week').startOf('week').format('MMMM D'); + + let groups = menuItems.reduce((acc, menuItem) => { + let date = menuItem.start_date; + let weekStart = moment(date).startOf('week').format('MMMM D'); + let weekEnd = moment(date).endOf('week').format('MMMM D'); + + let title = weekStart + ' - ' + weekEnd; + if (thisWeek === weekStart) { + title = 'On The Menu This Week (' + title + ')' + } else if (nextWeek === weekStart) { + title = 'On The Menu Next Week (' + title + ')' + } else if (lastWeek === weekStart) { + title = 'On The Menu Last Week (' + title + ')' + } else { + return acc; + } + + if (typeof acc[title] === 'undefined') { + acc[title] = []; + } + acc[title].push(menuItem); + return acc; + }, {}); + + if (menuItems.length > 0) { + return ( +
+
+ {Object.keys(groups).map((key) => ( +
+

{key}

+ +
+ ))} +
+
+ ) + } + + return (
) +}; + +FullMenu.propTypes = { + menuItems: PropTypes.array.isRequired, + completeMenuItem: PropTypes.func.isRequired, + editMenuItem: PropTypes.func.isRequired, +}; + +export default FullMenu \ No newline at end of file diff --git a/modules/menu/components/modals/BaseModal.js b/modules/menu/components/modals/BaseModal.js index f851ead6..a526d48b 100644 --- a/modules/menu/components/modals/BaseModal.js +++ b/modules/menu/components/modals/BaseModal.js @@ -1,7 +1,5 @@ import React from 'react' -require('../../css/rbc-calendar-modal.scss'); - class BaseModal extends React.Component { validate = (name, value) => { let v = this.props.validation.find(t => t.name === name); diff --git a/modules/menu/components/modals/MenuItemModal.js b/modules/menu/components/modals/MenuItemModal.js index 4483ae96..13fed4a6 100644 --- a/modules/menu/components/modals/MenuItemModal.js +++ b/modules/menu/components/modals/MenuItemModal.js @@ -8,8 +8,6 @@ import { Checkbox } from '../../../common/components/FormComponents' import { DateTime } from '../../../common/components/DateTime' import { Async } from '../../../common/components/Select' -require('../../css/rbc-calendar-modal.scss'); - class MenuItemModal extends BaseModal { constructor(props) { super(props); @@ -18,20 +16,16 @@ class MenuItemModal extends BaseModal { recipe: this.props.recipe || '', title: this.props.title || '', start_date: '', - end_date: '', - all_day: '', }; } componentWillReceiveProps(nextProps) { - let { event, startDate, endDate } = nextProps; + let { event, startDate } = nextProps; let title = this.props.title; let placeholder = this.props.intl.messages['men_item_event_model.new_menu_item']; let recipe = this.props.recipe; let start_date = startDate || new Date(); - let end_date = endDate || new Date(); - let all_day = false; let complete = false; if (event) { @@ -40,8 +34,6 @@ class MenuItemModal extends BaseModal { placeholder = event.recipe_data.title; start_date = event.start_date; complete = event.complete; - end_date = event.end_date; - all_day = event.all_day; } this.setState({ @@ -49,8 +41,6 @@ class MenuItemModal extends BaseModal { placeholder: placeholder, title: title, start_date: start_date, - end_date: end_date, - all_day: all_day, complete: complete, }); } @@ -60,27 +50,18 @@ class MenuItemModal extends BaseModal { value = moment(value); let newState = {}; newState[name] = value; - - if (value >= moment(this.state.end_date)) { - newState['end_date'] = moment(value).add(1, 'h'); - } this.setState(newState) }; render () { let { id, show, onHide, fetchRecipeList, intl } = this.props; - let { recipe, title, placeholder, start_date, end_date, all_day, complete } = this.state; + let { recipe, title, placeholder, start_date, complete } = this.state; const messages = defineMessages({ start_date: { id: 'men_item_event_model.start_date', description: 'Start Date', defaultMessage: 'Start Date', }, - end_date: { - id: 'men_item_event_model.end_date', - description: 'End Date', - defaultMessage: 'End Date', - }, recipe: { id: 'men_item_event_model.recipe', description: 'Recipe', @@ -91,11 +72,6 @@ class MenuItemModal extends BaseModal { description: 'Menu', defaultMessage: 'Menu', }, - all_day: { - id: 'men_item_event_model.all_day', - description: 'Anytime today', - defaultMessage: 'Anytime today', - }, complete: { id: 'men_item_event_model.complete', description: 'Complete', @@ -142,32 +118,16 @@ class MenuItemModal extends BaseModal { errors={ this.state['error_recipe'] } /> - - { - let parsed = qs.parse(this.props.location.search); - parsed['view'] = value; - history.push('/menu/?' + qs.stringify(parsed)); - }; - - buildDateUrl = value => { - let parsed = qs.parse(this.props.location.search); - parsed['date'] = moment(value).format('YYYY-MM-DD'); - history.push('/menu/?' + qs.stringify(parsed)); - }; - - buildVisibilityUrl = (name, value) => { - let parsed = qs.parse(this.props.location.search); - if (value) { - parsed['menu'] = value; - } else { - delete parsed['menu']; - } - history.push('/menu/?' + qs.stringify(parsed)); - }; - - onMenuItemShow = (id, startDate=null, endDate=null) => { - this.setState({ - showItemModal: true, - editMenuItemEventId: parseInt(id, 10), - startDate: startDate, - endDate: endDate, - }) - }; - - getComponents = () => { - return { - event: RecipeEvent, // used by each view (Month, Day, Week) - }; - }; - - render() { - const { menuItems, location } = this.props; - const { menuItemActions } = this.props; - // const { showMenuModal, editMenuEventId } = this.state; - // const { showCopyMenuModal, editCopyMenuEventId } = this.state; - const { showItemModal, editMenuItemEventId, startDate, endDate } = this.state; - const query = qs.parse(location.search); - - if (menuItems !== null) { - let events = menuItems.map(item => { - return { - ...item, - allDay: item.all_day, - start: moment(item.start_date).toDate(), - end: moment(item.end_date).toDate(), - } - }); - - return ( -
- { this.setState({showItemModal: false}) } } - event={ menuItems.find(t => t.id === editMenuItemEventId) } - startDate={ startDate } - endDate={ endDate } - onSave={ menuItemActions.save } - onRemove={ menuItemActions.remove } - fetchRecipeList={ fetchRecipeList } - validation={ menuItemValidation } - /> - this.onMenuItemShow(event.id) } - onSelectSlot={ slotInfo => this.onMenuItemShow( - 0, - moment(slotInfo.start), - moment(slotInfo.end).add(1, 'h') - )} - /> -
- ); - } else { - return ( ) - } - } -} - -Menu.propTypes = { - menuItems: PropTypes.array, - menuItemActions: PropTypes.object.isRequired, - location: PropTypes.object.isRequired, -}; - -const mapStateToProps = state => ({ - menuItems: state.menu.items, -}); - -const mapDispatchToProps = dispatch => ({ - menuItemActions: bindActionCreators(MenuItemActions, dispatch), -}); - -export default connect( - mapStateToProps, - mapDispatchToProps -)(Menu); diff --git a/modules/menu/containers/Menu.js b/modules/menu/containers/Menu.js new file mode 100644 index 00000000..5f16e134 --- /dev/null +++ b/modules/menu/containers/Menu.js @@ -0,0 +1,140 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { bindActionCreators } from 'redux' +import { connect } from 'react-redux' + +import authCheckRedirect from '../../common/authCheckRedirect' +import documentTitle from '../../common/documentTitle' + +import TC from '../constants/TabConstants.js' + +import Loading from '../../base/components/Loading' +import MenuItemModal from '../components/modals/MenuItemModal' +import Stats from '../components/Stats' +import MenuLayout from '../components/MenuLayout' +import FullMenu from '../components/FullMenu' + +import * as MenuItemActions from '../actions/MenuItemActions' +import { fetchRecipeList } from '../actions/RecipeListActions' +import { menuItemValidation } from '../actions/validation' + +class Menu extends React.Component { + constructor(props) { + super(props); + + this.state = { + tab: TC.OnTheMenu, + showMenuModal: false, + editMenuEventId: 0, + startDate: null, + endDate: null, + }; + } + + componentDidMount() { + authCheckRedirect(); + documentTitle('Menu'); + this.props.menuItemActions.loadItems(); + this.props.menuItemActions.loadStats(); + } + + componentDidUpdate(prevProps, prevState) { + if (this.state.tab !== prevState.tab && this.state.tab === TC.Stats) { + this.props.menuItemActions.loadStats(); + } + } + + componentWillUnmount() { + documentTitle(); + } + + changeTab = (tab) => { + this.setState({tab}); + }; + + onMenuItemShow = (id, startDate=null, endDate=null) => { + this.setState({ + showItemModal: true, + editMenuItemEventId: parseInt(id, 10), + startDate: startDate, + endDate: endDate, + }) + }; + + render() { + const { menuItems, stats, SimpleLayout } = this.props; + const { menuItemActions } = this.props; + const { showItemModal, editMenuItemEventId, startDate, tab } = this.state; + + if (menuItems !== null) { + if (SimpleLayout) { + return ( +
+ { this.setState({showItemModal: false}) } } + event={ menuItems.find(t => t.id === editMenuItemEventId) } + startDate={ startDate } + onSave={ menuItemActions.save } + onRemove={ menuItemActions.remove } + fetchRecipeList={ fetchRecipeList } + validation={ menuItemValidation } + /> + +
+ ); + } + return ( + + { this.setState({showItemModal: false}) } } + event={ menuItems.find(t => t.id === editMenuItemEventId) } + startDate={ startDate } + onSave={ menuItemActions.save } + onRemove={ menuItemActions.remove } + fetchRecipeList={ fetchRecipeList } + validation={ menuItemValidation } + /> + {tab === TC.Stats ? : ''} + {tab === TC.OnTheMenu + ? + : '' + } + + ); + } else { + return ( ) + } + } +} + +Menu.propTypes = { + menuItems: PropTypes.array, + stats: PropTypes.array, + menuItemActions: PropTypes.object.isRequired, +}; + +const mapStateToProps = state => ({ + menuItems: state.menu.items, + stats: state.menu.stats, +}); + +const mapDispatchToProps = dispatch => ({ + menuItemActions: bindActionCreators(MenuItemActions, dispatch), +}); + +export default connect( + mapStateToProps, + mapDispatchToProps +)(Menu); diff --git a/modules/menu/css/menu.scss b/modules/menu/css/menu.scss new file mode 100644 index 00000000..12448007 --- /dev/null +++ b/modules/menu/css/menu.scss @@ -0,0 +1,28 @@ +.menu-planner { + margin-top: 20px; + .content { + border-left: #eeeeee 1px solid; + .recipes{ + margin-top: 0; + .page-header { + margin-top: 0; + } + } + } +} + +.menu-complete-btn { + border-radius: 0 0 0 2px !important; + width: 100%; + .glyphicon-ok { + margin-left: 10px; + } +} + +.menu-edit-btn { + border-radius: 0 0 2px 0 !important; + width: 100%; + .glyphicon-ok { + margin-left: 10px; + } +} \ No newline at end of file diff --git a/modules/menu/css/rbc-calendar-alert.scss b/modules/menu/css/rbc-calendar-alert.scss deleted file mode 100644 index 1646f7d9..00000000 --- a/modules/menu/css/rbc-calendar-alert.scss +++ /dev/null @@ -1,6 +0,0 @@ -.calendar { - .alert { - margin-bottom: 0; - margin-top: 15px; - } -} \ No newline at end of file diff --git a/modules/menu/css/rbc-calendar-modal.scss b/modules/menu/css/rbc-calendar-modal.scss deleted file mode 100644 index 10afdbc0..00000000 --- a/modules/menu/css/rbc-calendar-modal.scss +++ /dev/null @@ -1,8 +0,0 @@ -.rbc-calendar-modal { - h4 { - display: inline; - } - .help-inline { - color: #a94442; - } -} \ No newline at end of file diff --git a/modules/menu/css/rbc-calendar.scss b/modules/menu/css/rbc-calendar.scss deleted file mode 100644 index cd89bb4c..00000000 --- a/modules/menu/css/rbc-calendar.scss +++ /dev/null @@ -1,53 +0,0 @@ -.rbc-calendar { - margin-top: 20px; - min-height: 600px; - .calender-recipe-event { - a { - color: #ffffff; - } - } - .rbc-agenda-event-cell { - div { - a { - color: #337ab7; - } - } - } - .rbc-toolbar-label { - .menus-group { - display: inline-block; - .menu-filter { - border-radius: 0 !important; - } - .menu-edit-buttons { - padding: 6px 0 8px 0; - border-right: solid 1px #ccc; - border-top: solid 1px #ccc; - border-bottom: solid 1px #ccc; - } - .new-menu { - padding: 6px 0 8px 0; - border-left: solid 1px #ccc; - border-top: solid 1px #ccc; - border-bottom: solid 1px #ccc; - } - .glyphicon { - cursor: pointer; - display: inline-block; - margin: 0 10px; - &.glyphicon-space { - margin: 0 36px; - } - } - .menu-selector { - display: inline-block; - .form-group { - width: 200px; - select { - border-radius: 0; - } - } - } - } - } -} diff --git a/modules/menu/reducers/MenuItemsReducer.js b/modules/menu/reducers/MenuItemsReducer.js index e06768e2..ecfd5b43 100644 --- a/modules/menu/reducers/MenuItemsReducer.js +++ b/modules/menu/reducers/MenuItemsReducer.js @@ -6,16 +6,14 @@ const items = (state = null, action) => { return action.data; case MenuItemConstants.MENU_ITEM_CREATE: return [ ...state, { ...action.data }]; - case MenuItemConstants.MENU_ITEM_CREATE_BULK: - return [ ...state, ...action.data ]; case MenuItemConstants.MENU_ITEM_SAVE: return state.map(item => item.id === action.data.id ? { ...action.data } : item ); + case MenuItemConstants.MENU_ITEM_COMPLETE: + return state.filter(t => t.id !== action.id); case MenuItemConstants.MENU_ITEM_DELETE: return state.filter(t => t.id !== action.id); - case MenuItemConstants.MENU_ITEM_MENU_DELETE: - return state.filter(t => t.menu !== action.id); default: return state; } diff --git a/modules/menu/reducers/StatsReducer.js b/modules/menu/reducers/StatsReducer.js new file mode 100644 index 00000000..19092282 --- /dev/null +++ b/modules/menu/reducers/StatsReducer.js @@ -0,0 +1,12 @@ +import MenuItemConstants from '../constants/MenuItemConstants' + +const stats = (state = null, action) => { + switch (action.type) { + case MenuItemConstants.MENU_ITEM_LOAD_STATS: + return action.data; + default: + return state; + } +}; + +export default stats diff --git a/modules/menu/reducers/reducer.js b/modules/menu/reducers/reducer.js index 2ea750e4..28d3d30d 100644 --- a/modules/menu/reducers/reducer.js +++ b/modules/menu/reducers/reducer.js @@ -1,9 +1,11 @@ import { combineReducers } from 'redux' -import { default as items } from './MenuItemsReducer' -import { default as status } from './status' +import items from './MenuItemsReducer' +import status from './status' +import stats from './StatsReducer' const menu = combineReducers({ items, + stats, status }); diff --git a/modules/news/actions/NewsActions.js b/modules/news/actions/NewsActions.js index 0b29d04c..6f4931a1 100644 --- a/modules/news/actions/NewsActions.js +++ b/modules/news/actions/NewsActions.js @@ -14,26 +14,3 @@ export const load = () => { }) } }; - -export const loadUpcomingMenuItems = () => { - return (dispatch) => { - request() - .get(serverURLs.menu_item + '?complete=false') - .then(res => dispatch({ - type: NewsConstants.NEWS_MENU_ITEM_LOAD, - items: res.body.results - })) - } -}; - -export const completeMenuItem = (id) => { - return (dispatch) => { - request() - .patch(serverURLs.menu_item + id + '/' ) - .send({complete: true}) - .then(res => dispatch({ - type: NewsConstants.NEWS_MENU_ITEM_COMPLETE, - id: id - })) - } -}; diff --git a/modules/news/components/News.js b/modules/news/components/News.js index d8aa3e92..31103bf0 100644 --- a/modules/news/components/News.js +++ b/modules/news/components/News.js @@ -6,7 +6,8 @@ import { connect } from 'react-redux' import { injectIntl, defineMessages } from 'react-intl' import MiniBrowse from '../../browse/containers/MiniBrowse' -import ListRecipes from '../../browse/components/ListRecipes' +import UpComingRecipes from '../../menu/components/UpComingRecipes' +import Menu from '../../menu/containers/Menu' import documentTitle from '../../common/documentTitle' import * as NewsActions from "../actions/NewsActions"; @@ -17,9 +18,6 @@ class News extends React.Component { if (!this.props.news.news) { this.props.newsActions.load(); } - if (this.props.user.id) { - this.props.newsActions.loadUpcomingMenuItems(); - } } componentWillUnmount() { @@ -56,27 +54,7 @@ class News extends React.Component {
- { this.props.news.menuItems && this.props.news.menuItems.length > 0 ? -
-

On the Menu

- x.recipe_data)} - footer={(recipe) => ( -
-
- -
-
- )} - /> -
: '' - } +

Recommended Recipes

diff --git a/modules/news/constants/NewsConstants.js b/modules/news/constants/NewsConstants.js index 44333f53..2c74d195 100644 --- a/modules/news/constants/NewsConstants.js +++ b/modules/news/constants/NewsConstants.js @@ -1,5 +1,3 @@ export default { - NEWS_LOAD: 'NEWS_LOAD', - NEWS_MENU_ITEM_LOAD: 'NEWS_MENU_ITEM_LOAD', - NEWS_MENU_ITEM_COMPLETE: 'NEWS_MENU_ITEM_COMPLETE', + NEWS_LOAD: 'NEWS_LOAD' }; \ No newline at end of file diff --git a/modules/news/css/news.scss b/modules/news/css/news.scss index e36f37a1..dcb7ccec 100644 --- a/modules/news/css/news.scss +++ b/modules/news/css/news.scss @@ -38,15 +38,6 @@ .recipe-card-news-footer { width: 100%; } - .recipe { - .complete-btn { - border-radius: 0 0 2px 2px; - width: 100%; - .glyphicon-ok { - margin-left: 10px; - } - } - } } @media (max-width: $screen-xs-max) { diff --git a/modules/news/reducers/NewsReducer.js b/modules/news/reducers/NewsReducer.js index 67833223..471e8667 100644 --- a/modules/news/reducers/NewsReducer.js +++ b/modules/news/reducers/NewsReducer.js @@ -4,10 +4,6 @@ const lists = (state = {}, action) => { switch (action.type) { case NewsConstants.NEWS_LOAD: return { ...state, news: action.news }; - case NewsConstants.NEWS_MENU_ITEM_LOAD: - return { ...state, menuItems: action.items }; - case NewsConstants.NEWS_MENU_ITEM_COMPLETE: - return { ...state, menuItems: state.menuItems.filter(x => x.id !== action.id) }; default: return state; } diff --git a/modules/recipe_form/utilts/parseIngredient.js b/modules/recipe_form/utilts/parseIngredient.js index cd8477b4..bb95bbd8 100644 --- a/modules/recipe_form/utilts/parseIngredient.js +++ b/modules/recipe_form/utilts/parseIngredient.js @@ -1,4 +1,3 @@ -import formatQuantity from '../../recipe/utilts/formatQuantity' import { GCD } from '../../recipe/utilts/gcd' // Given an array of text values, @@ -45,6 +44,8 @@ const numberSplit = number => { let last = -1; let length = number.length; let numbers = ['1','2','3','4','5','6','7','8','9','0']; + + // eslint-disable-next-line numbers.map(n => { if (number.lastIndexOf(n) > last) { last = number.lastIndexOf(n) diff --git a/modules/registerServiceWorker.js b/modules/registerServiceWorker.js index 51f64a36..b5077e1c 100644 --- a/modules/registerServiceWorker.js +++ b/modules/registerServiceWorker.js @@ -30,6 +30,7 @@ export default function register() { } window.addEventListener('load', (event) => { + // eslint-disable-next-line if (window.location.pathname.match('^.*(\/admin\/).*$')) { return false; } diff --git a/package.json b/package.json index 4fcc9760..50ded0d7 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "react-redux": "^5.0.6", "react-router-bootstrap": "^0.24.4", "react-router-dom": "^4.2.2", - "react-select": "^2.1.1", + "react-select": "^2.4.1", "react-spinkit": "2.1.2", "redux": "^3.7.2", "redux-thunk": "^2.2.0", diff --git a/yarn.lock b/yarn.lock index 9efa0711..b58f13db 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6663,7 +6663,7 @@ react-router@^4.3.1: prop-types "^15.6.1" warning "^4.0.1" -react-select@^2.1.1: +react-select@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/react-select/-/react-select-2.4.1.tgz#99dd9c8b7700b5ebd38007dd707b1abdbad2e70f" dependencies: