| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- import React, { Component } from 'react';
- import { RouteComponentProps } from 'react-router';
- import Navbar from 'components/Navbar';
- import { AppState } from 'store/configureStore';
- import { connect } from 'react-redux';
- import { PlannerState, Weekday, Meal, DayPlan, PlannerMode, RecipePlan, WeekPlan } from 'types/planner';
- import Card from 'components/Card';
- import PlannerActions, { fetchPlannerActionCreator, PlannerActions as PlannerActionsTypes, savePlannerActionCreator } from './actions';
- import moment from 'moment';
- import { DragDropContext, Droppable, Draggable, DropResult, OnDragEndResponder } from 'react-beautiful-dnd';
- import './styles.scss';
- import { getWeekDay } from 'services/time';
- import Button from 'components/Button';
- import { ThunkDispatch } from 'redux-thunk';
- import { bindActionCreators } from 'redux';
- type Actions = typeof PlannerActions
- interface PlannerContainerProps extends RouteComponentProps, PlannerState, Actions {
- fetch: typeof fetchPlannerActionCreator,
- save: typeof savePlannerActionCreator
- }
- interface PlannerContainerState {
- week: [Weekday, string][]
- }
- class PlannerContainer extends Component<PlannerContainerProps, PlannerContainerState> {
- constructor(props: PlannerContainerProps) {
- super(props);
- this.state = {
- week: Object.keys(props.planner).map((weekday) => ([ weekday as Weekday, moment(props.planner[weekday as Weekday].date).format()]))
- }
- }
- componentDidMount() {
- this.props.fetch(this.props.week);
- }
- componentDidUpdate() {
- const { isFetching } = this.props;
- }
- assignRecipe = (result: DropResult) => {
- const recipe = this.findRecipe(result.draggableId);
- if (result.destination && recipe) {
- const [idx, day, meal] = result.destination.droppableId.split('-');
- this.props.assignToDay(recipe, day as Weekday, meal as Meal);
- this.props.removeFromBacklog(recipe);
- this.props.editPlanner();
- }
- }
- removeMeal = (day: Weekday, meal: Meal) => {
- this.props.editPlanner();
- return this.props.removeMeal(day, meal);
- }
- findRecipe = (recipeId: string) => this.props.backlog.find(recipe => recipe._id === recipeId);
- changeMode = (mode: PlannerMode) => this.props.changePlannerMode(mode);
- render () {
- return (
- <div className='cbk-planner'>
- <Navbar
- title='Planner'
- >
- {
- this.props.mode === 'view' ? (
- <Button outlined raised onClick={() => this.changeMode('edit')}>Edit</Button>
- ) : (
- <Button outlined raised onClick={() => {
- if (this.props.edit) {
- this.props.save(this.props.planner, this.props.from, this.props.to)
- }
- this.changeMode('view')
- }}>Save</Button>
- )
- }
- </Navbar>
- <DisplayPlanner
- mode={this.props.mode}
- week={this.state.week}
- weekNumber={this.props.week}
- onDragEnd={this.assignRecipe}
- backlog={this.props.backlog}
- planner={this.props.planner}
- removeMeal={this.removeMeal}
- />
- </div>
- );
- }
- }
- const DisplayMealWithActions: React.SFC<{
- recipe?: RecipePlan,
- children?: React.ReactElement
- }> = ({ recipe, children }) => recipe ? (
- <div className='meal-card'>
- <div className="meal-card--actions">
- { children }
- </div>
- <h5>{ recipe.name }</h5>
- </div>
- ) : null;
- const DisplayPlanner: React.SFC<{
- week: [Weekday, string][],
- onDragEnd: OnDragEndResponder,
- weekNumber: number,
- backlog: RecipePlan[],
- planner: WeekPlan,
- removeMeal: typeof PlannerActions.removeMeal,
- mode?: PlannerMode,
- }> = ({ mode, onDragEnd, backlog, weekNumber, week, planner, removeMeal}) => (
- <section className='cbk-planner__body'>
- <DragDropContext onDragEnd={onDragEnd}>
- {
- mode === 'edit' ? (
- <div className='cbk-planner__body__backlog'>
- <Droppable droppableId='recipeList'>
- {(provided) => (
- <div ref={provided.innerRef}>
- {backlog.map((item, index) => (
- <Draggable
- key={item._id}
- draggableId={item._id}
- index={index}>
- {provided => (
- <div
- ref={provided.innerRef}
- {...provided.draggableProps}
- {...provided.dragHandleProps}
- >
- <Card
- key={item._id}
- title={item.name}
- onClick={() => {}}
- />
- </div>
- )}
- </Draggable>
- ))}
- {provided.placeholder}
- </div>
- )}
- </Droppable>
- </div>
- ) : null
- }
- <div className='cbk-planner__body__calendar'>
- <div>Week {weekNumber}</div>
- <div className='container'>
- <div className='day-schedule day-schedule--meals'>
- <div className='day-schedule--date'></div>
- <div className='day-schedule--lunch'> <h5>lunch</h5></div>
- <div className='day-schedule--dinner'> <h5>dinner</h5> </div>
- </div>
- {
- week.map(([weekday, day], dayNumber) => (
- <div key={dayNumber} className='day-schedule'>
- <div className='day-schedule--date'>
- <h5>{weekday} {moment(day).format('DD')}</h5>
- </div>
- <div className='day-schedule--lunch'>
- <Droppable droppableId={`${dayNumber}-${weekday}-lunch`}>
- {provided => (
- <div className='day-schedule-content' ref={provided.innerRef}>
- {provided.placeholder}
- <DisplayMealWithActions recipe={planner[weekday]['lunch']}>
- {
- planner[weekday]['lunch'] && mode === 'edit' ? (
- <Button icon='clear' onClick={() => removeMeal(weekday, 'lunch')} small></Button>
- ) : undefined
- }
- </DisplayMealWithActions>
- </div>
- )}
- </Droppable>
- </div>
- <div className='day-schedule--dinner'>
- <Droppable droppableId={`${dayNumber}-${weekday}-dinner`}>
- {provided => (
- <div className='day-schedule-content' ref={provided.innerRef}>
- {provided.placeholder}
- <DisplayMealWithActions recipe={planner[weekday]['dinner']}>
- {
- planner[weekday]['dinner'] && mode === 'edit' ? (
- <Button icon='clear' onClick={() => removeMeal(weekday, 'dinner')} small></Button>
- ) : undefined
- }
- </DisplayMealWithActions>
- </div>
- )}
- </Droppable>
- </div>
- </div>
- ))
- }
- </div>
- </div>
- </DragDropContext>
- </section>
- )
- const mapStateToProps = (state: AppState) => {
- return state.planner
- }
- const mapDispatchToProps = (dispatch: ThunkDispatch<AppState, any, any>) => ({
- fetch: (week: number) => dispatch(fetchPlannerActionCreator(week)),
- save: (plan: WeekPlan, from: Date, to: Date) => dispatch(savePlannerActionCreator(plan, from, to)),
- ...bindActionCreators(PlannerActions, dispatch)
- })
- export default connect(
- mapStateToProps,
- mapDispatchToProps
- )(PlannerContainer);
|